Why even bother if you don't care to explain? I'm trying my best to write a code that will work. I thought that Serial.read() collected one byte from the serial buffer at a time...
It seems like the bytes from the serial buffer is mixed up. Does anyone have know what's going on and how tp fix it?
Below is some test code that works between two standard arduinos. Connect the sending arduino rx pin to the receiving arduino rx pin. Connect the arduino grounds together.
//zoomkat 3-5-12 simple delimited ',' string tx/rx
//from serial port input (via serial monitor)
//and print result out serial port
//Connect the sending arduino rx pin to the receiving arduino rx pin.
//Connect the arduino grounds together.
//What is sent to the tx arduino is received on the rx arduino.
//Open serial monitor on both arduinos to test
String readString;
void setup() {
Serial.begin(9600);
Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}
void loop() {
//expect a string like wer,qwe rty,123 456,hyre kjhg,
//or like hello world,who are you?,bye!,
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
if (readString.length() >1) {
Serial.print(readString); //prints string to serial port out
Serial.println(','); //prints delimiting ","
//do stuff with the captured readString
readString=""; //clears variable for new input
}
}
else {
readString += c; //makes the string readString
}
}
}
What more do you need explained? Your if statement says to do something if there is at least one byte to read. That does not give you permission then to read 4. If you need to read 4, then you need to do that only when Serial.available() says that there are 4 or more available to read.
I figured that a clue might be all that was needed. I guess not, so here's that snippet fixed:
if (Serial.available() >= 4) {
header = Serial.read();
sign = Serial.read();
value = Serial.read();
tail = Serial.read();
There is no reason to use a String or comma delimiter to read binary data, so zoomkat's code does not apply to your situation.
It is lost. The incoming serial buffer is what is called a ring buffer. When the buffer fills up it just writes over the older data. For serial data you need to provide your own buffer and read the data into the buffer as it arrives. And then process it -- you can't work with it when it is in the serial buffer.
For example.
/*
read serial input with \n (newline) as ending delimiter
be sure to send a newline or a carriage return and a newline when using this scheme
non blocking, do other stuff between chars being received
you can use any baud rate
change BUFF_SIZE as needed for expected data
Test string:
Start(99chars)cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc-End
*/
#define BUFF_SIZE 100
char inBuff [ BUFF_SIZE ]; // buffer for incoming serial
unsigned int buffIndex = 0;
char inChar;
void setup ()
{
Serial.begin ( 9600 ); // 300..115200 any baud rate will work
Serial.println ( F (__FILE__) );
Serial.println ( F ( "Read serial until line end (newline) and echo." ) );
Serial.print ( F ( "Buffer size = " ) );
Serial.print ( BUFF_SIZE );
Serial.println ( F ( " chars." ) );
} // setup
void loop ()
{
while ( Serial.available () > 0 ) // read data when it's available
{
inChar = Serial.read ();
switch ( inChar )
{
case '\n': // line complete, do somthing
// echo to serial out for demo
Serial.println ( inBuff );
// reset buffer
buffIndex = 0;
inBuff [ buffIndex ] = '\0';
break;
case '\r': // drop carriage return, if present
break;
default: // append buffer if not full
if ( buffIndex < ( BUFF_SIZE - 1 ) )
{
inBuff [ buffIndex ] = inChar;
buffIndex++;
inBuff [ buffIndex ] = '\0';
}
break;
}
}
} // loop
Another question that has surfaced is, what happens to the serial buffer when a steady stream of data is incomming and the buffer is full?
Nothing happens to the buffer. If there is no room in the buffer, the incoming byte is discarded. This should, of course, never happen, since the Arduino can read data orders of magnitude faster than it can arrive.
The server sends a "" to request data from the thermostat, and the thermostat reads data one char at a time. I did this because I could make it so the server sends single char commands to keep it simple. The slave then sends back a string of data such as
"62h60d8r10n".
The server then looks for each letter indicating the end of a section of data, converts that to a new string and then converts that to an int.
Regarding the buffer again, if nothing is sent to an arduino, is there at any point "garbage" bytes present in the buffer?
When using Serial.read(), is the data collected from the buffer deleted or do I have to flush it?