TapHome

Modbus data types

Modbus data types in TapHome scripts — Int16, Uint16, Int32, UInt32, Float, Bool, String and the 64-bit Int64, UInt64 and Double — with big-endian, little-endian and byte-swap variants.

The data type is the third argument of MODBUSR, MODBUSW and MODBUSWNE and of UNPACKVALUE and PACKVALUE. It decides how many 16-bit registers a value takes and in which order its bytes are stored. Data type names are not case sensitive.

Base data types

Each base data type takes a fixed number of 16-bit registers and gives the script a value of a fixed type.

TypeRegistersRangeValue in the script
Bool10 = FALSE, anything else TRUEbool
Int161−32 768 … 32 767number
Uint1610 … 65 535number
Int322−2 147 483 648 … 2 147 483 647number
UInt3220 … 4 294 967 295number
Float2IEEE 754 single precisionnumber
Int64, UInt64464-bit whole numbersint64, uint64
Double4IEEE 754 double precisionnumber
String1 – 1232 characters per registerstring

Many devices store a decimal value as a whole number with a fixed scale — divide it after reading, for example MODBUSR(H, 20, Int16) / 10. BCD-coded values are converted with FROMBCD.

Byte order variants

Every type exists in a big-endian and a little-endian variant; the 32- and 64-bit types also in byte-swap variants.

1
2
3
4
5
6
7
8
BigEndianInt16      LittleEndianInt16
BigEndianUint16     LittleEndianUint16
BigEndianInt32      LittleEndianInt32       BigEndianInt32ByteSwap      LittleEndianInt32ByteSwap
BigEndianUint32     LittleEndianUint32      BigEndianUint32ByteSwap     LittleEndianUint32ByteSwap
BigEndianFloat      LittleEndianFloat       BigEndianFloatByteSwap      LittleEndianFloatByteSwap
BigEndianInt64      LittleEndianInt64       BigEndianInt64ByteSwap      LittleEndianInt64ByteSwap
BigEndianUint64     LittleEndianUint64      BigEndianUint64ByteSwap     LittleEndianUint64ByteSwap
BigEndianDouble     LittleEndianDouble      BigEndianDoubleByteSwap     LittleEndianDoubleByteSwap
FlagMeaning for registers
BigEndianThe most significant register comes first. This is the default: Int32 is BigEndianInt32.
LittleEndianThe register order is reversed (word swap). For a 16-bit type, which has one register, the two bytes inside it are swapped.
ByteSwapThe two bytes inside every register are swapped.

Remarks

  • Reads and writes apply all flags the same way, so writing a value and reading it back with the same type gives the same value. On cores older than 2026.1, MODBUSW and MODBUSWNE ignored ByteSwap for Int32 and UInt32.
  • When a value reads as nonsense, try the variants in the manual Modbus operations of the app, which switch the data type over the same registers.
  • In a byte collection the flags mean byte order instead — see Byte order in collections.

Example

MODBUSR(H, 0x0100, LittleEndianFloat);
MODBUSR(A, 30, BigEndianUint32ByteSwap);

64-bit data types

Int64, UInt64 and Double take four registers; Int64 and UInt64 are read as 64-bit whole numbers, exact over the whole range, because a double holds whole numbers exactly only up to 2^53.

Remarks — A 64-bit value keeps all 64 bits in the bit functions, so bits 32 to 63 of an alarm word are reachable.

Example — energy counter in Wh, shown in kWh

VAR energy := MODBUSR(H, 100, UInt64);
energy / 1000;

Errors — Modbus data type ‘X’ not supported. Please update your core unit to be able to use this feature. — when the script is saved for an older core.

Available — Core 2026.1, build 40595 or newer.

String

String reads text stored two characters per register, the high byte first; the number of registers is the fourth argument.

Remarks

  • MODBUSR reads 0 to 123 registers; the text ends at the first zero byte. Each byte is one character.
  • String can only be read. MODBUSW and PACKVALUE do not write it.

Example

MODBUSR(H, 14, String, 4);
# Result: text of up to 8 characters, for example a serial number

Writing values

MODBUSW, MODBUSWNE and PACKVALUE convert the value to the data type before writing.

  • Integer types round to the nearest whole number; a value exactly halfway goes to the even number, so 2.5 is written as 2 and 3.5 as 4.
  • A value outside the range of Int16, Uint16 or Float stops the script: Overflow when writing X as UInt16.
  • NaN can be written only to Float and Double. To an integer type it stops the script: RegisterValueToWrites: Can’t write double.NaN to modbus register (MODBUSW, MODBUSWNE) or PACKVALUE: Can’t write double.NaN to modbus register.
  • Bool writes 1 for any value other than 0. TRUE and FALSE can also be written to number types as 1 and 0.

Example — set point with one decimal place

MODBUSW(H, 20, Int16, ROUND(Te * 10));

See also — Modbus functions, Modbus scripts and prefetch, Binary data.