Optimising bluetooth data transfer from Android app to Arduino

Hi everybody!

I have a project where an app I have written on Android sends two numbers over bluetooth (blueSMIRF) to the Arduino Uno at infrequent intervals (depending on when location services on the phone updates). I have this working 60% of the time, but it is not sufficiently reliable and a takes a few seconds to get the numbers. Would love some ideas on how to improve both the reliability and the speed.

Here is my setup:

  • Bluetooth pairing and connection works fine

  • Android is sending two 3-digit numbers (no decimal places) at each update, corresponding to a distance and bearing

  • In the Android app, I've packaged together the numbers as a string "D100/B200/", where D corresponds to the start of the distance (100 in this case) and "B" corresponds to the start of the bearing (200). The "/" corresponds to the end of each number.

  • This string is sent bytes from the android app using .write("D100/B200/".getBytes);

  • On the Arduino side, the following is called on every loop:

[code]void bluetoothUpdate(){

if (bluetooth.available()) 
 {
      int ascii = bluetooth.read();                 
   
   //ESTABLISH WHETHER WE'RE CURRENTLY RECEIVING DISTANCE OR BEARING
   
     if(ascii == 68)                                //If this character is D (68 is "D" in ascii)     
     {distanceData = true;}                         //Now we're receiving a distance
  
     else if(ascii == 66)                           //If this character is B (66 is "B" in ascii)
     {bearingData = true;}                          //Now we're receiving a bearing
  
  //RECEIVING DISTANCE
      if(distanceData == true){                     //If we are receiving a distance
      if (isDigit(ascii)) {                         //Does received code represent a digit?
      distanceInt =(distanceInt*10)+(ascii-48);}    //Yes: convert to integer and add to “distanceInt”
          
      else if(ascii == 47) {                        //Yes: we have finished receiving this distance (ASCII number 47 represents “/”) 
      float distanceFloat = distanceInt;            //UPDATE DISTANCE VARIABLES     
      distanceToDest = distanceFloat/100;           //UPDATE DISTANCE VARIABLES
      distanceInt=0;                                //Set distance build-up back to zero again  
      distanceData = false;}                        //We're no longer receiving a distance
      }
  
  //RECEIVING BEARING          
      else if(bearingData == true){                 //If we are receiving a bearing
      if (isDigit(ascii)) {                         //Does received code represent a digit?
      bearingInt =(bearingInt*10)+(ascii-48);}      //Yes: convert to integer and add to “bearingInt”
          
      else if(ascii == 47) {                        //Yes: we have finished receiving this bearing (ASCII number 47 represents “/”) 
      bearingToDest = bearingInt;                   //UPDATE BEARING VARIABLE 
      bearingInt=0;                                 //Set bearing build-up back to zero 
      bearingData = false;}                         //We're no longer receiving a bearing 
 }}}

[/code]

It works ok some of the time (~70%), but I have some issues:

  • It sometimes get the number slightly wrong (eg receives 098 instead of 198)
  • It sometimes mixes up distance and bearing
  • It sometimes combines distance and bearing into one number
  • It takes too long to update, because it only receives one digit per loop of code. The project requires this data much faster

I'm fairly new to this, so I'm sure I'm writing something semi-logical but sub-optimal! Any ideas of a better way to do this very much appreciated!!!

Mark

I suspect Mark, you are concatenating the values together on the android platform. I think you need to store them in an array and send the array and then break the array down on the arduino platform.

Thanks, I've now done this with an array and it's working well

Android code:

     byte[] dataSend;
                                dataSend = new byte[9];
                                dataSend[0] = (byte)0xAA;
                                dataSend[1] = (byte)distanceHundreds;
                                dataSend[2] = (byte)distanceTens;
                                dataSend[3] = (byte)distanceUnits;
                                dataSend[4] = (byte)bearingHundreds;
                                dataSend[5] = (byte)bearingTens;
                                dataSend[6] = (byte)bearingUnits;
                                dataSend[7] = (byte)checkTotal;
                                dataSend[8] = (byte)0xFF;

//Sending byte array
                            try {
                                outStream.write(dataSend);

                            } catch (IOException e) {
                                e.printStackTrace();
                            }

Arduino code:

void bluetoothUpdate(){

if (bluetooth.available()) 
 {
   for (int i=0; i <=9 ; i++)
   {
    btData[i] = bluetooth.read(); 
   }

I used one value in the array to store the sum of all the others. This allows you to put a check in place on the Arduino to identify if any data is incorrect

Cheers!