Pages: [1] 2   Go Down
Author Topic: Serial - Issues reading and parsing  (Read 1132 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Been trying for hours to figure out what I'm doing wrong here.   I've got a Bluetooth module connected to my Android device.  My device sends byte data as follows:  s25,50e.  My end state project will parse these values to drive motors.  However, before I am able to get there, I have an issue with basic parsing.  I am using the below sketch to troubleshoot my issue.  It reads the bytes and stores them into inData.  My issue is that when I am viewing the first byte (for testing purposes) in the Serial Monitor I get what I am expecting.  However, it stops at 300 iterations.  So, I get a value 300 times, then poof, nothing. Serial.Available is no longer > 0 (tested using an else statement previously).  It seems to be that some sort of buffer is filling up?   I am using an Android device to send the Bluetooth data, and it is sending the data as text s25,50e.  

Edit: I noticed that the more info I try to "Serial.Print" to the Serial Montior, the quicker that Serial.Available seems to stop working (=0).  i.e. I added Serial.Prints for inData[2] up to [7] and it crapped out sooner?

Any thoughts on what I am doing wrong?  I know I am reading bytes, but it is parsing the correct info into the inData array, and I can see the correct values as iterate through the array?



Code:
byte inByte;   // Where to store the Bytes read
char inData[16];  // Allocate some space for the Bytes
byte index = 0;   // Index into array; where to store the Bytes
int i=0;

void setup() {
  Serial.begin(9600);       // start serial communication at 9600bps

}

void loop() {

 if(Serial.available() > 0)
  {
    while (Serial.available() > 0)
    {
      if(index < 15) // One less than the size of the array   (note inData was [10] and this call < 9 before
        {
   inByte = Serial.read(); // Read a Byte
   inData[index] = inByte; // Store it
            if (inData[index] == 'e') break;      
   index++;
        }  
    }

    index = 0;  
 

   switch(inData[0])
    {
      case 's':
        Serial.print("i=");
        Serial.print(i);
        Serial.print(" ");        
        Serial.print(inData[1]);
        Serial.println();
        break;
    }

    i++;
    // clear serialData array
    memset(inData, 0, sizeof(inData));
  }

 delay(50);
}

« Last Edit: March 09, 2013, 07:41:53 am by deejayspinz » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
if(Serial.available() > 0)
  {
    while (Serial.available() > 0)
The if test is unnecessary.

Code:
        Serial.print("i=");
        Serial.print(i);
        Serial.print(" ");       
        Serial.print(inData[1]);
        Serial.println();
If you send "s25,50e". what are you expecting inData[1] to contain?

It should contain '2'.

That code does not illustrate "iterating through the array" and it does not illustrate parsing.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes.  inData[1] returns 2.  However, the issue is, as this data is being send over Bluetooth, Serial.available stops being available after a number of values are returned.  Using the below code as an even simpler example, I am sending data like this:  25,50\n.  When I run this in the Serial Monitor, I get 25 and 50 returned with the below code, it continues until a point and then the Serial Monitor stops showing values?  My Android app shows that data is still being sent over Bluetooth to the Arduino. 

Code:
void setup() {
  // initialize serial:
  Serial.begin(9600);
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int firstNum = Serial.parseInt();
    // do it again:
    int secondNum = Serial.parseInt();

    // look for the newline. That's the end of your
    // sentence:
    if (Serial.read() == '\n') {
     
     


      // print the three numbers in one string as hexadecimal:
      Serial.print(firstNum);
      Serial.print("  ");
      Serial.println(secondNum);
    }
  }
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  while (Serial.available() > 0) {
There is at least one byte to read. You then proceed to read as many as you want. Fail.

One byte available enables one read. There is no way around that.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 183
Posts: 11154
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know how parseInt() behaves and the documentation for it is utterly useless. It might do exactly what you need here, but it might not. What happens if you get extra characters (for example \r) not consumed by parseInt(), or a dropped character, or if the read times out or something? Are you sure your code is going to get back in sync with the incoming stream? It's hard to know, because I don't know what the incoming stream contains or what parseInt() actually does - but it's not at all obvious that it will.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Offline Offline
Tesla Member
***
Karma: 114
Posts: 8911
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
My device sends byte data as follows:  s25,50e

Is the e the end of packet marker? Be aware that on the sending end you may need to use a delay to prevent sending data faster than it can be processed on the receiving end.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Jr. Member
**
Karma: 0
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thx for the tips...  I think it may be an issue with my bluetooth send routine on the Android device.  I'm sending a text string (and not by bytes), but to be honest, I'm a bit green on that part.  Since I've gotten the above to samples (one of which is pretty much verbatim from Arduino.cc) to receive and show data, I'm going to have to look deeper at how I am sending the data as it seems that at some pt, it just stops sending. Problem is my Android procedures don't show any errors...
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.gammon.com.au/serial
Logged

Chicago
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How many time are we going to cover this topic? Thanks Nick G for providing that awesome example for handling multiple character with serial communications.
Don
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46026
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
How many time are we going to cover this topic?
At least once more. Today.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No love in the house eh guys...   I tried Nick's example, and it too parsed data like the rest of the examples I posted, but it too also craps out after so many iterations through the loop.  Serial.Available becomes 0.  Not saying there is anything wrong with his code, or the examples I posted above.  Just trying to understand what I am missing, so go easy please.  It's either the serial buffer is not getting cleared out on the Arduino side, or my Android device  stops sending the data but does not throw any errors.   Is it possible to fill up the Serial buffer using Nick's example?  ie. is it possible for the BT data to come over too quick?  I've got my data sending at (what I think is) a reasonable speed of 200ms between packets.
Logged

Chicago
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nicks code wasn't written for your problem. You should read it figure out whats happening and apply it to solve your problem. Try it yourself you have to experiment..
Logged

0
Offline Offline
Tesla Member
***
Karma: 114
Posts: 8911
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your data packet is delimited by a e (you failed to answer the question concerning this), then you might try substituting an e for the comma , in the below code.

Code:
//zoomkat 3-5-12 simple delimited ',' string parce
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

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.println(readString); //prints string to serial port out
        //do stuff with the captured readString
        readString=""; //clears variable for new input
      }
    } 
    else {     
      readString += c; //makes the string readString
    }
  }
}

Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Offline Offline
Jr. Member
**
Karma: 0
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@zoomkat, thx for the example.  Tried it and substituted the 'e' and, as all the other examples it too worked, but again crapped out in the serial window after a number of values showed.  Maybe I am missing something, but it seems that everyone thinks that I am not getting results from these samples. I am.  The issue is that the serial monitor stops reporting them as Serial.Available is no longer true.

I modified the sample above by adding a counter.  The serial window stops about about ~180 iterations each time.  Below is a dump of the last few values passed:
178  sX=97,Y=-7
179  sX=97,Y=-7
180  sX=97,Y=-7
181  sX=97,Y=-7
182  sX=97,Y=-7
183  sX=97,Y=-7
184  sX=97,Y=-7
185  sX=97,Y=-7
186  sX=97,Y=-7
187  sX=97,Y=-7



Code:
//zoomkat 3-5-12 simple delimited ',' string parce
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}
int i;
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 == 'e') {
      if (readString.length() >1) {
        Serial.print(i);
        Serial.print("  ");
        Serial.println(readString); //prints string to serial port out
        //do stuff with the captured readString
        readString=""; //clears variable for new input
      }
       i++;
    } 
    else {     
      readString += c; //makes the string readString
    }
   
  }

}
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
String readString;

Please note that, at present, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.

Alternatively, install the fix described here:  Fixing String Crashes
Logged

Pages: [1] 2   Go Up
Jump to: