Serial communication

I have encountered a problem when I'am trying send data between two arduinos (TX: Nano, RX: Due) via serial. The TX code is as follows:

int analogValue2 = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  // read analog input
  analogValue2 = analogRead(2)/4;
  analogValue3 = analogRead(3)/4;

  Serial.write('A'); //Header
  Serial.write('P'); //Sign
  Serial.write(analogValue2);
  Serial.write('A'); //Tail

  Serial.write('B'); //Header
  Serial.write('P'); //Sign
  Serial.write(analogValue3);
  Serial.write('B'); //Tail
 
  delay(150);      // A time delay seems vital...
}

and the RX code:

byte header, sign, value, tail = 0;

void setup() {
    Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {  
      header = Serial.read();
      sign = Serial.read();
      value = Serial.read();
      tail = Serial.read();
      
      Serial.println(char(header));
      Serial.println(char(sign));
      Serial.println(value);
      Serial.println(char(sign));
      }
}

The output I get in the serial monitor at the RX-side is stuff like this:

P
P
4
66
%
---------------
A
B
80
A
---------------

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?

Best regards

  if (Serial.available() > 0) {  
      header = Serial.read();
      sign = Serial.read();
      value = Serial.read();
      tail = Serial.read();

The presence of one byte does not mean that you can read 4. Never has. Never will.

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
    }
  }
}

Why even bother if you don't care to explain?

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.

Thank you zoomkat and PaulS! I'm truly grateful for your help! I have managed to get my code to (almost) work as intended!

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?

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.

Take a look at my thermostat and server sketches. They work very well together.

Thermostat RTC v4.0 - Pastebin.com starting at line 712, void serialEvent() and
Web Server for Thermostat RTC - Pastebin.com starting at line 283, void serialEvent().

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.

Thank you guys!

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?

I will take a look at your program vulture2600!

if nothing is sent to an arduino, is there at any point "garbage" bytes present in the buffer?

No.

When using Serial.read(), is the data collected from the buffer deleted

Yes.

or do I have to flush it?

How would you? The flush() method blocks until the outgoing serial buffer is empty. It has nothing to do with the incoming buffer.