How to convert a substring to uint8_t or int8_t

I would like to read serial data i receive from another Arduino into a structure (with the format uint8_t or int8_t). The data is sent as following: starting with "<", ending with ">" and is separated by "; "
Reading the data and printing it as a string (called incoming) works very nicely. However, if I try to split the string and put the sub-strings into the individual structure element a conversion from string to uint8_t or int8_t needs to take place. And I do not know how to implement that in the code.

      int ind1 = incoming.indexOf(';'); 
      UARTdata.triangle_button=(incoming.substring(0, ind1));

Many thanks for your help!
The entire code is as the following:

boolean start = false;
String incoming;

// UART data structure
struct UART_Data_Package {
  uint8_t triangle_button;    //one byte --> 0 to 255(2^8-1)
  uint8_t circle_button;  
  uint8_t cross_button;   
  uint8_t square_button;
  uint8_t up_button;
  uint8_t right_button;
  uint8_t down_button;
  uint8_t left_button;
  uint8_t select_button;
  uint8_t start_button;
  uint8_t left_shoulder_button;
  uint8_t right_shoulder_button;
  uint8_t left_trigger_button;
  uint8_t right_trigger_button;
  int8_t left_stick_x;    //one byte --> -128 to 127 (-2^7-1 to 2^7) 1 bit for the minus sign
  int8_t left_stick_y;
  int8_t right_stick_x;
  int8_t right_stick_y;
  uint8_t battery_status;
};

UART_Data_Package UARTdata; //Create a variable with the above structure


void setup() {
  Serial.begin(115200);   // UART via USB
  Serial1.begin(115200);  // UART via Rx Tx Pins

// Set initial default values
  UARTdata.triangle_button=0;
  UARTdata.circle_button=0;  
  UARTdata.cross_button=0;
  UARTdata.square_button=0;
  UARTdata.up_button=0;
  UARTdata.right_button=0;
  UARTdata.down_button=0;
  UARTdata.left_button=0;
  UARTdata.select_button=0;
  UARTdata.start_button=0;
  UARTdata.left_shoulder_button=0;
  UARTdata.right_shoulder_button=0;
  UARTdata.left_trigger_button=0;
  UARTdata.right_trigger_button=0;
  UARTdata.left_stick_x=0;
  UARTdata.left_stick_y=0;
  UARTdata.right_stick_x=0;
  UARTdata.right_stick_y=0;
  UARTdata.battery_status=0;
}

void loop() {
  if(Serial1.available()>0){
    char c = Serial1.read();
    if(c == '<'){
      start=true;
    }
    if(c == '>'){
      start=false;
//      Serial.println(incoming);

      int ind1 = incoming.indexOf(';'); 
      UARTdata.triangle_button=(incoming.substring(0, ind1));
      int ind2 = incoming.indexOf(';', ind1+1);       
      UARTdata.circle_button=incoming.substring(ind1+1, ind2+1);
      int ind3 = incoming.indexOf(';', ind2+1); 
      UARTdata.cross_button=incoming.substring(ind2+1, ind3+1);
      int ind4 = incoming.indexOf(';', ind3+1);      
      UARTdata.square_button=incoming.substring(ind3+1, ind4+1);
      int ind5 = incoming.indexOf(';', ind4+1);        
      UARTdata.up_button=incoming.substring(ind4+1, ind5+1);
      int ind6 = incoming.indexOf(';', ind5+1);       
      UARTdata.right_button=incoming.substring(ind5+1, ind6+1);
      int ind7 = incoming.indexOf(';', ind6+1);       
      UARTdata.down_button=incoming.substring(ind6+1, ind7+1);
      int ind8 = incoming.indexOf(';', ind7+1);       
      UARTdata.left_button=incoming.substring(ind7+1, ind8+1);
      int ind9 = incoming.indexOf(';', ind8+1);       
      UARTdata.select_button=incoming.substring(ind8+1, ind9+1);
      int ind10 = incoming.indexOf(';', ind9+1);       
      UARTdata.start_button=substring(ind9+1, ind10+1);
      int ind11 = incoming.indexOf(';', ind10+1);       
      UARTdata.left_shoulder_button=substring(ind10+1, ind11+1);
      int ind12 = incoming.indexOf(';', ind11+1);       
      UARTdata.right_shoulder_button=substring(ind11+1, ind12+1);
      int ind13 = incoming.indexOf(';', ind12+1);       
      UARTdata.left_trigger_button=substring(ind12+1, ind13+1);
      int ind14 = incoming.indexOf(';', ind13+1);       
      UARTdata.right_trigger_button=substring(ind13+1, ind14+1);
      int ind15 = incoming.indexOf(';', ind14+1);       
      UARTdata.left_stick_x=substring(ind14+1, ind15+1);
      int ind16 = incoming.indexOf(';', ind15+1);       
      UARTdata.left_stick_y=substring(ind15+1, ind16+1);
      int ind17 = incoming.indexOf(';', ind16+1);       
      UARTdata.right_stick_x=substring(ind16+1, ind17+1);
      int ind18 = incoming.indexOf(';', ind17+1);       
      UARTdata.right_stick_y=substring(ind17+1, ind18+1);
      int ind19 = incoming.indexOf(';', ind18+1);       
      UARTdata.battery_status=substring(ind18+1, ind19+1);
      
      incoming="";
    }
    if(c != '<' && start==true){
      incoming+=c;
    }
  }
}

Avoid using Strings, especially on AVR-based Arduinos, as they cause memory problems and program crashes.

The Serial Input Basics tutorial should answer your question.

Though I agree with the sentiment above, you can try the below.

      int ind1 = incoming.indexOf(';'); 
      UARTdata.triangle_button=incoming.substring(0, ind1).toInt();

And the tutorial mentioned above includes an example using atoi() which will work with so-called c-strings.

Here is a way to send and receive a struct via serial so that no conversion is necessary at either end. No Strings attached.

Tested on real hardware.

Send:

#include <SoftwareSerial.h>

const byte ssRX = 5;
const byte ssTX = 6;

SoftwareSerial ss(ssRX, ssTX);
// by groundFungus  aka c.goulding
// send data via serial in a stuct payload

struct Payload
{
   int integer;
   unsigned long timer;
   float floatNum;
   char str[6];
};

Payload payload = {85, 102522, 3.1415, "hello"};

void setup()
{
   Serial.begin(115200);
   ss.begin(9600);
   Serial.println("I send a payload in the form of a struct");
}

void loop()
{
   send();
}

void send()
{
   static unsigned long timer = 0;
   unsigned long interval = 1000;
   if (millis() - timer >= interval)
   {
      timer = millis();
      payload.timer = millis();
      Serial.write((byte*)&payload, sizeof(payload));
      Serial.write('\n');
      //Serial.print("sizeof(payload)  ");
      //Serial.println(sizeof(payload));


      ss.write((byte*)&payload, sizeof(payload));
      ss.write('\n');
   }
}

Receive
Adjust numbytes according to your code.

// by groundFungus  aka c.goulding
// receive data via serial in a stuct payload

#include <SoftwareSerial.h>

const byte ssRX = 5;
const byte ssTX = 6;

SoftwareSerial ss(ssRX, ssTX); 

const byte numBytes = 32;
byte receivedChars[numBytes];   // an array to store the received data for processing
bool newData = false;
byte bytesReceived = 0;

struct Payload
{
   int integer;
   unsigned long timer;
   float floatNum;
   char str[6];
} payload;


void setup()
{
   Serial.begin(115200);
   ss.begin(9600);
   Serial.println("I receive a payload in the form of a struct");
}

void loop()
{
   recvWithEndMarker();
   //showNewData();
   parseData();
   if (newData)
   {
      if (!swapPayload())
      {
         Serial.print("bad data");
         while (1);
      }
      else
      {
         newData = false;
      }
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\n';
   byte rc;

   while (ss.available() > 0 && newData == false)
   {
      rc = ss.read();
      //Serial.print(rc);
      if (rc == '\r') // ignore carriage return
      {
         return;
      }
      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numBytes)
         {
            ndx = numBytes - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         bytesReceived = ndx;
         ndx = 0;
         newData = true;
      }
   }
}

void parseData()
{
   if (newData)
   {
      if (!swapPayload())
      {
         Serial.println(F("bad data"));
         newData = false;
         return;
      }

      Serial.print(payload.integer);
      Serial.print("\t ");
      Serial.print(payload.timer);
      Serial.print("\t ");
      Serial.print(payload.floatNum, 3);
      Serial.print("\t ");
      Serial.println(payload.str);
      //newData = false;
   }
}

bool swapPayloadP()
{
   memcpy(&payload, receivedChars, sizeof(payload));
   return 1;
}

bool swapPayload()
{
     if ((bytesReceived) == sizeof(payload))
   {
      memcpy(&payload, receivedChars, sizeof(payload));
      return 1;
   }
   else
   {
      return 0;
   }
}

Many thanks for all your helpful suggestions. I will implement them in my code! Grate Help!

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