Skip to main content

Modbus data conversion to different data types

Recently I was writing code to read Int64 numbers from Modbus devices in dotnet C#. The data coming from Modbus was all in array of bytes. But how to decode it and transform that to some meaningful numbers? 


That's how a sample response from Modbus looks like

00000714467200640000000000000

The data reading of Float value is 400.5

and another one

0000011148000005761020000000000000,

this time it's Int64 value 347238

The architecture was built on top of Azure IoT and I wanted to have it as an Edge Module. However at the end it was nothing more than a piece of c# code inside of the framework. I started with iot-edge-modbus, and that was a good beginning. It was able to decode the message and read the UInt16 values.

Le't quickly decompose the sample message

0000011148000005761020000000

First few bytes are addresses, etc - more on that here. We are interested values starting at 9th byte which is in this example value 8 - this information of how many bytes the data itself has. In Modbus message you may have multiple numbers. So here we have 8 for Int64, however it may be i.e. 16 then it would contain two Int64 values each of 8 bytes.

Then starting at 10th byte we have the actual data and then 8 bytes that would be that part

00000576102

Ok so how to make an Int64 number out of it which we know already is 347238?

Let's first read them into variables to make it easier.

00000576102
b1 b2 b3 b4 b5 b6 b7 b8

And then as simple as that in C#. Note the reverse order of bytes.

BitConverter.ToInt64(new byte[] { b8b7b6b5b4b3b2b1 }, 0);

If you have other types like UInt16, UInt32, UInt64, Int16, Int32, Float and also IEEE Float then the functions are here. Naturally other types will use different number of bytes. 

BitConverter.ToInt16(new byte[] { b2b1 }, 0);
BitConverter.ToUInt16(new byte[] { b2b1 }, 0);
BitConverter.ToSingle(new byte[] { b4b3b2b1 }, 0); // Float
BitConverter.ToSingle(new byte[] { b2b1b4b3 }, 0); // Float IEEE
BitConverter.ToInt32(new byte[] { b4b3b2b1 }, 0);
BitConverter.ToUInt32(new byte[] { b4b3b2b1 }, 0);
BitConverter.ToInt64(new byte[] { b8b7b6b5b4b3b2b1 }, 0);
BitConverter.ToUInt64(new byte[] { b8b7b6b5b4b3b2b1 }, 0);nd then as simple as that. Note the reverse order of bytes.

Comments