bertmelis / esp32ModbusRTU

modbus RTU client for ESP32
MIT License
70 stars 44 forks source link

Type casting of Data response #8

Open AkhileshThorat opened 4 years ago

AkhileshThorat commented 4 years ago

Hi Bert,

Is there any method to extract data from response and convert it to other data types? There aren't any examples /methods on this. Tried typecasting but data gets changed and overflows sometimes. Can you please explain with a example ?

bertmelis commented 4 years ago

On data you get a pointer to a byte array with the length: uint8_t* data and size_t length. You can cast this to whatever you want but you don't want to cast 2 byte data to a 4 byte type.

If you look carefully, the example casts the data to a float pointer (which get dereferenced to print):

Serial.printf("\nval: %.2f", *reinterpret_cast<float*>(data));

Beware: this is only possible because in this case I know I get 4 bytes of data which are convertible to a float (as specified in the SMA's docs).

AkhileshThorat commented 4 years ago

On data you get a pointer to a byte array with the length: uint8_t* data and size_t length. You can cast this to whatever you want but you don't want to cast 2 byte data to a 4 byte type.

Exactly , I'm not getting expected values(except for float data type). Here I'm trying to read a word(16 bit unsigned integer) from a Input register, but having bad luck. I was thinking if we can copy the response data(2*no of registers) into a array/variable then convert it to whichever data type we wish for. This way we can generalize the data conversion for ( uint16_t, uint32_t, int16_t,int32_t and so on).

bertmelis commented 4 years ago

Several things come to mind (endianess, memory structure...)

Yu have to read your modbus device's manual and see how the data is returned. From then on you can build your code. That's not something I can do for you.

why don't you print the raw data you receive:

Serial.print("Data: 0x");
for (size_t i = 0; i < length; ++i) {
  Serial.printf("%02x", data[i]);
}
Serial.print("\n");

Mind that onData returns the number of bytes, and not the number of words/registers/...

AkhileshThorat commented 4 years ago

I think we miss communicated here , I know how data is received and what data type it is. I'm aware of response type. My idea was to add a parameter in onData() function which will mention data type as well as endianess.

Maybe I'll pull request once I'm done with parsing data with all data types. then I'll be in a better position to explain you :)

bertmelis commented 4 years ago

How would the lib know the endianess or the data format? It is modbus slave specific and not part of this lib. It is also not mentioned in the modbus specification.

bertmelis commented 4 years ago

I have another idea: we try to create a inherited class with esp32ModbusRTU as base class. The inherited class can add the desired functionality.

What is the device you are trying to communicate to?

AkhileshThorat commented 4 years ago

It's true that specification doesn't mention endianess or byte ordering. This differs from slave to slave But when added , it is expected to handle/arrange the incoming bytes beforehand.

Have a look https://www.modbustools.com/poll_display_formats.html

The user will define the data type based on his slave machine let's say modbus.readInputRegisters(server_add,reg_add, no_of_reg, data_type/byte_ordering); example: modbus.readInputRegisters(0x01,100, 1,F_ABCD );

these data types can be included in library

F_ABCD = 32 Bit signed Big-endian
F_CDAB = 32 Bit signed Little-endian
F_BADC = 32 Bit signed Big-endian byte swap
F_DCBA = 32 Bit signed Little-endian byte swap

and many more ...

Planning to add these defines in library with some modifications in the ondata() handle for multiple read and write function.

AkhileshThorat commented 4 years ago

What is the device you are trying to communicate to?

Initially it was a energy meter which had 32-bit float format. Here code worked fined and data was handled properly.

Then I jumped to Simply Modbus Slave simulator and started tinkering with all possible data types along with byte ordering.

Screenshot (32)

Kind of trying to create test cases for multiple function codes/ different data types for testing!! below is a snap of the setup

Screenshot (31)