Hi all,
I am working on a project that requires me to read sensor values from 4 IR sensors, as well as periodically switch on 9 different valves (independent of the sensor values). The way that I have set up the code is that I am reading the input values from the IR sensors continuously, while the 9 valves switch on as follows: one switches on for 400 ms every ~5s, 4 switch on for 3s every ~15s, and 4 switch on for 400ms every ~20s.
My problem is as follows: when none of the valves are on, the "baseline" readings for the sensor values range from 30 to 50, and increases >50 when I pass any object in front of the sensor, as it is meant to. However, when the valves switch on, the baseline values suddenly drop to 10-20. Is this something I should be worried about in terms of breaking the Arduino, valves or sensors? Even if that is not the case, I am curious as to why this is happening. Could someone shed some light on this please?
The components I am using are:
1 Arduino Mega 2560
9 NResearch valves (component 161K011, details attached)
4 Sanworks IR sensors (Link)
My code is as follows:
// This code is to carry out odor training 1 in upto 4 behavioral set-ups.
#include <RBD_Timer.h> // RBD Timer is the package this code is using to set timed events. Credit: https://github.com/alextaujenis/RBD_Timer
RBD::Timer timer;
RBD::Timer dummytimer;
// Lickometers
const int lickometerPin1 = A1; float sensorValue1 = 0;
const int lickometerPin2 = A2; float sensorValue2 = 0;
const int lickometerPin3 = A3; float sensorValue3 = 0;
const int lickometerPin4 = A4; float sensorValue4 = 0;
// Valves
const int valveOdor = 2;
const int valveOdor2 = 6;
const int valveReward = 3;
const int valveReward2 = 5;
const int valveDummy = 4;
// TTLs for Cheetah system
const int odorTTL = 28;
const int rewardTTL = 30;
const int lick1TTL = 32;
const int lick2TTL = 36;
const int lick3TTL = 34;
const int lick4TTL = 38;
const int dummyTTL = 40;
// Event-marker variables for CoolTerm/Bonsai/Arduino SDE serial plotter
int odor = 0;
int reward = 0;
// To have variable inter-trial length, we will use random numbers from 10-21. This is an initialization.
long randomNumber1 = 10;
// Setup for time variables
unsigned long delayInterval = 6000;
unsigned long timerValue;
unsigned long dummyTimeValue;
void setup()
{
Serial.begin(9600); // For continuous event display/saving for CoolTerm/Bonsai/Arduino SDE serial plotter
timer.setTimeout(3400); // Set trial length
timer.restart(); // Timer resets after trial length
dummytimer.setTimeout(4000); // Set dummy valve frequency
dummytimer.restart();
pinMode(valveOdor, OUTPUT);
pinMode(valveOdor2, OUTPUT);
pinMode(valveReward, OUTPUT);
pinMode(valveReward2, OUTPUT);
pinMode(valveDummy, OUTPUT);
pinMode(odorTTL, OUTPUT);
pinMode(rewardTTL, OUTPUT);
pinMode(lick1TTL, OUTPUT);
pinMode(lick2TTL, OUTPUT);
pinMode(lick3TTL, OUTPUT);
pinMode(lick4TTL, OUTPUT);
pinMode(dummyTTL, OUTPUT);
randomSeed(analogRead(A6)); // Seed for random number 1
}
void loop()
{
sensorValue1 = analogRead(lickometerPin1);
sensorValue2 = analogRead(lickometerPin2);
sensorValue3 = analogRead(lickometerPin3);
sensorValue4 = analogRead(lickometerPin4);
Serial.print(odor);
Serial.print(",");
Serial.print(reward);
Serial.print(",");
Serial.print(sensorValue1);
Serial.print(",");
Serial.print(sensorValue2);
Serial.print(",");
Serial.print(sensorValue3);
Serial.print(",");
Serial.println(sensorValue4);
sendLickData(60, sensorValue1, lick1TTL);
sendLickData(60, sensorValue2, lick2TTL);
sendLickData(60, sensorValue3, lick3TTL);
sendLickData(60, sensorValue4, lick4TTL);
dummyTimeValue = dummytimer.getValue();
if (dummyTimeValue < 400) {
digitalWrite(valveDummy, HIGH); digitalWrite(dummyTTL, HIGH);
}
else if (dummyTimeValue >= 400 && dummyTimeValue <= 700) {
digitalWrite(valveDummy, LOW); digitalWrite(dummyTTL, LOW);
}
else if (dummyTimeValue >= 3500 && dummyTimeValue <= 4000) {
dummytimer.restart();
}
timerValue = timer.getValue();
if (timerValue <= delayInterval) {
odor = 0; digitalWrite(valveOdor, LOW); digitalWrite(valveOdor2, LOW); digitalWrite(odorTTL, LOW);
reward = 0; digitalWrite(valveReward, LOW); digitalWrite(valveReward2, LOW); digitalWrite(rewardTTL, LOW);
}
else if (timerValue > delayInterval && timerValue <= delayInterval + 6000) {
odor = 1; digitalWrite(valveOdor, HIGH); digitalWrite(valveOdor2, HIGH); digitalWrite(odorTTL, HIGH);
reward = 0; digitalWrite(valveReward, LOW); digitalWrite(valveReward2, LOW); digitalWrite(rewardTTL, LOW);
}
else if (timerValue > delayInterval + 6000 && timerValue <= delayInterval + 6000 + 400) {
odor = 1; digitalWrite(valveOdor, HIGH); digitalWrite(valveOdor2, HIGH); digitalWrite(odorTTL, HIGH);
reward = 1; digitalWrite(valveReward, HIGH); digitalWrite(valveReward2, HIGH); digitalWrite(rewardTTL, HIGH);
}
if (timer.onRestart()) {
randomNumber1 = random(10, 21);
delayInterval = randomNumber1 * 1000;
timer.setTimeout(delayInterval + 6000 + 400);
odor = 0; digitalWrite(valveOdor, LOW); digitalWrite(valveOdor2, LOW); digitalWrite(odorTTL, LOW);
reward = 0; digitalWrite(valveReward, LOW); digitalWrite(valveReward2, LOW); digitalWrite(rewardTTL, LOW);
}
}
void sendLickData (int threshold, int sensorValue, const int lickTTL)
{
if (sensorValue > threshold)
{
digitalWrite(lickTTL, HIGH);
}
else
{
digitalWrite(lickTTL, LOW);
}
}
Please let me know if I've missed anything, I would be happy to share further details if required.
Valve manual.pdf (98.1 KB)