Modbus writing 16bit Signed (-) values


Thread Starter


Hi, I’m new to the forum and quite new to the Modbus protocol and I'm hoping someone can help me with my Modbus problem.

I am using RS485 to communicate with a generator engine controller. The controller stores a series of event records across several string type registers that contain firstly date, time and event log reason; secondly the state of all inputs/outputs of the engine (this works well and is not the issue).

The issue is:
To acquire this data I must first write to a 16-bit signed register the actual ID of the event record before I can read out the data. The record ID's range from 0 to approx. -1200 depending on the records logged. I have had success writing from 0 to -128 and the correct records are then contained in the appropriate registers but after -128 I have many problems, for example: When trying to write -384 I am actually given record -128 but -385 is ok and gives me the correct record. And again writing -256 give me -256 but -257 gives me -1. I have looked at the binary values etc. and cannot see a problem.

Any help is greatly appreciated!
It sounds like something somewhere is getting 8 bit and 16 bit words confused.

8 bit signed numbers range from -127 to +128
16 bit signed numbers range from -32766 to +32767

If you are familiar with the "2s Compliment" notation you will understand how negative numbers are encoded - i.e. if the MSB is SET then the number is negative.'s_complement

In your case it appears that when you write a value where bit 8 is set (ie the MSB of an 8 bit word) it will appear as a negative integer value. I suspect from your symptoms that you are either writing 8 bit words or your device is expecting 8 bits instead of 16.

Hi Rob,

Thanks for your reply.

Thats wot I thought may have been the problem but for some reason when writing within the range 0 to -256, -385 to -512 etc the correct records are shown, and the values in between show:

-257 to -384 actually show records -1 to - 128

and writing
-513 to -643 again shows -1 to -128?

I can see a pattern but cannot find the cause.

Lynn August Linse

This isn't really a Modbus problem as Modbus literally moves all registers as 'unsigned 16-bit'. Modbus is the delivery truck & doesn't care what's in the package.

The problem is in how your code is packing your signed integer into that unsigned 16-bit word.

Your signed INT is likely 32-bit if a PC or modern embedded system, but perhaps 8-bit if your system is trying to highly minimize data memory usage.

Since a PC is also little-byte first and Modbus is big-byte first, this makes packing a signed int from 'host form' to 'Modbus form' tricky. I can't explain how you accomplish this, but since the most common design is something like:
modbus[0] = (X >> 8) AND 0xFF
modbus[1] = (X AND 0xFF)

Your symptom sounds like your first equation is always resulting in 0xFF. The shift-right (>>) operation may have unexpected consequences on a signed integer in some systems.