Hi all,
I'm looking to get some advice on speeding up a little serial chain of arduino pro minis.
I have 13 pro minis plus 1 digital compass (ocean server) communicating to my mac via a bluetooth (bluesmirf). Everything is daisy chained together: Tx of modem >> Rx of compass >> Tx of compass >> Rx of Arduino #1 >> Tx or Arduino #1 >> ... >> Tx or Arduino #13 >> Rx of modem. It's quite an impressive collection of tiny flashing LEDs. The compass is at the beginning of the chain since it sends data as soon as it gets powered up (can't poll it), but I can at least set it's sampling rate. The compass is serial output and is read by the first arduino via the Rx pin, where the line feed character (the end of the packet from the compass) triggers a print of the data from all the analog pins (basically adding the data to the end of the packet), and passes it down the line. I think I've set it up so that while the minis are not dealing with data from the serial port they are reading data from the analog pins. This was one of my efforts to speed things up a bit, thinking that if it wasn't reading AND printing the data when it received a line feed it might take less time. I was originally planning on setting up a little I2C network until I read the fine print about it needing 2 of my 6 analog ports...hence the daisy chain.
Everything is working great, however with each arduino that I've added I've had to lower the sampling rate to ensure that the entire packet (all the data from the compass and the 13 minis) reaches the computer. It now sits at about 12Hz, and was hoping for closer to 40Hz. My code is below, and was wondering if anyone had any pointers on how to speed this up.
Thank you in advance for any guidance.
Cheers,
David
int statusLED = 13; // status LED on Arduino
byte serialIn; // container to hold incoming serial data
// values below are used to determine sampling inverval
unsigned long time_now = 0; // current time
unsigned long time_lastprint = 0; // previous time
unsigned long dt = 0; // elapsed time
unsigned long sampleclock_now = 0; // current time
unsigned long sampleclock_lastread = 0; // previous time
unsigned long sampleclock_dt = 0; // elapsed time
int photo[6]; // holds all the data for the photosensors
unsigned long readclock_0 = 0;
unsigned long readclock_1 = 0;
unsigned long readclock_dt = 0;
// ********** change this for each Arduino in the chain ********** //
int place_in_chain = 1; // = 1 is master, others = slave
// *************************************************************** //
void setup()
{
Serial.begin(57600); // 57600 115200
pinMode(statusLED, OUTPUT); // declare pin as output
for (int i=0; i < place_in_chain; i++){ // flash status LED # flashes = assignment in chain
digitalWrite(statusLED, HIGH);
delay(150);
digitalWrite(statusLED, LOW);
delay(150);
} // end LED flash for loop
for (int i=0; i <= 6; i++){ // set sensor data to 0
photo[i] = 0;
} // end for
} // end setup
void loop()
{
// reads data from analog inputs in background so when line feed comes in
// it merely prints the current values rather than taking time to read the ports
// hopefully this will speed up the sampling a bit given the number of Arduinos in our chain
readclock_0 = micros();
readclock_dt = readclock_0 - readclock_1;
if (readclock_dt >= 1000) // = 1 ms
getInputData(); // get data from analog inputs
readclock_1 = readclock_0;
if (place_in_chain == 1) { // I am the master
while (Serial.available() > 0) { // check serial buffer for any data
serialIn = Serial.read(); // assigns incoming byte to serialIn array
if (serialIn == 10) { // line feed = end of packet from compass
Serial.print(" "); // add a space before getting pin data
getElapsedTime(); // get elapsed time since last pass and print it
printInputData(); // add data from analog inputs
Serial.println(); // print a line break
} // end if for line feed character
else if (serialIn == 44) { // 44 = comma
Serial.print(" "); // replace comma with a space
}
else {
Serial.print(serialIn, BYTE); // if not a line break, then pass along Rx (compass) to the Tx pin (to the modem)
}
} // end while
}
else {
while (Serial.available() > 0) { // check serial buffer for any data
serialIn = Serial.read(); // assigns incoming byte to serialIn array
if (serialIn == 10) { // line feed = end of packet from previous arduino
Serial.print(" "); // add a space before getting pin data
printInputData(); // add this arduinos data to packet
Serial.println(); // print a line break
}
else { // it's not a line feed, so pass the data along
Serial.print(serialIn, BYTE);
} // end serialIn if
} //end while loop
}
}
void getInputData() {
photo[0] = analogRead(0);
photo[1] = analogRead(1);
photo[2] = analogRead(2);
photo[3] = analogRead(3);
photo[4] = analogRead(4);
photo[5] = analogRead(5);
} // end getInputData
void printInputData() {
// add a header
Serial.print("photo_");
Serial.print(place_in_chain);
Serial.print(" ");
Serial.print(photo[0]);
Serial.print(" ");
Serial.print(photo[1]);
Serial.print(" ");
Serial.print(photo[2]);
Serial.print(" ");
Serial.print(photo[3]);
Serial.print(" ");
Serial.print(photo[4]);
Serial.print(" ");
Serial.print(photo[5]);
Serial.print(" ");
} // end printInputData
void getElapsedTime() {
time_now = millis();
dt = time_now - time_lastprint;
Serial.print(dt); // should be last element in list
Serial.print(" ");
time_lastprint = time_now;
} // end getElapsedTime