Converting string from a HC-12 wireless module to useful data

I have 2 Arduino Unos connected together with HC-12 wireless modules. One Arduino sends a string that is "s22.04e" - the "s" is the start character and the "e" is the end character. Using this sketch on the other Arduino I am able to receive that and take the "22.04" number out and save it to a float.

#include <SoftwareSerial.h>
SoftwareSerial HC12(5, 6);        // HC-12 TX Pin, HC-12 RX Pin

char incomingData;
String readBuffer = "";

float val1 = 0;
float val2 = 0;

void setup() {
  Serial.begin(115200);           // Serial port to computer
  HC12.begin(9600);               // Serial port to HC12
}

void loop() {
  readBuffer = "";
  boolean start = false;
  // Reads the incoming angle
  while (HC12.available()) {             // If HC-12 has data
    incomingData = HC12.read();          // Store each icoming byte from HC-12
    delay(5);
    // Reads the data between the start "s" and end marker "e"
    if (start == true) {
      if (incomingData != 'e') {
        readBuffer += char(incomingData);    // Add each byte to ReadBuffer string variable
      }
      else {
        start = false;
      }
    }
    // Checks whether the received message statrs with the start marker "s"
    else if ( incomingData == 's') {
      start = true; // If true start reading the message
    }
  }
  // Converts the string into integer
  if (readBuffer != "") {
  val1 = readBuffer.toFloat();
 Serial.println(val1, 2);
  }
 delay(1000);

}

My question is this: How do I change the code to be able to receive 2 variables. Let's say I send "s22.04,897.62e", how do I do it so that I receive a Val1 = 22.04 and Val2 = 897.62?

The Serial Input Basics tutorial on this forum shows you how to do that.

You should avoid using Strings, especially on AVR Arduinos like the Uno, Mega, etc. as Strings cause memory problems and program crashes.

Instead, use C-strings (zero terminated character arrays). There are a bunch of simple routines in the <string.h> library that make doing what you want very easy. In particular strtok() splits up a string into "tokens" that can be interpreted in various ways.

This example program shows some of the methods in use.

// examples of strtok()

char delim[] = " :,";  //substring delimiters

void setup() {
  char* pch;
  char message[] = "X, 35.3 Y: 44 Z:10.5";  //make up a line with some data to be parsed

  Serial.begin(115200);

  Serial.print("message >");
  Serial.print(message);
  Serial.println("<");


  pch = strtok(message, delim);
  Serial.print("strtok returns >");
  Serial.print(pch);
  Serial.println("<");

  pch = strtok(NULL, delim);
  Serial.print("strtok returns >");
  Serial.print(pch);
  Serial.println("<");

  Serial.print("atoi returns: ");
  Serial.println(atoi(pch));
  Serial.print("atof returns: ");
  Serial.println(atof(pch));
  // etc.
}

void loop() {}

Output:

message >X, 35.3 Y: 44 Z:10.5<
strtok returns >X<
strtok returns >35.3<
atoi returns: 35
atof returns: 35.30

1 Like

You could also use the SerialTransfer Library to send multiple values contained in a struct. They would be sent in binary which is more efficient than using ASCII.

1 Like

Thank you, that SerailTransfer library works beautifully! :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.