/* Sketch for stage 4 GoNoGo, LEFT active nosepoke hole. */ #include int gatePin = 12; //controls feeder transistor int houseLight = 8; int GrLED1 = 6; //green LEDs above ports; i.e. cue lights int GrLED2 = 7; int NoGoTone = 11; int scope = 9; int buzz = 10; //nose-poke buzzer int pokes1 = 0; //nosepoke counters (any nose poke) int pokes2 = 0; int PREpokes = 0; //premature nose poke counter int GOrewards = 0; // reward counter int NOGOrewards = 0; int GOtrials = 0; //GO trial counter int NOGOtrials = 0; int PREtrial = 0; //premature trial counter int omissions = 0; int comissions = 0; int tstart = 0; //time tracking #define SENSORPIN_A 4 #define SENSORPIN_B 5 // variables will change: int sensorState_A = 0, lastState_A = 0; int sensorState_B = 0, lastState_B = 0; int PREperiodValue = 0; //will be used to store randomly generated PREperiod duration (see below) int TrialSelect = 0; //will be used to determine if a GO or NOGO trial is initiated bool scopeTrigger = true; //timer variables unsigned long OFFtimerStart; //timer for cue light OFF unsigned long ONtimerStart; //timer for cue light ON unsigned long PREtimerStart; //timer for premature response period unsigned long HouseSuccStart; //timer for house light after successful poke unsigned long BUZZtimerStart; unsigned long currentMillis; const unsigned long OFFperiod = 10000; const unsigned long ONperiod = 3000; int PREperiod[3] = {3000, 6000, 9000}; //duration of pre-trial period is an array that will be called with a "random" function const unsigned long HousePeriod = 3000; //duration of house light on after successful poke const unsigned long BUZZperiod = 250; void setup() { // initialize the gate pin as an output: pinMode(gatePin, OUTPUT); // initialize the sensor pins as an input and enable internal pullup: pinMode(SENSORPIN_A, INPUT_PULLUP); pinMode(SENSORPIN_B, INPUT_PULLUP); //green LEDs above nosepoke holes: pinMode(GrLED1, OUTPUT); pinMode(GrLED2, OUTPUT); pinMode(houseLight, OUTPUT); pinMode(scope, OUTPUT); pinMode(buzz, OUTPUT); randomSeed(analogRead(0)); Serial.begin(9600); tstart = now(); } void loop() { // timer for session of X milliseconds, stops arduino for Y milliseconds if (now()- tstart >= 1800) //X { Serial.println ("--------------------------------------"); Serial.println ("session end"); Serial.println ("--------------------------------------"); Serial.print("GO trials"); Serial.print(","); Serial.println(GOtrials); Serial.print ("GOrewards"); Serial.print (","); Serial.println (GOrewards); Serial.print ("active"); Serial.print (","); Serial.println (pokes1); Serial.print ("inactive"); //port ID Serial.print (","); Serial.println(pokes2); Serial.print("pre-trials"); Serial.print(","); Serial.println(PREtrial); Serial.print ("premature"); Serial.print (","); Serial.println(PREpokes); Serial.print("omissions"); Serial.print(","); Serial.println(omissions); Serial.print("NOGO trials"); Serial.print(","); Serial.println(NOGOtrials); Serial.print("NOGOrewards"); Serial.print(","); Serial.println(NOGOrewards); Serial.print("comissions"); Serial.print(","); Serial.println(comissions); digitalWrite (GrLED1, LOW); digitalWrite (houseLight, LOW); digitalWrite (scope, LOW); delay (1200000); //Y } if (scopeTrigger == true) { digitalWrite(scope, HIGH); Serial.println("scope on"); scopeTrigger = false; } digitalWrite(GrLED1, LOW); digitalWrite(GrLED2, LOW); PREperiodValue = PREperiod[random(0,3)]; //randomly select PREperiod duration from selected values in PREperiod variable TrialSelect = random(2); digitalWrite(houseLight, HIGH);//turn house light on PREtrial = PREtrial + 1; Serial.print("pre-trials"); Serial.print(","); Serial.println(PREtrial); PREtimerStart = millis(); while(digitalRead(houseLight) == HIGH && digitalRead(GrLED1) == LOW) //detect premature nose-poke { currentMillis = millis(); if (currentMillis - BUZZtimerStart >= BUZZperiod) digitalWrite(buzz, LOW);//turn off buzzer if (currentMillis - PREtimerStart >= PREperiodValue) break; // if subject waits appropriate amount of time, exit loop // read the state of the sensors: sensorState_A = digitalRead(SENSORPIN_A); sensorState_B = digitalRead(SENSORPIN_B); if (sensorState_A && !lastState_A) { digitalWrite(gatePin, LOW); //unnecessary? } if (!sensorState_A && lastState_A) { pokes1 = pokes1 + 1; PREpokes = PREpokes + 1; Serial.print ("active"); Serial.print (","); Serial.println (pokes1); Serial.print ("premature"); Serial.print (","); Serial.println (PREpokes); digitalWrite(houseLight, LOW); //switch house light off after premature nosepoke } lastState_A = sensorState_A; if (sensorState_B && !lastState_B) { digitalWrite(gatePin, LOW); } if (!sensorState_B && lastState_B) { pokes2 = pokes2 + 1; Serial.print ("inactive"); //port ID Serial.print (","); Serial.println (pokes2); //poke counter } lastState_B = sensorState_B; delay(10); // so we don't flood the serial port } if (digitalRead(houseLight) == HIGH && TrialSelect == 0) //if there was no premature nose poke to turn off the houselight, procede with a NOGO trial { tone(NoGoTone, 3000, 3000); digitalWrite(GrLED1, HIGH); //turn on LED1 over left nosepoke NOGOtrials = NOGOtrials + 1; Serial.print("NOGO trials"); Serial.print(","); Serial.println(NOGOtrials); } if (digitalRead(houseLight) == HIGH && TrialSelect == 1) //if there was no premature nose poke to turn off the houselight, procede with a GO trial { digitalWrite(GrLED1, HIGH); //turn on LED1 over left nosepoke GOtrials = GOtrials + 1; Serial.print("GO trials"); Serial.print(","); Serial.println(GOtrials); } ONtimerStart = millis(); //records start of cue light "on" timer while(digitalRead(GrLED1) == HIGH && TrialSelect == 0) //this was important to be written like this!!; "NOGO" trial is initiated by green LED1 { currentMillis = millis(); //record time at each iteration of loop in currentMillis var if (currentMillis - BUZZtimerStart >= BUZZperiod) digitalWrite(buzz, LOW);//turn off buzzer if (currentMillis - ONtimerStart >= ONperiod) { BUZZtimerStart = millis(); digitalWrite(buzz, HIGH); digitalWrite(gatePin, HIGH); // pellet is dispensed if subject withheld nose poke delay(75); digitalWrite(gatePin, LOW); NOGOrewards = NOGOrewards + 1; //count and report no-go reward Serial.print("NOGOrewards"); Serial.print(","); Serial.println(NOGOrewards); digitalWrite(GrLED1, LOW);//if the ON period has passed break out of "while ON" loop } // read the state of the sensors: sensorState_A = digitalRead(SENSORPIN_A); sensorState_B = digitalRead(SENSORPIN_B); if (sensorState_A && !lastState_A) { digitalWrite(gatePin, LOW); } if (!sensorState_A && lastState_A) { pokes1 = pokes1 + 1; Serial.print("active"); Serial.print(","); Serial.println(pokes1); noTone(NoGoTone); //tunr off tone on comission error comissions = comissions + 1; //count and report comission error Serial.print("comissions"); Serial.print(","); Serial.println(comissions); digitalWrite(houseLight, LOW); //house light goes off digitalWrite(GrLED1, LOW); //switch LED1 off after nosepoke } lastState_A = sensorState_A; if (sensorState_B && !lastState_B) { digitalWrite(gatePin, LOW); } if (!sensorState_B && lastState_B) { pokes2 = pokes2 + 1; Serial.print("inactive"); //port ID Serial.print(","); Serial.println(pokes2); //poke counter } lastState_B = sensorState_B; delay(10); // so we don't flood the serial port } ONtimerStart = millis(); //records start of cue light "on" timer while(digitalRead(GrLED1) == HIGH && TrialSelect == 1) // "GO" trial is initiated by green LED1 { currentMillis = millis(); //record time at each iteration of loop in currentMillis var if (currentMillis - BUZZtimerStart >= BUZZperiod) digitalWrite(buzz, LOW);//turn off buzzer if (currentMillis - ONtimerStart >= ONperiod) { omissions = omissions + 1; //count and report omissions Serial.print("omissions"); Serial.print(","); Serial.println(omissions); digitalWrite(houseLight, LOW); digitalWrite(GrLED1, LOW);//if the ON period has passed break out of "while ON" loop and the house light goes off } // read the state of the sensors: sensorState_A = digitalRead(SENSORPIN_A); sensorState_B = digitalRead(SENSORPIN_B); if (sensorState_A && !lastState_A) { digitalWrite(gatePin, LOW); } if (!sensorState_A && lastState_A) { pokes1 = pokes1 + 1; GOrewards = GOrewards + 1; Serial.print ("active"); Serial.print (","); Serial.println (pokes1); Serial.print ("GOrewards"); Serial.print (","); Serial.println (GOrewards); BUZZtimerStart = millis(); digitalWrite(buzz, HIGH); digitalWrite(gatePin, HIGH); delay(75); digitalWrite(gatePin, LOW); digitalWrite(GrLED1, LOW); //switch LED1 off after nosepoke } lastState_A = sensorState_A; if (sensorState_B && !lastState_B) { digitalWrite(gatePin, LOW); } if (!sensorState_B && lastState_B) { pokes2 = pokes2 + 1; Serial.print ("inactive"); //port ID Serial.print (","); Serial.println (pokes2); //poke counter } lastState_B = sensorState_B; delay(10); // so we don't flood the serial port } lastState_A = sensorState_A; //reset sensor states lastState_B = sensorState_B; OFFtimerStart = millis(); //record time when "while OFF" loop started in OFFtimerStart var HouseSuccStart = millis(); while(digitalRead(GrLED1) == LOW) // this part of code controls the 10s inter-trial interval when the cue lights are off. { currentMillis = millis(); //record time at each iteration of loop in currentMillis var if (currentMillis - BUZZtimerStart >= BUZZperiod) digitalWrite(buzz, LOW);//turn off buzzer if (currentMillis - HouseSuccStart >= HousePeriod) digitalWrite(houseLight, LOW); // controls house light after correct poke: it remains on for 3 sec. if (currentMillis - OFFtimerStart >= OFFperiod) break; //if the OFF period has passed break out of "while OFF" loop // read the state of the sensors: sensorState_A = digitalRead(SENSORPIN_A); sensorState_B = digitalRead(SENSORPIN_B); if (sensorState_A && !lastState_A) { digitalWrite(gatePin, LOW); } if (!sensorState_A && lastState_A) { pokes1 = pokes1 + 1; //only pokes counted, no rewards since no pellet dispensed Serial.print ("active"); Serial.print (","); Serial.println (pokes1); // no gatePIN trigger since non-rewarded poke } lastState_A = sensorState_A; if (sensorState_B && !lastState_B) { digitalWrite(gatePin, LOW); } if (!sensorState_B && lastState_B) { pokes2 = pokes2 + 1; Serial.print ("inactive"); //port ID Serial.print (","); Serial.println (pokes2); //poke counter } lastState_B = sensorState_B; delay(10); // so we don't flood the serial port } }