/* Sketch for 3rd stage GoNoGo, LEFT active nosepoke hole. */ #include int gatePin = 12; //controls feeder transistor int houseLight = 8; int scope = 9; int buzz = 10; //nose-poke buzzer int GrLED1 = 6; //green LEDs above ports int GrLED2 = 7; int pokes1 = 0; //nosepoke counters (any nose poke) int pokes2 = 0; int PREpokes = 0; //premature nose poke counter int rewards = 0; // reward counter int GOtrials = 0; //GO trial counter int PREtrial = 0; //premature trial counter int omissions = 0; int tstart = 0; //time tracking int tstamp = 0; #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) 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 (millis() >= 1800000) //X { Serial.println ("-------------------------------"); Serial.println ("session end"); Serial.println ("-------------------------------"); digitalWrite (GrLED1, LOW); digitalWrite (houseLight, LOW); digitalWrite (scope, LOW); Serial.print("GO trials"); Serial.print(","); Serial.println (GOtrials); Serial.print ("rewards"); Serial.print (","); Serial.println (rewards); 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.print(omissions); 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 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; //note upper bound of "random" is exclusive // 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) //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(); while(digitalRead(GrLED1) == HIGH) // "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; 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; rewards = rewards + 1; Serial.print ("active"); Serial.print (","); Serial.println (pokes1); Serial.print ("rewards"); Serial.print (","); Serial.println (rewards); 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); Serial.print ("rewards"); Serial.print (","); Serial.println (rewards); // 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 } }