macieju
December 13, 2021, 5:19pm
1
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
Next hint: AVR-based Arduinos are little Endian.
macieju
December 13, 2021, 6:43pm
5
sorry i have esp32 and this is a little endian
That is all you need to know to solve the problem.
macieju
December 13, 2021, 6:58pm
7
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?
macieju
December 13, 2021, 7:03pm
9
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.
macieju
December 13, 2021, 7:41pm
11
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() {}
macieju
December 13, 2021, 8:06pm
13
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.
macieju
December 13, 2021, 8:17pm
15
this is also a solution , thanks...
macieju
December 16, 2021, 6:52pm
16
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.
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); …
macieju
December 16, 2021, 7:20pm
19
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.