Modbus rtu frame hex to float convert

Hi, I present my code below.
I can send a request and get an response (modbus RTU frame) from the device (flow meter) but I cannot convert hex to float. Otherwise everything works fine and the way I want it. Does anyone know how to improve it in a simple way?

#define RXD2 18
#define TXD2 19

byte ByteArray[250];
int ByteData[30];

const char msg_reguest[] = {0x01, 0x04, 0x00, 0x08, 0x00, 0x02, 0xf0, 0x09};

void setup() {

  Serial.begin(115200);
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); 

}
void loop() {
  
 delay(200);
 int i;
 int len=8; 

Serial.println("WYSŁANA RAMKA");
for(i = 0 ; i < len ; i++){
      Serial2.write(msg_reguest[i]); 
      Serial.print("[");
      Serial.print(i);
      Serial.print("]");
      Serial.print("="); 
      Serial.print("Ox");
      Serial.print(String(msg_reguest[i], HEX));      
      Serial.print(" ");
 }
 len = 0;
 Serial.println();
 Serial.println();

int a = 0;
 while(Serial2.available()) 
 {
 ByteArray[a] = Serial2.read();
 a++;
 }

 int b = 0;
 String registros;
    Serial.println("ODEBRANA RAMKA");
    for(b = 3 ; b < a-2 ; b++){      

      registros =String(ByteArray[b], HEX);   
      Serial.print(registros);
      Serial.print(" "); 
      }
       Serial.println();
       Serial.println();
        
Serial.println(ByteArray[3],DEC);
Serial.println(ByteArray[4],DEC);
Serial.println(ByteArray[5],DEC);
Serial.println(ByteArray[6],DEC);

Serial.println();
Serial.println();

const byte hexArray[] = "registros";
  float value;
  memcpy(&value, hexArray, sizeof(hexArray));
  Serial.println(value);

delay(3000);
}

"hex" is a human readable representation of a binary number.

There are two ways of converting the four binary bytes that make up a 32 bit float, which depends on whether the number is stored as little or big endian. Which is it?

Hint: How Real (Floating Point) and 32-bit Data is Encoded in Modbus RTU Messages - Chipkin Automation Systems

Big Endian

Next hint: AVR-based Arduinos are little Endian.

sorry i have esp32 and this is a little endian

That is all you need to know to solve the problem.

I'm sorry, but I was wrong, there is a problem with this part of the code:

int b = 0;
 String registros;
    Serial.println("ODEBRANA RAMKA");
    for(b = 3 ; b < a-2 ; b++){      

      registros =String(ByteArray[b], HEX);   
      Serial.print(registros);
      Serial.print(" "); 
      }
       Serial.println();
       Serial.println();
        
Serial.println(ByteArray[3],DEC);
Serial.println(ByteArray[4],DEC);
Serial.println(ByteArray[5],DEC);
Serial.println(ByteArray[6],DEC);

const byte hexArray[] = "registros";
  float value;
  memcpy(&value, hexArray, sizeof(hexArray));
  Serial.println(value);

the point is that I am receiving and displaying the correct data frame but I cannot display this number in float

Do you actually expect that the ASCII characters in hexArray[] have anything to do with a float value?

i also tried this:

const char modbus_data[] = {"registros"};
    union {
        uint32_t i;
        float f;
    } data;
    data.i = strtoul(modbus_data, NULL, 16);
    Serial.println(data.f, 2);

What you need to do is to get the four binary Modbus bytes that make up the Modbus 32 bit float value, and copy them in reversed order to make up a little Endian 32 bit float on the MCU.

Please spend some time reading the documentation linked in reply #2 until you understand this point.

would you be so good to give some example?

Example of a straight copy of four little Endian bytes to little Endian float variable. For Modbus, reverse the byte order.

void setup() {
  
  char buf[4] = {0x9A, 0x99, 0x99, 0x3F};  //4 binary values, represented in hex notation
  float data = 0.0;  // a floating point number

  Serial.begin(9600);
  Serial.println();
  Serial.println("convert bytes to float");
  Serial.println(data); //print float value (intially zero)
  memcpy((char *)&data, buf, 4); //copy 4 bytes in buf into data variable);
  Serial.print(data);  //print new float value
}
void loop() {}

Thanks for the answer,
but how would it be if I have esp32 and TTL rs485, and each time I read the frame with different data and that they would be automatically converted to float?

You have to write that program.

If you want someone to write it for you, post on the Jobs and Paid Consultancy forum section.

this is also a solution , thanks...

Hi,
Could someone give me some hints for a script that will convert integer modbus rtu response to floating point? I will be extremely grateful ...

IS there something special about a modbus rtu integer that simply moving it to a float variable will not work?
Paul

This is most likely just a repost of the OP's earlier thread.

I'm sorry but I got it wrong, I did this:

while(Serial2.available()) 
 {
 ByteArray[a] = Serial2.read();
 a++;
 }
 int b = 0;
 String registros;
    for(b = 0 ; b < a ; b++){      
      registros =(ByteArray[b], HEX);   
      Serial.print(registros);
      }
       Serial.println();
       Serial.println();

byte bit5= ByteArray[5];
byte bit6= ByteArray[6];
byte bit3= ByteArray[3];
byte bit4= ByteArray[4];

unsigned long licznik= 0;
long x5 = (long)bit5<<24; 
long x6 = (long)bit6<<16;
long x3 = (long)bit3<<8;
long x4 = (long)bit4;
licznik = x5 | x6 | x3 | x4;

Serial.println(licznik);
Serial.println();  
Serial.println(licznik,HEX);
Serial.println();
  
const char modbus_data[] = "licznik";
    union {
        uint32_t i;
        float f;
    } data;
    data.i = strtoul(modbus_data, NULL, 16);
Serial.println(data.f, 2);

does not work, I do not know where I made a mistake?

"Does not work" tells us nothing. Please read and follow the directions in the "How to get the best out of this forum" post.

You are probably still confused about endian conventions.