Introduction to Modbus
Modbus is a simple communication protocol, often used to integrate HVAC equipment. It uses master-slave communication, when several devices can be connected to the common bus, each must have a unique Slave ID, and the master device always queries the individual slave devices that respond to it.
Master - slave topology
In most cases, TapHome is used in the mode where the Core control unit is Modbus Master, and the connected devices are Modbus Slave. This is set in the Hardware section → Modbus RTU or Modbus TCP. However, it is also possible to use the opposite direction, when TapHome Core provides some other superior system with information about its devices. It is defined in section Expose devices → Modbus RTU or Modbus TCP.
Modbus can communicate through different physical layers:
- via a serial line, typically RS485. This is referred to as Modbus RTU
- over the LAN network via the TCP/IP protocol
- over the LAN network via the UDP protocol - currently not supported by the TapHome system
Modbus defines 4 types of registers:
|Holding Registers||H||Read-write||16-bits||Read: 03, Write multiple: 16 (0x10)|
| - Write Single Holding||SH||Read-write||16-bits||Write single: 06|
|Coil (Discrete Output Coils)||C||Read-write||1-bit||Read: 01, Write multiple: 15 (0xF)|
| - Write Single Coil||SC||Read-write||1-bit||Write single: 05|
|Discrete Input Contacts||D||Read-only||1-bit||Read: 02|
|Analog Input Registers||A||Read-only||16-bits||Read: 04|
The register number is 16 bits, that is, it can have a value from 0 to 65535. Operations can be performed on the registers:
- reading multiple registers
- registration of one register
- registration of several registers
Some Modbus implementations add additional commands: report slave id, bit masking, write and read at once, etc., but these are not supported by TapHome.
Information about what is stored in which register and in what format is part of the equipment documentation provided by the equipment supplier or manufacturer.
An example of Modbus documentation from a Modbus device supplier:
Register type C (Coil), index 58, since it has only 2 values (open / closed) and allows in addition to reading and writing, the appropriate type of TapHome device is Digital output.
Accelerated instructions for integrating a Modbus device into TapHome
- Connect the device to the appropriate bus (for Modbus RTU and ASCII) or to the LAN (for Modbus TCP). For a TCP device, make sure it is on the same network as the TapHome Core controller, for example using Fing (iOS, Android) or IP Scanner (Windows).
- In TapHome → Hardware, add a new Modbus RTU or Modbus TCP interface, and set the communication parameters according to the documentation. For Modbus RTU it is Baud rate, Stop bits, Parity, Data bits, for Modbus TCP it is IP address.
- Find in the Modbus documentation of the device what Slave ID it uses. In the case of Modbus TCP, this is sometimes referred to as Unit ID. If you want to use multiple devices on one bus with Modbus RTU, you must change the Slave ID of each one so that it is unique for the given bus line.
- Communication test - using the Manual operations tool, try to read some information according to the documentation (Modbus table) for the given device. If everything works, you should see a readout.
- If the communication test was successful, create a Module that represents the Modbus device
- Choose which information from the Modbus documentation you want to present in the TapHome system and create the corresponding devices. Start by reading the values (Read script), and in the case of actors, continue by writing (Write script).
- If the basic functions of the device are working, add Error, Warning, or Information definitions to the scripts.
- If necessary, you can also define Service Attributes and Service Actions for TapHome devices and modules
- If everything is tuned and communicating correctly, export the Module to an XML file so you can use it next time. You can also contribute to the community at github.com/taphome-official/modbus_templates
Implementation in TapHome
This documentation is intended for the scenario where the TapHome Core control unit is a Modbus master, and the physical devices that are added to the Hardware → Modbus RTU / TCP section are Modbus slaves.
Hardware → Modbus RTU: devices are connected on some BUS, the basic parameters of RS485 transmission are defined, such as baudrate, parity, stop bits, or whether the data is ASCII or binary. Only devices with the same communication settings can be connected on this bus. Also, correct communication can only work if the A and B cables are connected correctly.
Hardware → Modbus TCP: devices are connected on the same LAN as the Core control unit. One TCP port is defined, which is common to all devices connected to this interface.
An interface can contain one or more modules, which in most cases cover communication with the entire physical device. From a configuration point of view, the Module defines the unique Slave ID of the connected device for Modbus RTU, and additionally the IP address for Modbus TCP.
Represents a specific control element or sensor in the TapHome system. It must always be part of one parent Module.
5 air conditioning units connected on one bus, use a common Modbus RTU interface, which defines the bus port, baudrate, and other communication parameters. The interface contains 5 modules, each of which represents one air conditioning unit with a unique Slave ID. Each module has defined devices under it, such as a thermostat, cooling / heating mode, fan power or tilting of the slats. Individual devices have defined commands for reading and/or writing Modbus values.
- Digital output
- Analog output
- Multi-value switch
- Temperature sensor
- Electric meter
- Status contact
- A variable
Scripts for reading and writing Modbus values
TapHome devices communicate with physical Modbus devices using scripts.
For communication with Modbus devices, scripting sections are defined on them:
- Initialize script: is run when the device starts (e.g. after the control unit is restarted)
- Read script: setting values of global variables or reading error states
- Read Value script: script for reading a specific value (quantity) from a Modbus device (e.g. set temperature on the thermostat or measured temperature on the thermostat)
- Write Value script: write the value to the Modbus device
Functions for communication with Modbus devices
MODBUSR (Modbus Read)
Function for reading register from Modbus. Depending on the data type, it can be 1 register (for 16-bit data types), 2 registers (for 32-bit data types), or more registers (for String data types)
MODBUSR(register_type, register_address, data_type, [OPTIONAL: number_of_characters if data_type=String])
Example: MODBUSR(H, 20, Int16)/100
Read the H register number (or address) 20, and interpret it as a 16-bit Integer (a whole number with a +- sign). Finally, divide this value by the number 100 (shift the decimal point 2 places to the left).
The registry address can also be entered in hexadecimal format, e.g. the value 20 can be written as 0x14.
MODBUSW (Modbus Write)
MODBUSW(register_type, register_address, data_type, value_to_write)
Example: MODBUSW(H, 20, Int16, Te * 100)
In the register H with address 20, write the value of the variable Te multiplied by the number 100 (shifting the decimal point by 2 to the right).
MODBUSWNE (Modbus Write if Not Equal)
The same as MODBUSW with the difference that it reads the value from the register before writing, and writes it only if the written value is different from the read one. The whole operation takes longer, and its typical use is when setting the properties of a Modbus device, where the configuration is written to the EEPROM memory with a limited number of writes.
The functions MODBUSR, MODBUSW and MODBUSWNE can only be used in Modbus scripts. If used in other scripts, they are considered an error.
Modbus data types
The contents of the registers are defined in the modbus table. Since the size of one Modbus register is 16 bits, 16-bit Int16 or UInt16 values are most often used, and decimal places are counted down by divisions of 10 or 100. But some Modbus devices also use 16-bit registers with floating-point numbers (Float), or they have a changed bit order (big endian, little endian), they write one number in two registers (32 bit variations). Sometimes the easiest way to find out the correct data type is to use the utility directly in the TapHome application (Manual Operations), where you can load 1 or more registers and dynamically switch the data type.
Update and Poll Interval
Each device in the Modbus interface has a defined Poll Interval attribute. This determines how often the TapHome control unit should poll for new Modbus device values. Modbus communication is of the Master-Slave type, and thus information from the Modbus device can reach TapHome only when TapHome requests it.
The longer the Poll Interval, the later the value in TapHome is refreshed. Too short a Poll Interval may mean that TapHome will be unnecessarily burdened by obtaining unnecessary values, and may not have time to serve all devices within the given time interval. For example, with Modbus RTU and lower Baud Rate speeds, e.g. 9600, one query / response can take tens of ms. For thermometers, in most cases, an interval of 15000ms (15s) is sufficient, for buttons, on the contrary, as little as possible, e.g. 50 ms.
Some Modbus devices expect the master to periodically write the current value to the register. This is what the Periodic Write attribute is for.
Definition of error states from scripts
In some scripts it is possible to define an error / warning / information on the device, based on the information read from the device's Modbus registers. These messages are displayed in TapHome in the same way as internal TapHome error messages. Optionally, a numeric error code can be added to the error message if practical for servicing the Modbus device.
Only one error message with no code or only one error message per error code can be defined on the device.
ADDERROR(), ADDWARING(), ADDINFO()
ADDERROR([Optional: custom_code], text)
Example: in the Read Script section of the Analog Output device there is a code:
ADDERROR("Error without code");
ADDWARNING("Warning without code");
ADDINFO("Info without code");
ADDERROR(1, "Error with code");
ADDWARNING(1, "Warning with code");
ADDINFO(1,"Info with code");
...which is reflected on the device by messages:
Service attributes and actions
In addition to a value (or multiple values, such as a Thermostat) from a connected Modbus device, TapHome modules and devices can also read service attributes or perform service actions. These are then not accessible on the desktop for other users of the system, but serve only for more detailed information about the Modbus device, without unnecessarily overloading the system with a large number of variables and actions.
Service attributes are displayed in the service settings of the TapHome module or device. Typically, they are used to display information about the device, such as Model, Serial Number, Firmware Version, Hardware Version, Time since last reboot, etc. This is useful information from the point of view of servicing a Modbus device, but it does not make sense to create separate TapHome devices for them.
Service actions are displayed in the service settings of the TapHome module or device, at the very bottom as buttons. When pressed, they perform a preset Modbus action that writes the required information to the register. Example of use: Setting or changing the Slave ID, Replacing the filter, Setting the counter to the required value, Resetting the device and the like.