Bluetooth connectivity help, serial.read and strtok

Hi all,

I am currently trying to connect two arduino unos with the HC-05 BT chips. I am trying to send IMU angle values over BT. Eventually I want to upgrade it to Arduino nano BLE’s with the built in BT. I am not well versed in the language and was hoping for some help/advice on my bluetooth code.

  1. I have read online that Serial.read can only read 1 byte at a time, however I have found example codes online that use BTSerial.read with the SoftwareSerial library that can read multiple bytes at a time. Is this truly the case or am I misunderstanding something?

  2. I am pulling and processing the serial.read data in void loop, below my IMU processing code, will this slow down my code since the Serial.read function is much slower than the processing capabilities of the Arduino Uno?

I have the code posted below (with IMU calculations omitted), ideally, the slave device should send data as <123,123> with the first value being the pitch angle and the second value being the roll angle.

//Declare variables

#include <Wire.h>
#define SOP '<'
#define EOP '>'

//define variables for device to angle calculations

//define variables for bluetooth loop
bool started = false;
bool ended = false;
char inData[80];
byte index;
char *strings[10];
char *ptr = NULL;

//define variables for hip angle calculation
float flex, rot, angle_f2, angle_r2;
int vibration = 5;



void setup() {

//IMU Calibration set up here
    
delay(3);                                                          //Delay 3us to have 250Hz for-loop                                    
  Serial.begin(115200);
  loop_timer = micros();                                               //Reset the loop timer
}



void loop() {

//Angle calculations here

 while(micros() - loop_timer < 4000);                                 //Wait until the loop_timer reaches 4000us (250Hz) before starting the next loop
 loop_timer = micros();//Reset the loop timer
  
  

  
 // Read all serial data available, as fast as possible
  while(Serial.available() > 0)                                       //If there is something in the serial monitor, start while loop
  {
    char inChar = Serial.read();                                      //If byte from SM is SOP, aka <, set index to 0 and start the loop
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)                                            //If byte from SM is EOP, aka >, end the loop
    {
       ended = true;
       break;
    }
    else                                                              //If byte from SM is neither SOP or EOP, input incoming characters into inData character array
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

//Tokenize the inData character array to split into different angle readings
  if(started && ended)                                       
  {
    byte index = 0;
    ptr = strtok(inData, ",");  // takes a list of delimiters
    while(ptr != NULL)
    {
        strings[index] = ptr;
        index++;
        ptr = strtok(NULL, ":;");  // takes a list of delimiters
    }

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }

//Pull values from strings array
  int val1 = atoi(strings[0]);
  int val2 = atoi(strings[1]);
  angle_f2 = (float)val1;
  angle_r2 = (float)val2;




//Calculating the angle differences
  flex = angle_pitch_output - angle_f2;
  rot = angle_roll_output - angle_r2;

//Vibration motor
  if(flex >= 90 || abs(rot) >= 10)
  {
    analogWrite(vibration,150);
  }
  else
  {
    analogWrite(vibration,0);
  }
}

Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

…R

Thanks Robin! I am still a little confused regarding the speed of loop. Since the final output of the code should be the angle of the master device minus the angle of the slave device, does the speed of the loop depend on the speed of the Serial.read since it's the slowest part of the loop? Or am I misunderstanding something?

Thanks again!

liux3292:
Thanks Robin! I am still a little confused regarding the speed of loop.

How fast do you need loop() to repeat - in millisecs?

...R