Arduino Real-time Streaming Reliability Issue

Hi,

I'm trying to send 3 different signals over the serial port on my Arduino Duemillanove. My goal is to be able to send 3 ADC signals to my computer where I can plot them simultaneously and I want to be able to have them plotting in real-time.

I have written this arduino code so send 3 signals over the serial port and to also communicate via the serial input buffer but I am having some reliability issues (read after the code).

[code]

//Set of numbers to communicate thru serial
int x1[5] = {1,2,3,4,5};
int x2[5] = {6,7,8,9,10};
int data = 0;
int i = 0;

String inside = "inside";

// I = 73
// E = 69
// R = 82
// C = 67

void setup()
{
  Serial.begin(9600);
  pinMode(13,HIGH); //to turn LED on
}

void loop()
{
  
  //Debugging block...
  //delay(1500);
  //Serial.print(Serial.read());
  //Serial.flush();
  //Serial.print('\n');
  
  
  //if 'I' is sent to the serial input buffer than...
  if(Serial.read() == 73)
  {
    
     Serial.println(inside);
     Serial.println('\n');
                
    go(); //call the go function which will send the numbers over the serial continuously....
  }
  
  //if 'R' is sent to the serial input buffer than...
  if(Serial.read() == 82)
  {
    
    Serial.print(data); // print 'data', the variable that holds the count for number of data points sent...
    Serial.flush();     // clear the buffer now that we've send over the count...
    
  }
  
  Serial.flush(); //clear the buffer from any miscillaneous junk now that none of the previous conditions have been met...
  
}

//this function sends sets of data via serial....
void go()
{
  digitalWrite(13,HIGH); // turn on LED to indicate that data is being sent via serial...
  
  //unless 'E' is sent to the serial input buffer, don't stop sending data over the serial line...
  while( Serial.read() != 69)
  {
    Serial.flush(); // now that you've checked that E hasn't been pressed, clear the buffer for the heck of it (neatness sort of thing)...
    
    //print first function
    //print delimeter ',' (it's a coma)...
    Serial.print(x1[i]);  
    Serial.print(',');    
    Serial.print(x2[i]);
    Serial.print(',');
    Serial.print(x1[i]);
    Serial.print(',');
    
    Serial.print('\n'); // print 3 in a line for arduino debugging....
    
    data++; //keep count of numbers sent over the serial channel...
    i++;    // send the next number in the X arrays...
    if(i ==5){i = 0;} //make sure you don't step out of the X array...
  }
  
  Serial.flush(); //clean this buffer just for the heck of it....
  digitalWrite(13,LOW); //shut off the LED light, we are no longer sending data...
}

[/code]

The code works as follows:

  1. When "I" sent over the serial Monitor the arduino sends back the string "inside" and follows by continously sending lines of 3 numbers (the array x1, x2)

  2. The arduino will stop sending these numbers when you press "E"

  3. If you send "R" after sending "E" it will print a count of data sets sent during the transmission phase. If you press "R" from the start without pressing "I" the arduino will send you a zero as nothing has been transmitted via the serial loop...

My problem is when I am using the Arduino Serial Monitor I have to send "R" or "I" multiple times in order to get the arduino to enter the "if" statements in the void loop()... This isn't very reliable, especially if I plan on using a program, MATLAB, to do this interfacing for me....

Does anyone know why I might have to send a string via serial 2 or more times in order to get the Arduino to read it ?? Is there something wrong with the Serial Monitor application?

I would truly appreciate any help

You have:

  //if 'I' is sent to the serial input buffer than...
  if(Serial.read() == 73)
if(Serial.read() == 'I')

would work just as well, and be easier to understand.

    Serial.flush();     // clear the buffer now that we've send over the count...

Any data in the input buffer just got deleted. There was no affect on the output buffer.

You really, yes, I mean really, should not be doing this.

  Serial.flush(); //clear the buffer from any miscillaneous junk now that none of the previous conditions have been met...

See above, and stop doing this.

    Serial.flush(); // now that you've checked that E hasn't been pressed, clear the buffer for the heck of it (neatness sort of thing)...

Neatness, my ass. You have no idea how much data you just dumped, or if it was relevant or not.

  Serial.flush(); //clean this buffer just for the heck of it....

No. Just for the heck of it, stop doing this.

My problem is when I am using the Arduino Serial Monitor I have to send "R" or "I" multiple times in order to get the arduino to enter the "if" statements in the void loop().

You don't suppose that all that flushing of the incoming data has anything to do with this, do you?

Does anyone know why I might have to send a string via serial 2 or more times in order to get the Arduino to read it ?

I think so.

Is there something wrong with the Serial Monitor application?

Not a thing. Your code, on the other hand...

Thanks for the help I appreciate it.

I'm going to implement your changes right now but I still don't think my flushes lose me any important data because I always put them after I check for a condition.. If a letter was sent to the input buffer after the flushes it'll be intact until the next "if" statement (serial buffer read in)..

I may be wrong.. but i'll implement your suggestions and let you know of the results...

and Thanks a ton!!

I've implemented the changes but I still have to resend the letters over the Serial Monitor repeatedly. It's random, sometimes I send the letter once and I get a response, other times I have to send it 3 times for the Arduino to process it.

I will say it's better this time that i've got rid of the flushes... here's my new code. Anything you think might be causing these problems? Or do you have any suggestions as to how I can graph 3 signals from the arduino's ADC inputs (my ultimate goal)....

[code]
//Set of numbers to communicate thru serial
int x1[5] = {1,2,3,4,5};
int x2[5] = {6,7,8,9,10};
int data = 0;
int i = 0;

String inside = "inside";

// I = 73
// E = 69
// R = 82
// C = 67

void setup()
{
  Serial.begin(9600);
  pinMode(13,HIGH); //to turn LED on
}

void loop()
{
  
  //Debugging block...
  //delay(1500);
  //Serial.print(Serial.read());
  //Serial.flush();
  //Serial.print('\n');
  
  
  //if 'I' is sent to the serial input buffer than...
  if(Serial.read() == 'I')
  {
    
     Serial.println(inside);
     Serial.println('\n');
                
    go(); //call the go function which will send the numbers over the serial continuously....
  }
  
  //if 'R' is sent to the serial input buffer than...
  if(Serial.read() == 'R')
  {
    
    Serial.print(data); // print 'data', the variable that holds the count for number of data points sent...
    //Serial.flush();     // clear the buffer now that we've send over the count...
    
  }
  
  //Serial.flush(); //clear the buffer from any miscillaneous junk now that none of the previous conditions have been met...
  
}

//this function sends sets of data via serial....
void go()
{
  digitalWrite(13,HIGH); // turn on LED to indicate that data is being sent via serial...
  
  //unless 'E' is sent to the serial input buffer, don't stop sending data over the serial line...
  while( Serial.read() != 69)
  {
    //Serial.flush(); // now that you've checked that E hasn't been pressed, clear the buffer for the heck of it (neatness sort of thing)...
    
    //print first function
    //print delimeter ',' (it's a coma)...
    Serial.print(x1[i]);  
    Serial.print(',');    
    Serial.print(x2[i]);
    Serial.print(',');
    Serial.print(x1[i]);
    Serial.print(',');
    
    Serial.print('\n'); // print 3 in a line for arduino debugging....
    
    data++; //keep count of numbers sent over the serial channel...
    i++;    // send the next number in the X arrays...
    if(i ==5){i = 0;} //make sure you don't step out of the X array...
  }
  
  // Serial.flush(); //clean this buffer just for the heck of it....
  digitalWrite(13,LOW); //shut off the LED light, we are no longer sending data...
}

[/code]

Thanks

  if(Serial.read() == 'I')

What if it wasn't 'I'? You now have no way of comparing it to any of the other cases.

  if(Serial.read() == 'R')

What if it wasn't 'R'? You now have no way of comparing it to any of the other cases.

You never call Serial.available() to see if there actually is data to read. You should. You should also store the value read from the serial port, so you can compare it to multiple values.

  while( Serial.read() != 69)

'I', 'R', and 69? The pattern doesn't make sense.

Please. Do this...

      // send data only when you receive data:
      if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();

            // say what you got:
            Serial.print("I received: ");
            Serial.println(incomingByte, DEC);
      }

MAKE all your MATCH decisions based on one "incomingByte"

If you receive what you expect... take action... but you don't have to keep reading serial since that moves you through serial input stream in an unintended manner.

Your "simple" way almost guarantees that you lose/miss data in the incoming data stream.

You can EASILY make quick "if then" decisions based on 1 SERIAL READ statement...

Your way just about requires that you receive "I" then "R" then "E" in that order... or you toss out good data... so... it's not random at all.

If you want to keep your code neater... try using a SWITCH statement based on incomingByte value

Like this:

switch (incomingByte) {
    case "I":
      //do something when var equals "I"
      break;
    case "R":
      //do something when var equals "R"
      break;
// ETC

    default: 
      // if nothing else matches, do the default
      // default is optional
  }