top of page

Visual Operant Arduino code

 

 

 

///////////////////////////////////////////////////////////////////////////////////////////

 


String programName = "headfix_visDiscSerial_080814b.pde";
String notes = "written for new visual disc task, for interaction with MATLAB Psychophysics Toolbox; now with new lick sensor";

//MOST IMPORTANT
int rewSolDur = 60; // time (in ms) that reward valve is open (80ms for 2p)
//int cueToneOn = 0; // specify cue tone on (1) or off (0)

//TIMING VARIABLES
int iti = 2000;  // 500 inter-trial interval (time after trial when no new trial can occur) (400 for lever hold iti, 2000 for timed trials)
int stimDur = 3000;  // duration of whisker stimulus (fast = 1500)
int drinkDur = 3000; // time given for animal to drink reward water before stimulus ends (fast=1500)

//int nostimTO = 6000; // nostim lever press punishment timeout
int unrewTO = 8000;  // unrewarded stim lever press punishment timeout (8000)

//int cueToneDur = 1000;
//int cueFreq = 1000;  // frequency of reward cue tone with Tone library
int rewToneDur = 1000;
int rewFreq = 2000;  // frequency of reward tone with Tone library

// variables for Jae-eun to modify
// int rewOutPin = 4;
// int lickOutPin = 5;
// int punOutPin = 6;

////// DEFINE PINS
int speakerOut = 3;    // define PWM pin for speaker/tone output

// defining solenoid pins
int rewPin = 11;      //  define pin for turing solenoid valve ON
//int ledPin = 13;                // LED connected to digital pin 13
//int vacPin = 9;      // define pin for turning vacuum line ON
int airpuffPin = 12;      // define pin for turning vacuum line OFF

int lickPin = 5;
int lickState = 0;

// some variables for vis stim
//int visStimNum = 0;
//int rewVisStim = 1;  // this is the rewarded visual stimulus

// variable for matlab data
int matlabData = 0;

// stuff for linear actuator
//#include <Servo.h>
//Servo linServo;
//int linServoPin = 8;

// stuff for MPR121 lick detector
//#include "mpr121.h"
//#include <Wire.h>

//int irqpin = 2;
//boolean touchStates[12];

//int sclPin = 5; // these are not needed because they are default
//int sdaPin = 4;


///////////// OTHER VARIABLES (NON-LIBRARY)

long randNumber;    // random number for whisker stimulus
long lickTime = 0;

long del = 0;    // initialize variable for making white noise stimulus (now presented during timeouts) 3/4/10                    

// various time counter variables
long elapTime = 0;  // variable for how long lever has been pressed (for triggering stimulus) or released (for triggering reward)
//long elapTime2 = 0;
long elapTime3 = 0;  // variable for how long to play punishment white noise

// time variables
long time = 0;    // initialize time since beginning of trial (I think Processing resets this, conveniently)
long startTime = 0;  // initialize times of trial start


//SETUP////////////////////////////////
void setup()                   
{
  //pinMode(ledPin, OUTPUT);      // sets the digital pin as LED output
  pinMode(rewPin, OUTPUT);  // sets digital pin for turing solenoid valve ON
  //pinMode(vacPin, OUTPUT);  // sets digital pin for turing solenoid valve ON
  pinMode(airpuffPin, OUTPUT);
 
  //pinMode(rewOutPin, OUTPUT);
  //pinMode(lickOutPin, OUTPUT);
  //pinMode(punOutPin, OUTPUT);

//  cueTones[0].begin(speakerOut);

  // linear servo setup
//  linServo.attach(linServoPin);
 
  // MPR121 touch sensor setup
//  pinMode(irqpin, INPUT);
//  digitalWrite(irqpin, HIGH); //enable pullup resistor
//  Wire.begin();
//  mpr121_setup();
 
  pinMode(lickPin, INPUT);

  Serial.begin(9600);    // initialize serial for output to Processing sketch
  randomSeed(analogRead(3));
}

//LOOP/////////////////////////////////
void loop()          {           // run over and over again



  // look for serial input from MATLAB/PsychToolbox
  if(Serial.available()>0) {
    
    tone(speakerOut, rewFreq, rewToneDur);
 
    matlabData = Serial.parseInt(); // read data
    
    startTime = millis();
    elapTime = 0;
    
    // once MATLAB sends serial data (when stim is over), start looking for licks
    while (elapTime < stimDur) {
 
      // check for licks
//      readTouchInputs();
      
      lickState = digitalRead(lickPin);
      
      // if lick, is it correct or incorrect (based upon rewPos)
      if (lickState == HIGH) {
        
        lickTime = millis();
      
        if (matlabData == 1) {
          reward();
        }
        else {
          punish();
        }
      } // end IF for lick
    
      elapTime = millis() - startTime;  // elapsed time in choice epoch
    } // end WHILE for reading touch inputs during stim dur
    
    delay(iti);  // this is the time after the choice interval, before Arduino sends signal to start next stimulus
    
    Serial.println('1'); // tell MATLAB choice epoch is over (so start next stim)
    
    tone(speakerOut, rewFreq, rewToneDur);
    
    // reset input from MATLAB/PsychToolbox computer
    matlabData = 0;
    lickState = 0;
    
  } // end IF for Serial.available()
 
}  // end VOID LOOP()


// function for reward administration
void reward() {

    // REWARD SEQUENCE
    // go through reward/vacuum solenoid sequence
    digitalWrite(rewPin, HIGH);    // open solenoid valve for a short time
    //digitalWrite(rewOutPin, HIGH);
    delay(rewSolDur);                  // 8ms ~= 8uL of reward liquid (on box #4 011811)
    digitalWrite(rewPin, LOW);
    //digitalWrite(rewOutPin, LOW);
    
    Serial.println('2');
        
    // PLAY TONE
//    cueTones[0].play(rewFreq, rewToneDur);   // changing to a frequency range that's more in the region of mouse hearing
    tone(speakerOut, rewFreq, rewToneDur);  // NOTE: don't know if this command is blocking

    delay(drinkDur);  // this is the time after reward for animal to drink before anything else happens
    
    elapTime = stimDur + 1;  // break out of the reward stimulus loop after receiving reward

}

// function for punishment administration
void punish() {
//  digitalWrite(vacPin, HIGH);    // send output signal for punishment to record analog timing
//  delay(50);                  //
//  digitalWrite(vacPin, LOW);

    digitalWrite(airpuffPin, HIGH);    // give aversive light for wrong press
    delay(50);  // changed this from 2000 because air puff goes on falling phase
    digitalWrite(airpuffPin, LOW);
 
    Serial.println('3');  // send this to MATLAB
 
//  digitalWrite(punOutPin, HIGH);
//  delay(10);
//  digitalWrite(punOutPin, LOW);

    // and make noise sound cue for unrewarded stim timeout
    elapTime3 = 0;
    while (elapTime3 < unrewTO) {
      del = random(1,7);
//      cueTones[0].play(del*1000); //notes[del]);
      tone(speakerOut, del*1000, 10);
      elapTime3 = millis() - lickTime;
    }
    // cueTones[0].stop();
    noTone(speakerOut);

    elapTime = stimDur + 1;  // 091311: need to check and make sure "elapTime1&2" are not in conflict

}

 

 

bottom of page