union bytes to float

Hello, how my code works is as follows. First you type a message in the serial monitor an example would be: 01 12 D4 00 00 A4 70 45 41 A4 70 45 41 A4 70 45 41 A4 70 04 C7. (you can only typ in hex).
This will be put in an array (i got that part working). then I want to print A4 70 45 41 A4 70 45 41 A4 70 45 41 A4 70 in floats. below you could see that I tried to use a union but when I typ this in my serial monitor I only see 0.00, 160.20, 0.00, 0.00, 0.00, 0.00.
Ontvangen() is the function i worte to put the string into an array and give it hex values.
Omgerekend[] is the array it returns. I hope someone can explain to me what I am doing wrong??

char r = 6;
float opslag[5][9];
int nummer = 0;

union TEMPO
{
float f;
byte z[4];
}x;

TEMPO a[9];

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

void loop()
{
cases();
}

//01 12 D4 00 00 A4 70 45 41 A4 70 45 41 A4 70 45 41 A4 70 04 C7

void cases()
{

case 1:
ontvangen();
if ((Omgerekend[0] == SoC) && (Omgerekend[1] == 0x29) && (Omgerekend[2] = FC06b) && (Omgerekend[4] == sourceID_CO) && (Omgerekend[5] == 0x37))
// 01 29 D4 A4 5B 37 A4 70 45 41 A4 70 45 41 A4 70 45 41 A4 70 04 C7
{
//recieve 4 bytes, change to floats
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < .4; j++)
{
a*.z[j] = Omgerekend[r];*

  • }*
    opslag[nummer] = a*.f;*
    _ Serial.println(opslag[nummer]);
    * if (r >= 19)
    {
    r = 6;
    }
    r++;
    }
    nummer++;
    state = 1;
    }
    //vervolgens ACK sturen als alles goed is aangekomen.
    break;*_

* }*
}

Code tags, please

Please edit your post to add code tags, and remove the excessive blank lines.

char r = 6; // selfmade pointer to scroll through the message array from a certain point.
float opslag[5][9]; // float array to save the float values but also to save multiple readings.
int nummer = 0; // selfmade pointer to scroll through the 2D array.

union TEMPO // union to convert bytes to floats.
{
float f;
byte z[4];
}x;

TEMPO a[9]; //2D array.

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

void loop()
{
cases(); // function for the cases.
}

// the message: 01 12 D4 00 00 A4 70 45 41 A4 70 45 41 A4 70 45 41 A4 70 04 C7.

void cases(){

case 1:
ontvangen(); // function to put the message in an array.
if ((Omgerekend[0] == SoC) && (Omgerekend[1] == 0x29) && (Omgerekend[2] = FC06b) &&
(Omgerekend[4] == sourceID_CO) && (Omgerekend[5] == 0x37)){ // checking if the message is for me.
for (int i = 0; i < 10; i++){ //recieve 4 bytes, change to floats.
for (int j = 0; j < .4; j++){
a*.z[j] = Omgerekend[r]; // attempt to write the bytes in the array.*

  • }*
    opslag[nummer] = a*.f; //trying to change the bytes to floats.*
    _ Serial.println(opslag[nummer]); // printing the value of the first batch.
    * if (r >= 19) // making the selfmade pointer start from the beginning point.
    {
    r = 6;
    }
    r++;
    }
    nummer++; // scrolling through the 2D array.
    state = 1; // looping through the same function to test it.
    }
    break;*_

* }*
}

Code tags.
Now.

char r = 6;   // selfmade pointer to scroll through the message array from a certain point.
float opslag[5][9]; // float array to save the float values but also to save multiple readings.
int nummer = 0;   // selfmade pointer to scroll through the 2D array.

union TEMPO      // union to convert bytes to floats.
{
  float f;
  byte z[4];
}x;

TEMPO a[9]; //2D array. 

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

void loop()
{
  cases();  // function for the cases.
}
// the message: 01 12 D4 00 00 A4 70 45 41 A4 70 45 41 A4 70 45 41 A4 70 04 C7.

void cases(){

 case 1:
 ontvangen(); // function to put the message in an array. 
 if ((Omgerekend[0] == SoC) && (Omgerekend[1] ==  0x29) && (Omgerekend[2] = FC06b) && 
 (Omgerekend[4] == sourceID_CO) && (Omgerekend[5] == 0x37)){ // checking if the message is for me.
        for (int i = 0; i < 10; i++){ //recieve 4 bytes, change to floats.
          for (int j = 0; j < .4; j++){
          a[i].z[j] = Omgerekend[r]; // attempt to write the bytes in the array.
         
          }
          opslag[nummer][i] = a[i].f;   //trying to change the bytes to floats.
          Serial.println(opslag[nummer][i]); // printing the value of the first batch.
          if (r >= 19) // making the selfmade pointer start from the beginning point.
          {
            r = 6;
          }
          r++;
        }
        nummer++; // scrolling through the 2D array.
        state = 1;    // looping through the same function to test it. 
      }
      break;
  }
}

I didn't know what you meant but i fixed it now.

A case without a switch?

char r = 6;   // selfmade pointer to scroll through the message array from a certain point.
float opslag[5][9]; // float array to save the float values but also to save multiple readings.
int nummer = 0;   // selfmade pointer to scroll through the 2D array.

union TEMPO      // union to convert bytes to floats.
{
  float f;
  byte z[4];
}x;

TEMPO a[9]; //2D array.

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

void loop()
{
  cases();  // function for the cases.
}
// the message: 01 12 D4 00 00 A4 70 45 41 A4 70 45 41 A4 70 45 41 A4 70 04 C7.

void cases(){
 switch (state){

    case 0:
      ontvangen();
      if ((Omgerekend[0] == SoC) && (Omgerekend[2] == FC06a) && (Omgerekend[4] == sourceID_CO)){// && lRC check 01 A4 D7 A4 5B
      

 case 1:
 ontvangen(); // function to put the message in an array.
 if ((Omgerekend[0] == SoC) && (Omgerekend[1] ==  0x29) && (Omgerekend[2] = FC06b) &&
 (Omgerekend[4] == sourceID_CO) && (Omgerekend[5] == 0x37)){ // checking if the message is for me.
        for (int i = 0; i < 10; i++){ //recieve 4 bytes, change to floats.
          for (int j = 0; j < .4; j++){
          a[i].z[j] = Omgerekend[r]; // attempt to write the bytes in the array.
        
          }
          opslag[nummer][i] = a[i].f;   //trying to change the bytes to floats.
          Serial.println(opslag[nummer][i]); // printing the value of the first batch.
          if (r >= 19) // making the selfmade pointer start from the beginning point.
          {
            r = 6;
          }
          r++;
        }
        nummer++; // scrolling through the 2D array.
        state = 1;    // looping through the same function to test it.
      }
      break;
  }
}

My code is too long so i only posted the important parts.
I apologize for the missing parts.

My code is too long so i only posted the important parts.
I apologize for the missing parts.

The best thing to do in this case is to write a small piece of example code which compiles, runs, and demonstrates your issue.

Quite often you will find the root cause by yourself when breaking the problem down into a smaller isolated piece.

what's FC06a in && (Omgerekend[2] == FC06a)is that supposed to be Hexadecimal ? or you have a constant by that name somewhere ? and is the array Omgerekend a global variable?

if you look at the 4 bytes A4 70 45 41:

  • if the data is represented in little endian, the LSB comes first, so you have the number 0x414570A4 which is 12.3400001526 in IEEE float
  • if the data is represented in big endian, the MSB comes first, so you have the number 0xA4704541 which is -5.21003646196e-17 in IEEE float

the second one looks weird so I'll assume you are getting little endian formatted data dump.

reading that on Arduino is not difficult (since it's using little endian too) once you have the bytes corresponding to your ASCII values in an array, it's just a matter finding the pointer to the start of the data and casting that pointer to a (float*) to tell the compiler what you want to extract

here is a quick example

uint8_t Omgerekend[] = {
  0x01, 0x12, 0xD4, 0x00, 0x00, // content we don't care about
  0xA4, 0x70, 0x45, 0x41, // first float starts at index 5
  0xA4, 0x70, 0x45, 0x41, // second float (4 bytes further)
  0xA4, 0x70, 0x45, 0x41, // third float (4 bytes further)
  0xA4, 0x70, 0x04, 0xC7  // fourth float (4 bytes further)
};

const uint8_t firstFloatIndex = 5;
float myFloat[4];

void setup() {
  Serial.begin(115200);
  for (uint8_t i = 0; i < 4; i++) {
    myFloat[i] = *((float*) &(Omgerekend[firstFloatIndex+4*i]));
    Serial.print(F("Float #")); Serial.print(i); Serial.print(F("\t"));Serial.println(myFloat[i],6);
  }
}

void loop() {}

Serial Monitor (@ 115200 bauds) will show

[color=purple]
Float #0	12.340001
Float #1	12.340001
Float #2	12.340001
Float #3	-33904.640625
[/color]

J-M-L:

  • if the data is represented in big endian, the MSB comes first, so you have the number 0xA4704541 which is -5.21003646196e-17 in IEEE float

1. How have you got it (-5.21003646196e-17) -- using manual method or using Arduino?

2. Using UNO and float, I get this (23 digit precision and 6 digit accuracy): -0.00000000000000005210036 (-5.210036e-17).

3. Using DUE and float, I get same as Step-2.

On Line converter, did not explore further as this was not the point
-5.21004e-17 Is fine

Many things are irrelevant in life; but, human curiosity/query?

I’m all in favor of intellectual curiosity but digressions in answers are generally bringing confusion. There is ample literature on IEEE float representation.

My point was just to say there could be two ways to read the 4 bytes (endianness) and if they are organized in a way that is compatible with little endian then reading them is a simple cast.

I felt 12.3 was more likely something OP was dealing with and thus offered an answer. If OP were to come back stating data is big endian then I’ll advise to swap the byte when building up the array.

I have applied the use of an union to change bytes into floats. But i encounterd another one.....
When I type the following code in the Serial monitor:
01 29 D4 A4 5B 37 00 B5 78 60 41 A4 70 45 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 C5 78 60 41 04 C7.
It won't print the last 2 hex values (04 and C7).

This is my code to read the values as a string and convert it to hex

'
const byte numChar = 140;
unsigned char omgezetbericht[numChar];
unsigned char bericht[numChar];
unsigned char Omgerekend[numChar];

void ontvangen()
{
for (char f = 0; f <= 49; f++)
  {
    bericht[f] = 0;
    omgezetbericht[f] = 0;
    Omgerekend[f] = 0;
  }
  char a = 0;
  while (!Serial.available());
  String ingevoerdbericht = Serial.readString();
  ingevoerdbericht.toCharArray(bericht, ingevoerdbericht.length()); //invoer naar een char array omzetten
  Serial.println(ingevoerdbericht);

  for (char i = 0; i <= sizeof(bericht); i++)
  {
    if ((bericht[i] >= 65) && (bericht[i] <= 70))
    {
      omgezetbericht[a] = bericht[i] - 55;
      a++;
    }
    else if ((bericht[i] >= 97) && (bericht[i] <= 102))
    {
      omgezetbericht[a] = bericht[i] - 87;
      a++;
    }
    else if ((bericht[i] >= 48) && (bericht[i] <= 57))
    {
      omgezetbericht[a] = bericht[i] - 48;
      a++;
    }
    else if (bericht[i] == 32);
  }
  unsigned char temp = 0;
  char k = 0;
  for (char j = 0; j <= sizeof(omgezetbericht); j++)
  {
    if (j % 2 == 0)
    {
      temp = omgezetbericht[j] * 16;
    }
    else
    {
      Omgerekend[k] = omgezetbericht[j] + temp;
      k++;
    }
  }
  Serial.println("Code zonder spaties en in char array:");
  for (char h = 0; h <= sizeof(Omgerekend); h++)
  {
    Serial.println(Omgerekend[h], HEX);
  }
  Serial.println();
  return Omgerekend;
}

when I put the function ontvangen() in the loop and write:
01 29 D4 A4 5B 37 00 B5 78 60 41 A4 70 45 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 C5 78 60 41 04 C7 in the serial monitor.
it will show me:
01 29 D4 A4 5B 37 00 B5 78 60 41 A4 70 45 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 C5 78 60 41. without the spaces, but I am missing the 04 and C7.

How do I fix this or does anyone know why it doesn't print everything?

  String ingevoerdbericht = Serial.readString(); is a poor way of reading what's coming.

there is also no point duplicating the memory buffer with   ingevoerdbericht.toCharArray(bericht, ingevoerdbericht.length()); //invoer naar een char array omzetten, you can iterate over each char of ingevoerdbericht by either accessing the underlying cString (c_str() method) or just each character as an array or with charAt()

you would want to read until a CR/LF for example, a end marker => I would suggest to study Serial Input Basics to handle this

dalawey:
I have applied the use of an union to change bytes into floats. But i encounterd another one.....
When I type the following code in the Serial monitor:
01 29 D4 A4 5B 37 00 B5 78 60 41 A4 70 45 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 B5 78 60 41 C5 78 60 41 04 C7.
It won't print the last 2 hex values (04 and C7).

I can print/show all the data bytes on the OutputBox (Fig-1) of Serial Monitor, which are coming from the InputBox of Serial Monitor.
sm2z.png
Figure-1:

sm2z.png

this is what i receive without spaces.

snip2.PNG