Serial read overrunning (i think?)

Why is this very basic serial read write code to send a command to my serial device and read the response:

#include <SoftwareSerial.h>

SoftwareSerial O2(5,6);
void setup()
{
  Serial.begin(9600);
  O2.begin(9600); 
}

void loop()
{
  O2.println("O"); 
  delay(50); 
   if (O2.available())
  { // If data comes in from sensor, send it out to serial monitor
    Serial.write(O2.read());
  }
}

Reporting a value the first few times to the serial monitor, but then does this:

O 0207.9
O 0207.9
O 0207.9
O 0207.9
O 0207.9
O 0207.9
O 0207.9
OOOOOOOOO 0lOOOOOOOOOOOOOOOO 0lOOOOOOOOOOOOOOOO 0lOOOOOOOOOOOOOOOO 0VOOOOOOOOOOOOOOOO 0¨OOOOOOOOOOOOOOOO 0pOOOOOOOOOOOOOOOO 0nOOOOOOOOOOOOOOOOÁ¹OOOOOOOOOOOOOOO�É‚ºOOOOOOOOOOOOOOOO 02OOOOOOOOOOOOOOO 020OOOOOOOOOOOOOOO 02OOOOOOOOOOOOOOO 02žOOOOOOOOOOOOOOO 02OOOOOOOOOOOOOOO

i have tried moving the delay around, not having it just produces jumbled characters like this:

¤è
“&S¡H¦B�™04h)�’‚¢‰H¨¦¡HL�š
O dÑÑj*‚jè
“&“MC�™š.4�É¢r¢¤¨S¡$&MM…�02hÑ)�’jô É$M=¤&˜r¤‰$˜�¢‚DS&…Ñ’Hš)r“S¦™�H¡Md䦙�¤¡M�)ôÉ$M=r&˜�)r“S¦™žH¡™dj¤Hš)¢&�:Ér¤¢‰&�šÉr¤¢‰&�šô¦™
¤ÐM*“S&…Ѥr¤“S¦™žH¡šdT¤Hš)r“S¦™žH¡Md*j¦™�¤¡M�ôÉ$M¹‚¤¤“S¦™�H¡Md*¤‰$šDHš“§h’M
¢M¹‚¤¤“S¦™�H¡Md
j¦™�¤¡M�)ô“$M=¤I¡šd
‚H¡¡šÉô“

What is going on?

Why don't you use "available()" to wait until there is something to read?

50 milliseconds is a long time at 960 characters per second.

This might work a little better:

#include <SoftwareSerial.h>
SoftwareSerial O2(5,6);
void setup() {
  Serial.begin(9600);
  O2.begin(9600); 
}

void loop() {
  O2.println("O"); 
   while (O2.available()) { // If data comes in from sensor, send it out to serial monitor
      Serial.write(O2.read());
  }
  delay(500); 
}

By using 'while' in place of 'if' it will at least empty the input buffer before sending the request again. I increased the delay to 500 milliseconds. You can make it lower if you really need more than two answers per second.

johnwasser:
This might work a little better:

#include <SoftwareSerial.h>

SoftwareSerial O2(5,6);
void setup() {
  Serial.begin(9600);
  O2.begin(9600);
}

void loop() {
  O2.println("O");
  while (O2.available()) { // If data comes in from sensor, send it out to serial monitor
      Serial.write(O2.read());
  }
  delay(500);
}




By using 'while' in place of 'if' it will at least empty the input buffer before sending the request again. I increased the delay to 500 milliseconds. You can make it lower if you really need more than two answers per second.

Thank you John I will give this a try. This seems to work great! So to recap: if just immediately spits out to the serial monitor anything that comes through the Rx, but while reads everything that comes through and then once nothign is there moves on to the next part of the loop? Is the garbled text a result of an overlap between the softwareserial port trying to Rx and Tx at the same time when I have the if statement in place?

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R

arddos:
So to recap: if just immediately spits out to the serial monitor anything that comes through the Rx, but while reads everything that comes through and then once nothign is there moves on to the next part of the loop?

Yes. Your original loop was sending the request, waiting 50 ms, processing one character of the reply, and going back to sending the request again. If each reply has 10 characters, while you were receiving the first reply you were sending about 9 more requests and waiting a total of half a second. You would never catch up with the replies because every half second you would receive one and send ten more requests.