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
}