I've got a question about stopping and starting serial communication. I've written some code to pass five numbers between processing (on my mac) and an Arduino (a Sparkfun redboard). Here's my processing:
import processing.serial.*;
Serial arduinoPort;
int incremental = 0;
int incre = 0;
boolean paused = true;
void setup() {
size(400, 600);
arduinoPort = new Serial(this,Serial.list()[2], 9600); //change to correct port number
delay(1000);
arduinoPort.write("0,0,0,0,65,");
}
void draw(){
}
void serialEvent(Serial arduinoPort) {
String answer = arduinoPort.readStringUntil('\n');
if (answer != null) {
println("returned: "+answer);
if (!paused){
String[] fromArduino = split(answer, ' ');
if(fromArduino[4].equals("65") == true) {
incremental++;
} else {
delay(1000);
}
arduinoPort.write(incremental+",25,26,"+incre+",65,");
}
}
}
void keyPressed() {
// if paused == true make it false
if(paused == true) {
paused = false;
println("go");
arduinoPort.write("0,0,0,"+incre+",65,"); //ending comma important to stop arduino searching.
incre++;
} else {
paused = true;
println("stop");
}
}
Where "incremental" is a variable that simply counts up from 0 for each sent packet, and "incre" is a variable that only counts up after each pause cycle. The other numbers sent are just static place holders for future data, and the last number, "65," is for handshaking. Basically, processing sends a string of numbers and commas to the Arduino.
And here's my Arduino code:
const int NUMBER_OF_FIELDS = 5; // how many comma-separated fields we expect
int fieldIndex = 0; // the current field being received
int values[NUMBER_OF_FIELDS]; // array holding values for all the fields
int ledPin = 13;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
}
void loop() {
}
void serialEvent() {
while (Serial.available() == 0) { }
if( Serial.available()) {
for(fieldIndex = 0; fieldIndex < 5; fieldIndex ++){
values[fieldIndex] = Serial.parseFloat(); // get a numeric value
}
fieldIndex = 0; //reset index
if(values[4] == 65){
//do stuff, run motors, etc.
digitalWrite(ledPin, HIGH);
Serial.print(values[0]);
Serial.print(" ");
Serial.print(values[1]);
Serial.print(" ");
Serial.print(values[2]);
Serial.print(" ");
Serial.print(values[3]);
Serial.print(" ");
Serial.print(values[4]);
Serial.println(" "); //println important. processing looks for line return
}else{
digitalWrite(ledPin, LOW);
Serial.println("0 0 0 0 0");
}
values[0] = 0; //clear array
values[1] = 0;
values[2] = 0;
values[3] = 0;
values[4] = 0;
}
}
Where the Arduino parses in a set of five float numbers into an index. If the last number is "65" then it turns on an LED at pin 13, sends back to processing what it received and clears out all the information (in the future it would run motors or do something else also).
Timeline:
- Processing sends "0,0,0,0,65," to Arduino in its setup.
- Arduino listens for a serialevent, then reads the five numbers into an array.
- If the last number is "65" (a static number), then the Arduino mirrors back to processing the info it received (with spaces instead of commas and a line break at the end).
- Processing listens with serialevent for incoming data and buffers until the line break.
- Processing chops the received string into an array. If the last value equals "65" it increments and sends data. Etc.
- Processing, listening for a keypressed event (any key press), can pause this communication. If it pauses, data is no longer sent to the Arduino.
- On a second keypressed event, the loop is unpaused, "incre" is incremented, and data continues to be sent.
My question:
On a pause, data stops being sent. If I pause and unpause quickly, it takes 4-5 seconds for proper data to resume. If I pause, wait longer than 4-5 seconds, and then unpause, no issues. Before I had the "Serial.println("0 0 0 0 0");" in the Arduino code, I could see that the numbers were getting mixed up somewhere. The 65 wasn't always received last. What is going on here? is this a buffer issue with the Arduino? There is something going on with the serial communication? I'm trying to make a fairly robust handshake serial connection between the two devices. Can someone point me to how I can make this so that I can pause/unpause this communication without issue?
Here's a sample processing readout (mid flow during a pause/unpause event):
returned: 261 25 26 4 65
returned: 262 25 26 4 65
stop
returned: 263 25 26 4 65
go
returned: 0 0 0 0 0
returned: 0 0 0 0 0
returned: 0 0 0 0 0
returned: 0 0 0 0 0
returned: 0 0 0 0 0
returned: 263 25 26 5 65
returned: 263 25 26 5 65
returned: 264 25 26 5 65
I know it's kind of long and complex, but I've narrowed down the code as much as I could to describe the issue. I've only been using Processing and Arduino about a month and I'd really appreciate any help or pointers. Thanks, Blake