multiple floats from one char array

hello everyone

im having a hard time coming up with code for getting multiple floats from one char array. I get one sentence from radio module that looks somethink like this "2800V6942I2953T000S" and ends with \0. I want to get numbers between letters and asign them to correct value based on letter after number. my current code looks like this but isnt working

void decodeInformation() {

  int counter = 0;
  for (int x = 0; x <= sizeof(information); x++) {
    if (information[x] != "U" || information[x] != "I" || information[x] != "T" || information[x] != "S") {
      buff[counter] = information[x];
   
    }
    else {
      switch (information[x]) {
        case 'U': skateBatVoltage = atof(buff); skateBatVoltage = skateBatVoltage / 100;break;
        case 'I': skateCurrent = atof(buff); skateCurrent = skateCurrent / 100; break;
        case 'T': temperature = atof(buff); temperature = temperature / 100; break;
        case 'S': skateSpeed = atof(buff); skateSpeed = skateSpeed / 100; break;
        default: break;
      }
      counter = 0;
      buff[0] =  '\0';
    }
  }
}

any help is appreciated :slight_smile:

You never increment counter and you don’t place a ‘\0’ in buff before you atof it.

If that is your code, not just what it looks like.

a7

oh i see. thanks i will try it

Isn't working is the most terrible phrase. Explain what is does and what you expected.

And for better help, make it into a mcve. For all we know 'buffer' is just 1 char big.

Also, why to a float? Values in the string are clearly no floats. And if the micro is an 8-bit (Uno etc), try to avoid float and just store it and know when you want to use it the value is 100 times "to big".

i modified a code a bit, added serial prints to debug,heres code

void decodeInformation() {
  Serial.println(information);
  Serial.println(sizeof(information));
  int counter = 0;
  for (int x = 0; x <= sizeof(information); x++) {
    if (information[x] != 'U' || information[x] != 'I' || information[x] != 'T' || information[x] != 'S') {
      buff[counter] = information[x];
      Serial.println(buff[counter]);
      Serial.println(counter);
      Serial.println(x);
      counter++;
    }
    else {
      strcat(buff, '\0');
      switch (information[x]) {
        case 'U': skateBatVoltage = atof(buff); skateBatVoltage = skateBatVoltage / 100;Serial.print("skateBatVoltage");Serial.println(skateBatVoltage);break;
        case 'I': skateCurrent = atof(buff); skateCurrent = skateCurrent / 100;Serial.print("skateCurrent");Serial.println(skateCurrent); break;
        case 'T': temperature = atof(buff); temperature = temperature / 100;Serial.print("temperature");Serial.println(temperature); break;
        case 'S': skateSpeed = atof(buff); skateSpeed = skateSpeed / 100;Serial.print("skateSpeed");Serial.println(skateSpeed); break;
        default: break;
      }
      counter = 0;
      strcpy(buff,'\0');
    }
  }
}

and here is output from serial monitor
2500U6942I2953T0S - full message
18 - sizeof message
2 - buff[counter]
0 - counter
0 - x
5
1
1
0
2
2
0
3
3
U
4
4
6
5
5
9
6
6
4
7
7
2
8
8
I
9
9
2
10
10
9
11
11
5
12
12
3
13
13
T
14
14
0
15
15
S
16
16

it looks like the if condition is always true, but i dont know why

NO! So close…

You can't strcat to an unterminated string.

strcat(buff, '\0'); // No!

instead do

buff[counter] = '\0';

a7

thanks, replaced it, still acting same...

void decodeInformation() {
  Serial.println(information);
  Serial.println(sizeof(information));
  int counter = 0;
  for (int x = 0; x <= sizeof(information); x++) {
    if (information[x] != 'U' || information[x] != 'I' || information[x] != 'T' || information[x] != 'S') {
      buff[counter] = information[x];
      Serial.println(buff[counter]);
      Serial.println(counter);
      Serial.println(x);
      counter++;
    }
    else {
      buff[counter] = '\0';
      switch (information[x]) {
        case 'U': skateBatVoltage = atof(buff); skateBatVoltage = skateBatVoltage / 100;Serial.print("skateBatVoltage");Serial.println(skateBatVoltage);break;
        case 'I': skateCurrent = atof(buff); skateCurrent = skateCurrent / 100;Serial.print("skateCurrent");Serial.println(skateCurrent); break;
        case 'T': temperature = atof(buff); temperature = temperature / 100;Serial.print("temperature");Serial.println(temperature); break;
        case 'S': skateSpeed = atof(buff); skateSpeed = skateSpeed / 100;Serial.print("skateSpeed");Serial.println(skateSpeed); break;
        default: break;
      }
      counter = 0;
      strcpy(buff,'\0');
    }
  }
}

for (int x = 0; x <= sizeof(information); x++)
Why not
for (int x = 0; x < strlen(information); x++) ?

You can't strcpy() from a char as well (as it's an unterminated string as well). No need to clear the buffer anyway.

My implementation including debug

char buffer[100];
byte bufferIndex = 0;

long skateBatVoltage, skateCurrent, temperature, skateSpeed = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  if(Serial.available()){
    if(Serial.peek() == '\n'){
      Serial.read();
      buffer[bufferIndex++] = '\0';

      Serial.print("Buffer: ");
      Serial.println(buffer);

      decodeInformation(buffer);

      Serial.print("skateBatVoltage: ");
      Serial.println(skateBatVoltage);
      Serial.print("skateCurrent:  ");
      Serial.println(skateCurrent);
      Serial.print("temperature: ");
      Serial.println(temperature);
      Serial.print("skateSpeed: ");
      Serial.println(skateSpeed);

      bufferIndex = 0;
    }
    else{
     buffer[bufferIndex++] = Serial.read();
    }
  }

}

void decodeInformation(char str[]){
  char* pnt;
  
  while(*str){
    long value = strtol(str, &pnt, 10);

    Serial.print("Value: ");
    Serial.println(value);
    Serial.print("Remain: ");
    Serial.println(pnt);
    Serial.print("at: ");
    Serial.println((uint16_t)pnt);
    Serial.print("Next char: 0x");
    Serial.println((uint8_t)pnt[0], HEX);

    if(pnt != str && *pnt){
      Serial.println("Set var!");
      switch (pnt[0]) {
        case 'U':
          skateBatVoltage = value;
        break;
        case 'I': 
          skateCurrent = value;
        break;
        case 'T': 
          temperature = value;
        break;
        case 'S': 
          skateSpeed = value;
        break;
        default:
          //null
          Serial.println("or not.... SKIP!");
        break;
      }
    }
    str = ++pnt;
  }
}

alto777:
NO! So close…

You can't strcat to an unterminated string.

strcat(buff, '\0'); // No!

Also, that would be "strchr", because "strcat" expects two char pointers.
But, as noted, you shouldn't use either on an unterminated buffer.

for (int x = 0; x <= sizeof(information); x++)

I suspect that that is wrong; you're reading data outside information. Without seeing the rest of your code, I can't be sure but you might very well write outside the bounds of buff.

strcpy(buff, '\0');

No idea what it will do but that's also wrong. strcpy takes a variable and a NUL terminated character array as arguments. If you want to clear buff, use one of the two below

buff[0] = '\0';
memset(buff, '\0', sizeof(buff));

septillion:
You can't strcpy() from a char as well (as it's an unterminated string as well). No need to clear the buffer anyway.

My implementation including debug

char buffer[100];

byte bufferIndex = 0;

long skateBatVoltage, skateCurrent, temperature, skateSpeed = 0;

void setup() {
 // put your setup code here, to run once:
 Serial.begin(115200);

}

void loop() {
 if(Serial.available()){
   if(Serial.peek() == '\n'){
     Serial.read();
     buffer[bufferIndex++] = '\0';

Serial.print("Buffer: ");
     Serial.println(buffer);

decodeInformation(buffer);

Serial.print("skateBatVoltage: ");
     Serial.println(skateBatVoltage);
     Serial.print("skateCurrent:  ");
     Serial.println(skateCurrent);
     Serial.print("temperature: ");
     Serial.println(temperature);
     Serial.print("skateSpeed: ");
     Serial.println(skateSpeed);

bufferIndex = 0;
   }
   else{
    buffer[bufferIndex++] = Serial.read();
   }
 }

}

void decodeInformation(char str[]){
 char* pnt;
 
 while(*str){
   long value = strtol(str, &pnt, 10);

Serial.print("Value: ");
   Serial.println(value);
   Serial.print("Remain: ");
   Serial.println(pnt);
   Serial.print("at: ");
   Serial.println((uint16_t)pnt);
   Serial.print("Next char: 0x");
   Serial.println((uint8_t)pnt[0], HEX);

if(pnt != str && *pnt){
     Serial.println("Set var!");
     switch (pnt[0]) {
       case 'U':
         skateBatVoltage = value;
       break;
       case 'I':
         skateCurrent = value;
       break;
       case 'T':
         temperature = value;
       break;
       case 'S':
         skateSpeed = value;
       break;
       default:
         //null
         Serial.println("or not.... SKIP!");
       break;
     }
   }
   str = ++pnt;
 }
}

thank you so much for help :slight_smile: