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??
}* 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;*_
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.
}
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;*_
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;
}
}
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.
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() {}
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.
Figure-1: