Hi folks
I've re-written my code and incorporated everything that Paul suggested: Replacing Do-While loops, setting Serial and Serial1 to the same baud rate, and even improving the formatting (see code below); but still no joy. I get a load of garbled text in the Serial Monitor (screen dump jpg attached), and the routine never exits.
To make matters worse, last time I re-compiled the code, it failed to compile with the error message:
'SERIAL_8E1 was not declared in this scope'
This is a new problem, and I haven't changed anything: Still using the same Arduino compiler (1.0.5_v2) and selecting the right Arduino board (Mega 2560).
I'm guessing that the Mega 2560 must be plenty powerful and fast enough to parse 321 bytes of data using a short routine at the relatively slow speed of 19200 baud.
Is it possible that the Mega is running too fast for the data - do I need to slow it down with some carefully placed short delays?
Similarly, I've tried increasing the Hardware Serial buffer (cores>arduino>HardwareSerial.cpp) from 64 to 512 bytes, but this seems to make no difference; so I suspect I'm making a dumb mistake in my code somewhere or missing something...
I understand that indiscriminate flushing of buffers is generally a bad thing, as it can result in data loss; but could a strategically placed "Serial1.flush()" statement be the answer to my problem in this case?
Parsing serial data with DLE is a common enough task (I believe that the www uses a version of this protocol); so if my own efforts are futile, is there maybe a library out there which will perform the task?
Apart from the above, I really have no idea how to proceed... :~
I'd be really grateful for your expert advice.
Thanks again in anticipation for your tolerance and guidance
Dave
byte data[321]; // byte array to store parsed data
byte d = 0; // buffer for reading data
byte e = 0;// buffer for reading data
void setup()
{
Serial.begin(19200,SERIAL_8E1); // for monitoring/debugging via USB & Serial Monitor
Serial1.begin(19200,SERIAL_8E1); // for receiving data from RS232 to TTL adaptor
}
void loop()
{ // receive next packet of data
int state = 1; // reset state to 'Wait'
int n = 0; // reset pointer for data array
// start of 'state machine' loop: state 1 = Wait; state 2 = Read; state 3 = Exit.
while (state <3){ // Wait and Read; otherwise Exit and continue
//------------------------------------------------------
// State = "WAIT"
//------------------------------------------------------
while (state == 1){
Serial.print("State = WAIT ");
Serial.println(state);
while(d != 0x7E){ // if data available, wait for 7E ( = start or end flag)
while (Serial1.available() < 0){ // keep looping until data available
}
d = Serial1.read();
}
/*
If 7E is found, it MUST be a start or finish flag
7E can't occur within the data, as it will have been shifted to "7D5E" by DLE protocol
therefore if we start reading the data mid-packet, or between packets, the program flow will not
get to this point, and just keep reading until 7E is found
*/
Serial.println("7E found");
if (Serial1.available() > 0 ){
// If 7E is followed by more data, this must be a start flag
data[n] = d;
n++;
state = 2; // change state to "Read"
Serial.print("State: READ ");
Serial.println(state);
}
//If no data follows 7E, we're at a stop flag; so keep waiting in the 'WAIT' while loop
} // end of WAIT 'while' loop
//------------------------------------------------------
// State = "READ"
//------------------------------------------------------
while (state == 2){
while (Serial1.available() < 0){ // keep looping until data available
}
/*
Shouldn't need to check Serial1.available(), as we can only get to this point if
we're at start of a data packet, therefore there MUST be bytes of data available
following the start flag...but this might help stability
*/
d = Serial1.read();
// If the byte is not a stop (7E) or shift (7D) byte, add it to the array
if ((d != 0x7E) && (d != 0x7D)){
data[n] = d;
n++;
}
// If the byte is 7E, then this must be a stop flag
if (d == 0x7E){
Serial.println("Stop Flag found");
data[n] = d; // add this 7E to the collected data
state = 3; //and change the state to allow exit from the state machine loop
}
// If the byte is 7D, then we need to shift the next byte
if (d == 0x7D){
Serial.println("Byte shifted");
while (Serial1.available() < 0){ // keep looping until data available
}
/*
Shouldn't need to check for Serial1.available(), as we can only get to this point if
we're in the middle of a data packet, therefore there MUST be bytes of data available
following the shift flag...but this might help stability
*/
e = Serial1.read(); // read next byte
data[n] = e ^ 0x20; // Bitwise XOR next byte with Ox20; so 7D5E->7E, and 7D5D->7D; and save result to the array
n++;
}
} // end of 'READ' while loop
} // end of 'state' while loop
//------------------------------------------------------
// State = "EXIT"
//------------------------------------------------------
Serial.print("State = EXIT ");
Serial.println(state);
Serial.print("Bytes collected: ");
Serial.println(n);
//...continue with more code here to further process received data
} // end of main loop
