Maximum 16-Bit Unsigned Value is 32767

Hi, I am currently trying to setup warning flags using values with values 0 - 65535 to be displayed on a grid (so that I can display up to 16 different errors for multiple systems using the bin values).

The idea being there is a unique value displayed between 0 and 65535 per system (per row on grid) which would represent a unique combination of errors per system.

I currently have 16 bit unsigned values being received over CAN however it appears there is a clear limitation in value at 32767 (the maximum for a 16-bit signed integer).

For example, when FF FF is sent over CAN, 65535 should be displayed, however the value displayed is only 32767 - even when the CAN input object is specified to be an unsigned value (photo attached for clarity).

This leads me to think any value being displayed is treated as a signed integer.

I have also tried creating a number and using the CAN bytes separately and maniupulating the value to create the 16-Bit value again (b0 + (256*b1) ). This also unfortunately failed and 32767 was still displayed. I’ve also played around with the Quantity and Unit just in case this limited the possible values. Similarly, I have tried bit extraction and using a custom data format rather than 16-bit, again with no luck.

Does anyone have any experience or ideas on how to solve this?

Thanks in advance.

Hi,

Assuming you have an ADU, the following solution applies to you. It is likely possible on a PMU as well, but the setup is a bit more complicated.

You have hit a known limitation. Unfortunately, the manual contains incorrect information regarding this, but we will fix it. When using a CANBus input, even if you set the data format to a 16-bit unsigned value, the value gets limited to the 0 - 32767 range. This happens because the system treats them internally as signed 16-bit integers.

The best workaround for this is to assign your incoming CAN data directly to a 32-bit channel. ADU has few special channels: adu.userX. You can do this using the “channel override” option in the CANbus input window. Since it is a 32-bit variable, it can easily store your 65535 value as a standard positive integer without cutting it off.

Once your value is stored in adu.userX, you can extract individual bits by using the Number element in the Project Tree.

You can use a simple math formula to isolate any bit ‘n’ = (Value / 2^n) mod 2.

Depending on the operation, the maximum constant value you can enter in the ADU/PMU client is limited (for example, up to +16383 for certain fields). This means you cannot directly enter larger divisors like 16384 (for Bit 14) or 32768 (for Bit 15). To deal with this limit, you can just split the division into two steps. For example, you can divide by 256 (which acts as an 8-bit shift) and then divide by the remaining power of 2.

Here are 6 examples of how to set up your Number elements to extract specific bits using this safe method:

1.Extracting Bit 0 (LSB).

value =
adu.userX * 1
mod 2

2.Extracting Bit 3.
value =
adu.userX * 1
/ 8
mod 2

3.Extracting Bit 7.

value =
adu.userX * 1
/ 128
mod 2

4.Extracting Bit 11.

value =
adu.userX * 1
/ 2048
mod 2

5.Extracting Bit 14. The divisor is 2^14 = 16384. We split this into 256 and 64.

value =
adu.userX * 1
/ 256
/ 64
mod 2

6.Extracting Bit 15 (MSB of a 16-bit value). The divisor is 2^15 = 32768. We split this into 256 and 128.

value =
adu.userX * 1
/ 256
/ 128
mod 2

Thank you very much for your reply and a working solution! I’ll override the existing channel then that allows for the required values.