Modbus server bit access
The following method is a recommended approach for accessing each bit individually and maintaining a readable program.
Date created: July 3rd, 2019
CB3 Software version: 3.1.17779 and above
e-Series Software version: 5.0 and above
Note that older or newer software versions may behave differently.
Binary signals using the Modbus TCP server
Universal Robots’ Modbus TCP server provides 128 general purpose 16-bit registers (addresses 128-255). Up to 16 on/off or other binary signals can be consolidated in a single register instead of using a different address for each. The following method is a recommended approach for accessing each bit individually and maintaining a readable program.
Overview
This guide explains how to use the following URScript commands to 1) read an integer from a server register, 2) convert it to an easily modifiable list, 3) converted the modified value back to an integer, and 4) write the modified value to a server register. This process allows you to treat each bit as an individual on/off signal.
read_port_register(<address>)
write_port_register(<address>, <value>)
integer_to_binary_list(<integer>)
binary_list_to_integer(<list>)
This guide also introduces sample user-defined URScript functions to facilitate the use of the above commands. A complete description of these commands and user-defined functions can be found in the URScript Manual.
- Reading values from the Modbus TCP server registers
Modbus TCP server registers can be read from a program using the URScript command read_port_register(<address>). This command will return an integer value between 0 – 65535.
This integer value can be modified directly by adding or subtracting other integers but this method is prone to mistakes and code written this way is difficult to read. For example, which bits are affected when adding an integer changes depending on the current status of those bits:
33 (0b0010 0001) + 8 (0b0000 1000) = 41 (0b0010 1001)
The fourth bit is modified. Adding eight again:
41 (0b0010 1001) + 8 (0b0000 1000) = 49 (0b0011 0001)
The fourth and fifth bit are changed.
- Converting integer values to binary lists
If the goal is to treat each bit in the 16-bit register as an individual on/off (binary) signal and only change one bit at a time, this is best accomplished by converting the integer value to a binary list. This can be done using the URScript command integer_to_binary_list(<integer>). This command returns a list of True and False values.
sample_list = integer_to_binary_list(725) = [True, False, True, False, True, False, True, True, False, True, False, False, False, False, False, False]
This list is the equivalent of the binary value 0b0000 0010 1101 0101 except the list uses little-endian notation, meaning the value of the first element is the least significant bit.
Each element of the list can be accessed or modified using standard list bracket [ ] notation. Because lists use zero-indexing, the first element is accessed as sample_list[0] and the third by sample_list[2]. Using a list allows us to accurately read or set a single bit regardless of the current value of entire register.
sample_list = integer_to_binary_list(725)
sample_list[3] = True
- Converting a list back to an integer value
Because sample_int and sample_list are program variables, manipulating them in our program does not change the value of the Modbus TCP server register. Before the register can be updated with the modified value, the list must be converted back to an integer value. This can be done using the URScript command binary_list_to_integer(<list>).
After modifying sample_list[3] as above, converting it to an integer returns the value 733.
modified_int = binary_list_to_integer(sample_list) = 733
- Writing to Modbus TCP server registers
The converted value can be written to the Modbus TCP server register using the command write_port_register(<address>, <value>). This function does not return any value. Calling write_port_register(128, modified_int) will set the value 733 in register address 128.
User defined URScript functions to simplify the process
User-defined URScript functions allow a user to perform the above multi-step process easily with a single function call. The attached ModbusServer_BitAccess.script provides three functions that read, set, or change the specified bit of the specified register.
Programming best practices
In order to easily remember which register contains which signals and which bit corresponds to which signal, it is better to use variables than numbers. Variable names provide a readable label for each signal. For example, using the user-defined functions described above:
set_register_bit(128, 0, True)
This provides the programmer with less information than:
valve_register = 128
valve_isOpen = 0
set_register_bit(valve_register, valve_isOpen, True)
See the attached program file, ModbusRegister_BitAccess_sample.urp, for how this can be done in a program.