Receiving Text Strings over Bluetooth

Hey d00ds,
I have been trying to send pitch and roll values from my android phone to my arduino Uno (it has a HC-05 bluetooth module) and I can receive text okay... most of the time. The text being sent from my phone is something like this: " 12.34567~0.1234567#"
Where the '
' is the start character, the '~' is the differentiator, and the '#' is the end of message character. The first section of numbers is the roll, the second is the pitch. This is my code to receive the string and output it to the serial monitor.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); //RX, TX

String Data = ""; //initialise a string to hold my message

void setup(){
  Serial.begin(9600);
  mySerial.begin(9600);
}
  
  
  void loop(){
  while(mySerial.available()){
     char character = mySerial.read(); // Receive a single character from the software serial port
        Data.concat(character); // Add the received character to the receive buffer
        if (character == '#')//If end of message character recieved, move on.
        {
        
         Serial.print(Data); //Output the message
           Data =""; //clear the buffer/message
           Serial.println();
           delay(1000);
      
  }
  
}
}

My problem is that in the serial monitor, sometimes I receive garbage numbers. i.e., the first half of a string and then another string on top of it, as if it received two strings at the same time and muddled up. Other times it receives a blank message. The attached picture is my serial monitor output. My phone is sending the strings every 1 millisecond, so I don't think my problem is timing. Any help would be appreciated,
GeekyD00d

What happens with that big delay() in there? Maybe (this is a hint) the serial buffer is overflowing.

My phone is sending the strings every 1 millisecond, so I don't think my problem is timing

20 chars every 1msec = 50usecs per char = 200kBaud.

Hey d00ds, thanks for the replies.

Firstly, I changed my code a bit, and I got it working. But with the one limitation that the Uno can only be reading the serial port for it to work. If I try to blink an LED and then read the serial port, 1/3 of my messages get screwed up like I explained above. I changed the phone's program so it sends the info every 100 milliseconds.
Here is my code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10,11);

String message; //Message buffer

char character; 


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

void loop(){
  roll_pitch();
 // delay(1000); // <-- This delay signifies me doing things other than reading the serial info it's also screwing things up.
}

void roll_pitch(){ //
  while(mySerial.available()){
    character = mySerial.read();
    message.concat(character);
   if(character == '#'){ // if end of message received
     Serial.print(message); //display message and
     message = ""; //clear buffer
     Serial.println();
  }
  }
 }

I need to be able to do other things, but if I'm not polling continuously, my data gets altered. I need to be able to put the code into a function and call it when I need to. But for now, I'm stuck to having to poll forever and do nothing else.
Thanks,
GeekyD00d

The below might be another approach to capturing serial input.

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

GeekyD00d:
If I try to blink an LED and then read the serial port, 1/3 of my messages get screwed up like I explained above.

Well you're not doing it right then. Since you mentioned receiving data and blinking an LED, here is a way to do it:

const byte MAX_STRING_LEN = 40;
const byte LED_PIN        = 13;    
const int  BLINK_INTERVAL = 1000;

char inputString[MAX_STRING_LEN];  // a string to hold incoming data
unsigned long nextMillis = 0;      // when we blink next
byte ledState = LOW;               // Current state of LED (HIGH=On)
byte strLen   = 0;                 // current length of rec'd string

void setup() {
  Serial.begin(19200);             // Change baud rate to suit
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  // Check the serial port for any pending data
  if (processSerial()) {
    // Received a complete string. For now, just echo it back
    Serial.println(inputString);

    inputString[0] = '\0';         // Make sure array is empty
    strLen         = 0;            // reset length to zero
  }   

  // Check to see if we need to blink the LED
  if(millis() - nextMillis > BLINK_INTERVAL) {
    nextMillis += BLINK_INTERVAL; 
    ledState = !ledState;         // Toggle LED state

    // set the LED with the ledState of the variable
    digitalWrite(LED_PIN, ledState);
  }  
}

// Check the Serial port and gather any pending data
boolean processSerial() {
  while (Serial.available()) {
    char inChar = (char)Serial.read(); 

    // We are done receiving the string if we received a return (or line feed)
    if ((inChar == '\n') || (inChar == '\r'))
      return true;

    // add it to the inputString if we have room
    if (strLen < (MAX_STRING_LEN - 1)) {
      inputString[strLen++] = inChar;
      inputString[strLen]   = '\0';
    }
  }

  return false;
}

Notice blinking an LED takes way less than 1000 millis.

I hope this helps,

Brad
KF7FER

Thanks everyone for the replies!
Thanks a lot Brad! I've changed my code so that it only flashes the LED when it has to, without waiting a full second between ons and ofs doing nothing.

Thanks everyone!
GeekyD00d