Hello all,
I'm working on a project that requires me to control 8 valves and 4 IR sensors, and send TTLs to the computer. I have posted the links for the valves and IR sensors at the bottom of this post. The main objective of this project is to deliver air and liquid through the valves at specific times, and measure a response from animals by measuring proximity to the IR sensors. 4 of the 8 valves will deliver air, while the other 4 will deliver the liquid. All 4 that deliver air need to be in sync with each other, and all 4 that need to deliver liquid also need to be in sync with each other. The way that I have currently set this system up is that the 4 odor valves are connected to one digital pin (pin 2), the 4 liquid valves are connected to another digital pin (pin 3), and the IR sensors are connected to analog pins A1-A4. Each valve is connected to a 12V 23A external battery supply (link to the battery is also at bottom of the post). The valves are connected to the pins via a transistor (PN2222A, technical details attached.)
The problem with this is that the valves are not working as I need them to. I have set pins 2 and 3 to HIGH when I need them to be on, and LOW when they need to be off. Only some (could be 1,2 or 3 on any given day) of the valves in each group switch on and off correctly. I have tested all the valves many times, and I know that they work when I connect them to the 12V battery supply directly.
All the connections are through a protoboard mounted on the Arduino, and I have checked connectivity through my soldering with a multimeter. I am quite confident that the connections are secure. What other reason could there be for the valves to not work? Is there a limit to how many valves a single pin can switch on/off?
I have attached the circuit diagram for each valve, and the technical details of the valves (operating voltage, etc). The Arduino board that I'm using is the Arduino Mega 2560. Please let me know if I've missed anything and you need more information. The code I am using 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 valveReward = 3;
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(valveReward, 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(odorTTL, LOW);
reward = 0; digitalWrite(valveReward, LOW); digitalWrite(rewardTTL, LOW);
}
else if (timerValue > delayInterval && timerValue <= delayInterval + 6000) {
odor = 1; digitalWrite(valveOdor, HIGH); digitalWrite(odorTTL, HIGH);
reward = 0; digitalWrite(valveReward, LOW); digitalWrite(rewardTTL, LOW);
}
else if (timerValue > delayInterval + 6000 && timerValue <= delayInterval + 6000 + 400) {
odor = 1; digitalWrite(valveOdor, HIGH); digitalWrite(odorTTL, HIGH);
reward = 1; digitalWrite(valveReward, 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(odorTTL, LOW);
reward = 0; digitalWrite(valveReward, LOW); digitalWrite(rewardTTL, LOW);
}
}
void sendLickData (int threshold, int sensorValue, const int lickTTL)
{
if (sensorValue > threshold)
{
digitalWrite(lickTTL, HIGH);
}
else
{
digitalWrite(lickTTL, LOW);
}
}
Links:
Battery supply
IR sensors
[Note: I thought that the IR sensors and TTLs are most likely unrelated to the problem, so I have not given more details about those. I would be happy to share details if you think it is relevant.]
Valve manual.pdf (98.1 KB)
PN2222-D transistor.PDF (198 KB)