Programming problem for bee tracking and nectar delivery system
in
Contributed Library Questions
•
6 months ago
Hi, I don't have any background in programming (unless you count making basic shapes in BASIC in 7th grade) but I have what is probably an overly ambitious project I am doing for work. I have all of the hard parts working but now I am being frustrated by what I'm sure is a simple problem.
A little background: I created a sketch that collects real-time UDP information from a RFID system that is tracking tagged bees. It is set up to deliver a small amount of sucrose solution to artificial flowers from a gravity feed solenoid valve when a bee is detected by the reader. There is also a wait time built into the program so that a valve is turned offline for a certain period of time so that a bee can not just hang out at the artificial flower and keep getting fed. The processing code uses firmata to control an arduino mega that open and close the valves. The program also parses the data and sends it to a text file. After much work I got it all working but there seems to be a bug. Once in a while the valves stay open and do not close after a tag has been detected at the reader. Obviously, it must be a problem in how I coded the valves to close but I'm not sure how to tackle it.
I put it in the 'programming questions' forum section because I think it just requires a programming solution since the libraries and hardware are functioning correctly. Please let me know if I should move my question to a more appropriate section.
Any help would be greatly appreciated.
Here is the code:
import hypermedia.net.*; // Import firmata library
import processing.serial.*; // Import processing serial communications library
import cc.arduino.*; // Import arduino library
PrintWriter output; // Create object output that allows characters to print to a
// text-output stream
// Assign port number that RFID host is using to transmit data over UDP
int PORT_RX=11001;
// Assign valves to corresponding pins on the Arduino board
int Valve0 = 23;
int Valve1 = 25;
int Valve2 = 27;
int Valve3 = 29;
int Valve4 = 31;
int Valve5 = 33;
int Valve6 = 35;
int Valve7 = 37;
int Valve8 = 39;
int Valve9 = 41;
int Valve10 = 43;
int Valve11 = 45;
int Valve12 = 47;
int Valve13 = 49;
int Valve14 = 51;
int Valve15 = 53;
// Assign variables that count elapsed time since a valve is turned on (open)
long timeron0 = 0;
long timeron1 = 0;
long timeron2 = 0;
long timeron3 = 0;
long timeron4 = 0;
long timeron5 = 0;
long timeron6 = 0;
long timeron7 = 0;
long timeron8 = 0;
long timeron9 = 0;
long timeron10 = 0;
long timeron11 = 0;
long timeron12 = 0;
long timeron13 = 0;
long timeron14 = 0;
long timeron15 = 0;
// Assign variables that count elapsed time since the valve was last open
long wait0 = millis();
long wait1 = millis();
long wait2 = millis();
long wait3 = millis();
long wait4 = millis();
long wait5 = millis();
long wait6 = millis();
long wait7 = millis();
long wait8 = millis();
long wait9 = millis();
long wait10 = millis();
long wait11 = millis();
long wait12 = millis();
long wait13 = millis();
long wait14 = millis();
long wait15 = millis();
// flowersp represents experimentally derived amount of time a valve needs to remain
// open to give same amount of volume ( > molar solutions are more viscous and
// require more time). This time will change based on starting height of valve and
// opening size of needle or pippette tip.
int flowersp1 = 44; // Flower "species" 1 (large blue flowers) - Sucrose Molarity = 2.0
int flowersp2 = 38; // Flower "species" 2 (medium white flowers) - Sucrose Molarity = 1.5
int flowersp3 = 34; // Flower "species" 3 (small yellow flowers) - Sucrose Molarity = 1.0
int flowersp4 = 32; // Flower "species" 4 (small pink flowers) - Sucrose Molarity = 0.5
// Assign time that must be passed before a valve will be allowed to open again
int waittime = 30000;
int serialCount = 0; // Keeps track of when a tag is read
String HOST_IP = "xxx.xxx.xxx.xxx";// IP Address of PC in which this App is running
String readerid ="00000"; // Declare the variable readerid
String tagnumber; // Declare variables of UID information
String scancount;
String date;
String time;
UDP udp; // Create UDP object for receiving
Arduino arduino; // Create a variable of type Arduino object
void setup(){
println(Serial.list()); //print a list of avaliable serial ports
// Create a new connection on the specified port and wait for incoming message
udp= new UDP(this, PORT_RX, HOST_IP);
udp.log(true); // Start a log of incoming udp messages
udp.listen(true); // Start waiting constantly for incoming data
// Port configuration, your offset may vary
arduino = new Arduino(this, Arduino.list()[3], 57600);
// The port value (the value in brackets []) may change if USB cables are unplugged
// or if computer is restarted
// Set pins assigned to Valves as outputs on the Arduino board
arduino.pinMode(Valve0, Arduino.OUTPUT);
arduino.pinMode(Valve1, Arduino.OUTPUT);
arduino.pinMode(Valve2, Arduino.OUTPUT);
arduino.pinMode(Valve3, Arduino.OUTPUT);
arduino.pinMode(Valve4, Arduino.OUTPUT);
arduino.pinMode(Valve5, Arduino.OUTPUT);
arduino.pinMode(Valve6, Arduino.OUTPUT);
arduino.pinMode(Valve7, Arduino.OUTPUT);
arduino.pinMode(Valve8, Arduino.OUTPUT);
arduino.pinMode(Valve9, Arduino.OUTPUT);
arduino.pinMode(Valve10, Arduino.OUTPUT);
arduino.pinMode(Valve11, Arduino.OUTPUT);
arduino.pinMode(Valve12, Arduino.OUTPUT);
arduino.pinMode(Valve13, Arduino.OUTPUT);
arduino.pinMode(Valve14, Arduino.OUTPUT);
arduino.pinMode(Valve15, Arduino.OUTPUT);
// Assign date and time info from the host computer to variables
int d = day();
int mo = month();
int y = year();
int h = hour();
int mi = minute();
// Convert these integers variables into strings
String sd = str(d);
String smo = str(mo);
String sy = str(y);
String sh = str(h);
String smi = str(mi);
// Join these variables to make a filename based on date/time the sketch starts
String exptdate = sy + "." + smo + "." + sd + "." + sh + smi;
// Create a new file in the sketch folder that PrintWriter will write to
output = createWriter("foragingdata."+exptdate+"a.txt");
}
void receive(byte[] data, String HOST_IP, int PORT_RX){
serialCount++; // Everytime a tag is read add 1 to the serialCount number
String value=new String(data);
// Count characters in data stream until 'R' in READER_ID; assign that number to ri
int ri = value.indexOf("READER_ID");
// Pull out string of char. btwn the 10th and 15th char. after ri; assign to readerid
readerid = value.substring(ri+10,ri+15);
int tn = value.indexOf("UID");
tagnumber = value.substring(tn+4,tn+27);
int sc = value.indexOf("SCANCOUNT");
scancount = value.substring(sc+10,sc+11);
date = value.substring(tn+28,tn+38);
time = value.substring(tn+39,tn+47);
// Print the newly created values to the console
println(date+","+time+","+readerid+","+tagnumber+","+scancount);
//0 - Steps to take if a reader detects a tag
if (readerid.equals("50144") // IF specified reader detects a tag
&& wait0 + waittime < millis() // AND it has been more than the specified
// waittime since valve has been open
&& scancount.equals("0") == false){ // AND scancount > 0 (eliminates false reads)
timeron0 =millis(); // THEN set timeron variable
wait0 =millis();} // AND wait variable to time since program started
if (millis() - timeron0 < flowersp1) { // IF time since tag detected is less
// then specified for the specified
// flower "species"
arduino.digitalWrite(Valve0, Arduino.HIGH); // THEN turn on (open) valve
}
//1
if (readerid.equals("50147") && wait1 + waittime < millis()
&& scancount.equals("0") == false) {
timeron1 =millis(); wait1 = millis();}
if (millis() - timeron1 < flowersp2) {
arduino.digitalWrite(Valve1, Arduino.HIGH);
}
//2
if (readerid.equals("50148") && wait2 + waittime < millis()
&& scancount.equals("0") == false) {
timeron2 =millis(); wait2 = millis();}
if (millis() - timeron2 < flowersp3) {
arduino.digitalWrite(Valve2, Arduino.HIGH);
}
//3
if (readerid.equals("50145") && wait3 + waittime < millis()
&& scancount.equals("0") == false) {
timeron3 =millis(); wait3 = millis();}
if (millis() - timeron3 < flowersp4) {
arduino.digitalWrite(Valve3, Arduino.HIGH);
}
//4
if (readerid.equals("50150") && wait4 + waittime < millis()
&& scancount.equals("0") == false) {
timeron4 =millis(); wait4 = millis();}
if (millis() - timeron4 < flowersp1) {
arduino.digitalWrite(Valve4, Arduino.HIGH);
}
//5
if (readerid.equals("50149") && wait5 + waittime < millis()
&& scancount.equals("0") == false) {
timeron5 =millis(); wait5 = millis();}
if (millis() - timeron5 < flowersp2) {
arduino.digitalWrite(Valve5, Arduino.HIGH);
}
//6
if (readerid.equals("50146") && wait6 + waittime < millis()
&& scancount.equals("0") == false) {
timeron6 =millis(); wait6 = millis();}
if (millis() - timeron6 < flowersp3) {
arduino.digitalWrite(Valve6, Arduino.HIGH);
}
//7
if (readerid.equals("50151") && wait7 + waittime < millis()
&& scancount.equals("0") == false) {
timeron7 =millis(); wait7 = millis();}
if (millis() - timeron7 < flowersp4) {
arduino.digitalWrite(Valve7, Arduino.HIGH);
}
//8
if (readerid.equals("50143") && wait8 + waittime < millis()
&& scancount.equals("0") == false) {
timeron8 =millis(); wait8 = millis();}
if (millis() - timeron8 < flowersp1) {
arduino.digitalWrite(Valve8, Arduino.HIGH);
}
//9
if (readerid.equals("50140") && wait9 + waittime < millis()
&& scancount.equals("0") == false) {
timeron9 =millis(); wait9 = millis();}
if (millis() - timeron9 < flowersp2) {
arduino.digitalWrite(Valve9, Arduino.HIGH);
}
//10
if (readerid.equals("50139") && wait10 + waittime < millis()
&& scancount.equals("0") == false) {
timeron10 =millis(); wait10 = millis();}
if (millis() - timeron10 < flowersp3) {
arduino.digitalWrite(Valve10, Arduino.HIGH);
}
//11
if (readerid.equals("50141") && wait11 + waittime < millis()
&& scancount.equals("0") == false) {
timeron11 =millis(); wait11 = millis();}
if (millis() - timeron11 < flowersp4) {
arduino.digitalWrite(Valve11, Arduino.HIGH);
}
//12
if (readerid.equals("50142") && wait12 + waittime < millis()
&& scancount.equals("0") == false) {
timeron12 =millis(); wait12 = millis();}
if (millis() - timeron12 < flowersp1) {
arduino.digitalWrite(Valve12, Arduino.HIGH);
}
//13
if (readerid.equals("50136") && wait13 + waittime < millis()
&& scancount.equals("0") == false) {
timeron13 =millis(); wait13 = millis();}
if (millis() - timeron13 < flowersp2) {
arduino.digitalWrite(Valve13, Arduino.HIGH);
}
//14
if (readerid.equals("50138") && wait14 + waittime < millis()
&& scancount.equals("0") == false) {
timeron14 =millis(); wait14 = millis();}
if (millis() - timeron14 < flowersp3) {
arduino.digitalWrite(Valve14, Arduino.HIGH);
}
//15
if (readerid.equals("50134") && wait15 + waittime < millis()
&& scancount.equals("0") == false) {
timeron15 =millis(); wait15 = millis();}
if (millis() - timeron15 < flowersp4) {
arduino.digitalWrite(Valve15, Arduino.HIGH);
}
}
void draw(){
if(serialCount>0 && scancount.equals("0") == false){ // IF a tag has been read AND
// the scan count is not 0
output.println(date+","+time+","+readerid+","+tagnumber+","+scancount);
// THEN print the tag info
// to the output file
output.flush(); // Actually write the bytes to
// the file
serialCount = 0; // Reset the variable that
} // tracks if a tag was read
//0 - Check to see if it's time to turn off a valve
if (millis() - timeron0 > flowersp1) { // IF valve has been open for longer than
// specified for its "species"
arduino.digitalWrite(Valve0, Arduino.LOW); // THEN turn off valve
}
//1
if (millis() - timeron1 > flowersp2) {
arduino.digitalWrite(Valve1, Arduino.LOW);
}
//2
if (millis() - timeron2 > flowersp3) {
arduino.digitalWrite(Valve2, Arduino.LOW);
}
//3
if (millis() - timeron3 > flowersp4) {
arduino.digitalWrite(Valve3, Arduino.LOW);
}
//4
if (millis() - timeron4 > flowersp1) {
arduino.digitalWrite(Valve4, Arduino.LOW);
}
//5
if (millis() - timeron5 > flowersp2) {
arduino.digitalWrite(Valve5, Arduino.LOW);
}
//6
if (millis() - timeron6 > flowersp3) {
arduino.digitalWrite(Valve6, Arduino.LOW);
}
//7
if (millis() - timeron7 > flowersp4) {
arduino.digitalWrite(Valve7, Arduino.LOW);
}
//8
if (millis() - timeron8 > flowersp1) {
arduino.digitalWrite(Valve8, Arduino.LOW);
}
//9
if (millis() - timeron9 > flowersp2) {
arduino.digitalWrite(Valve9, Arduino.LOW);
}
//10
if (millis() - timeron10 > flowersp3) {
arduino.digitalWrite(Valve10, Arduino.LOW);
}
//11
if (millis() - timeron11 > flowersp4) {
arduino.digitalWrite(Valve11, Arduino.LOW);
}
//12
if (millis() - timeron12 > flowersp1) {
arduino.digitalWrite(Valve12, Arduino.LOW);
}
//13
if (millis() - timeron13 > flowersp2) {
arduino.digitalWrite(Valve13, Arduino.LOW);
}
//14
if (millis() - timeron14 > flowersp3) {
arduino.digitalWrite(Valve14, Arduino.LOW);
}
//15
if (millis() - timeron15 > flowersp4) {
arduino.digitalWrite(Valve15, Arduino.LOW);
}
}
void stop() { // Tasks to be performed before the sketch closes
output.flush(); // Finish writing any data to output file
output.close(); // Close the output file
}
1