Receiving data from Bluetooth for multiple sensors. [SOLVED]

Hi there! Slightly new to all of this, I've done my best to avoid having to post but feel I've got to the point of having to do it now. I've been reading/testing with lots of different ideas on this forum and others to try and get my code going, so I apologize if this is something really basic.

I'm making a small sensor device to go into a greenhouse to record basic things such as temperature and humidity, and will expand in the future to include light ect. Though for now it is just temperature & humidity. These sensors are connected to an Arduino Uno, which then sends the data through a slave HC-05 to a master HC-05 which is connected to another Arduino Uno in the house.

The Bluetooth is connected and working and I can send data between them, the issue is parsing the data.

I currently am sending it in the form of CSV, so I will receive a message of 22.40,55.80 --> this corresponds to temperature and humidity. Is there an easy way to parse the 2 sensor readings from this into variables which I can then use for an LCD ect.

The current code I am trying to get working is shown below, which isn't outputting any values at all, just the text shown.

#include <SoftwareSerial.h>
SoftwareSerial EEBlue(8, 10); // RX | TX

//Variables
String data;           
void setup()
{
  Serial.begin(9600);
  EEBlue.begin(38400); 
}
 
void loop()
{

  if (EEBlue.available()){
     // data = EEBlue.readStringUntil('\n');      
     // Serial.println(data);


      String temp  = Serial.readStringUntil(',');
      Serial.read(); //Read the comm
      String humidity = Serial.readStringUntil(',');
      
      Serial.println("Temp = ");
      Serial.print(temp);
      Serial.println("Hum = ");
      Serial.print(humidity);
      }
  }

If anybody can point me in the right direction, whether that is by helping or pushing me towards a good tutorial for what I'm trying to do that would be great :slight_smile: If you need any more information to try and help me please ask :slight_smile: Thank you in advance.

Is there an easy way to parse the 2 sensor readings from this into variables which I can then use for an LCD ect.

Depends on what you think of as easy. Calling strtok() and atof() seems pretty easy to me.

There is NO reason to use the String class. Make an educated decision as to how big a fixed length array needs to be to hold all the data, and use a char array instead.

PaulS:
Depends on what you think of as easy. Calling strtok() and atof() seems pretty easy to me.

How would I go about calling strtok()?And pushing those into separate variables. Sorry for asking more questions, quite new to this :slight_smile:

How would I go about calling strtok()?

"Yoohoo, strtok, where are you?"

I'm pretty sure google found at least one example.

char *data = "pig whistle";

char *animal = strtok(data, " ");
char *toy = strtok(NULL, " ");

Serial.print("The ");
Serial.print(animal);
Serial.print(" blew the ");
Serial.println(toy);

PaulS:

char *data = "pig whistle";

char *animal = strtok(data, " ");
char *toy = strtok(NULL, " ");

Serial.print("The ");
Serial.print(animal);
Serial.print(" blew the ");
Serial.println(toy);

I've adapted the example above, shown below, though it outputs it correctly the first time, then only outputs the temperature variable.
At first I was wondering if the 'NULL' should be there, though have no idea what I'd change it too. Am I being an idiot here and doing something stupid? :slight_smile: Thanks in advance

char *data = "23.80 55.60";

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

void loop() {
  char *temp = strtok(data, " ");
  char *humidity = strtok(NULL, " ");

  Serial.println(temp);
  Serial.println(humidity);
  delay(2000);
}

Look at what strtok actually does.

This code executes once when the Arduino starts up...

char *data = "23.80 55.60";

This code...

char *temp = strtok(data, " ");

Looks for the first " " and replaces it with a string terminator.

Now your data variable looks exactly like you started your code with...

char *data = "23.80";

If you reset data every time round the loop (as will be the case if you are reading fresh data from the Bluetooth) this won't be a problem.

Edit: NULL is correct. It means continue scanning from where you left off after the last call, instead of from the start (which is what passing non-NULL "data" means). strtok reference.

However, if you have already completely scanned the string once (first time through loop) this has modified it by putting string terminators at each token delimiter. You can't scan it again (second time through loop). If you try it is like the string had only one token in it in the first place.

ah perfect, that makes complete sense now. Thanks for all the help guys :slight_smile:

The reason that your code extracted the data correctly the first time and not on subsequent iterations is that strtok() is a destructive function. It modifies the string being parsed.

On the second iteration, the string being parsed is not "23.80 55.60". It is "23.80" because strtok() put a NULL where it found a delimiter.

Calling strtok() will NULL as the first argument causes strtok() to parse the rest of the string ("55.60").