Go Down

Topic: How to get multiple data via Bluetooth (Read 112 times) previous topic - next topic

sirjolo

Sooo...
Im a beginner at Coding, so pls easy understandable answers ^^
Im trying to send via Androidapp some Data to my Arduino. Following Data is planned to recieve on Arduino:

a char (g / l / r) for direction
a number for the distance

How can I implement the "number" in my Code to print the distance on my OLED?

What I thoght: 
I could send a string from my App (for example: g300). My btData Input would then be not char but string.
Id have to difference between char (g/l/r) and number (300). Would that be possible?
Are there any other ideas how to solve my problem actually more beautiful?

groundFungus

The serial input basics tutorial may be of interest.  If I were doing it I would make a comma delimited data packet and use the example code of example #5 to receive and parse the packet.

More members will see your code if posted properly.  Read the how get the most out of this forum sticky to see how to properly post code.  Remove useless white space and format the code with the IDE autoformat tool (crtl-t or Tools, Auto Format) before posting code in code tags.


groundFungus

example #5 modified to illustrate the method from reply #1.
Code: [Select]

// Example 5 - Receive with start- and end-markers combined with parsing

const byte numChars = 16;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

// variables to hold the parsed data
char dir[2];
int speed = 0;

boolean newData = false;

//============

void setup()
{
   Serial.begin(9600);
   Serial.println("This demo expects 2 pieces of data - a characte for direction and an int for speed");
   Serial.println("Enter data in this style <g,300>  ");
   Serial.println();
}

//============

void loop()
{
   recvWithStartEndMarkers();
   if (newData == true)
   {
      strcpy(tempChars, receivedChars);
      // this temporary copy is necessary to protect the original data
      //   because strtok() used in parseData() replaces the commas with \0
      parseData();
      showParsedData();
      newData = false;
   }
}

//============

void recvWithStartEndMarkers()
{
   static boolean recvInProgress = false;
   static byte ndx = 0;
   char startMarker = '<';
   char endMarker = '>';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();

      if (recvInProgress == true)
      {
         if (rc != endMarker)
         {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars)
            {
               ndx = numChars - 1;
            }
         }
         else
         {
            receivedChars[ndx] = '\0'; // terminate the string
            recvInProgress = false;
            ndx = 0;
            newData = true;
         }
      }

      else if (rc == startMarker)
      {
         recvInProgress = true;
      }
   }
}

//============

void parseData()        // split the data into its parts
{

   char * strtokIndx; // this is used by strtok() as an index

   strtokIndx = strtok(tempChars, ",");     // get the first part - the string
   strcpy(dir, strtokIndx); // copy it to dir

   strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
   speed = atoi(strtokIndx);     // convert this part to an integer, speed
}

//============

void showParsedData()
{
   Serial.print("Direction  ");
   Serial.print(dir);
   Serial.print("     Speed  ");
   Serial.println(speed); 
}


drmpf

#3
Jan 24, 2021, 01:33 am Last Edit: Jan 24, 2021, 01:34 am by drmpf
A few points

If you are just beginning coding to get a project done (as opposed to learning C/C++ programming) you should avoid c-string processing of char[],  and use SafeString library instead (available from the library manager)

It is very easy to make coding mistakes with strcpy and strtok etc.
SafeString provides high level string handling with detailed error msgs and the convenience of Strings but without Arduino Strings memory problems and odd errors

Below is the code sample above re-written using SafeString, and the more common CSV data format, and with added data format error checking in addition to the built-in SafeString error checking.  SafeString takes a little getting use to (check out the detailed tutorial) but will save you a lot of  heartache and coding errors in the future.

Secondly you don't mention what Android app you intend to use to send the string.
For BLE you can use Nordic's BLE UART app and there are also Classic Bluetooth apps available also as well as telnet apps for WiFi connections.

Code: [Select]
// Android app data processor
// sing SafeString library  installed from Library Manager
// tutorial at https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
#include <SafeStringReader.h>

createSafeStringReader(sfReader, 20, "\n\r");  // a line reader that holds 20char

char dir; // direction l or g or r
int speed = 0;
void setup() {
   Serial.begin(9600);
   for (int i= 10; i>0; i--) {
    Serial.print(i); Serial.print(' ');
   }
   Serial.println();
  
   SafeString::setOutput(Serial); // enable error msgs
   sfReader.connect(Serial); // read from this input

   Serial.println("This demo expects CSV (comma separate values) input terminated by newline");
   Serial.println("  a character for direction comma and an int for speed newline");
   Serial.println("e.g. g,300  ");
   Serial.println(" Set the Arduino monitor to Newline endings OR CR NL or CR");
   Serial.println();
  
}

void loop() {
  if (sfReader.read()) {
    // got a line of data
    if(parseData()) {
      showParsedData();
    } else {
      Serial.print(" data format error:");
      Serial.println(sfReader);
    }
    sfReader.clear(); // empty for next line
  }
}


bool parseData() {        // split the data into its parts
  cSF(token,12); // shorthand for createSafeString(token,12);
  size_t idx = 0;
  idx = sfReader.stoken(token,idx,',');
  token.trim(); // remove leading and trailing spaces
  if (token.length() != 1) {
    Serial.print("Invalid direction :"); Serial.println(token);
    return false;
  }
  dir = token[0]; // pickup l or g or r,  the first char of the token
  // check here if vaid direction and return false if not
  if ((dir != 'l') && (dir != 'g') && (dir != 'r') ) {
    Serial.print("Invalid direction :"); Serial.println(dir);
    return false;
  }

  idx = sfReader.stoken(token,idx,',');
  // this is the distance
  if (token.toInt(speed)) {
    // got a valid int
  } else {
    Serial.print(token);
    Serial.println(" Distance not an int :");
    return false;
  }
  return true;
}

//============

void showParsedData() {
   Serial.print("Direction  ");
   Serial.print(dir);
   Serial.print("     Speed  ");
   Serial.println(speed);
}



Go Up