ModbusTCPServer
ModbusTCPServer implements the Modbus TCP server. ModbusTCPServer support function codes 1 (Read Coils), 2 (Read Discrete Inputs), 3 (Read Holding Registers), 4 (Read Input Registers), 5 (Write Single Coil), 6 (Write Single Holding Register), 15 (Write Multiple Coils), and 16 (Write Multiple Holding Registers).
UiFlow2 Example
CoreS3 TCP Server
Open the cores3_tcp_server_example.m5f2 project in UiFlow2.
This example demonstrates how to use ModbusTCPServer to implement a Modbus TCP server.
UiFlow2 Code Block:
Example output:
None
MicroPython Example
CoreS3 TCP Server
This example demonstrates how to use ModbusTCPServer to implement a Modbus TCP server.
MicroPython Code Block:
1# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD 2# 3# SPDX-License-Identifier: MIT 4import os, sys, io 5import M5 6from M5 import * 7import modbus 8import network 9 10 11label0 = None 12label1 = None 13label3 = None 14label2 = None 15wlan_sta = None 16modbustcpserver_0 = None 17 18 19starting_register4 = None 20slave_list4 = None 21starting_register1 = None 22slave_list1 = None 23starting_register2 = None 24slave_list2 = None 25register2 = None 26slave_value2 = None 27starting_register3 = None 28slave_list3 = None 29starting_register6 = None 30slave_list6 = None 31register1 = None 32slave_value1 = None 33starting_register5 = None 34slave_list5 = None 35 36 37def modbus_read_input_registers_cb(args): 38 global \ 39 label0, \ 40 label1, \ 41 label3, \ 42 label2, \ 43 wlan_sta, \ 44 modbustcpserver_0, \ 45 starting_register4, \ 46 slave_list4, \ 47 starting_register1, \ 48 slave_list1, \ 49 starting_register2, \ 50 slave_list2, \ 51 register2, \ 52 slave_value2, \ 53 starting_register3, \ 54 slave_list3, \ 55 starting_register6, \ 56 slave_list6, \ 57 register1, \ 58 slave_value1, \ 59 starting_register5, \ 60 slave_list5 61 _, starting_register4, slave_list4 = args 62 label0.setText(str("read input register")) 63 label1.setText(str(starting_register4)) 64 label2.setText(str(slave_list4)) 65 66 67def modbus_read_coils_cb(args): 68 global \ 69 label0, \ 70 label1, \ 71 label3, \ 72 label2, \ 73 wlan_sta, \ 74 modbustcpserver_0, \ 75 starting_register4, \ 76 slave_list4, \ 77 starting_register1, \ 78 slave_list1, \ 79 starting_register2, \ 80 slave_list2, \ 81 register2, \ 82 slave_value2, \ 83 starting_register3, \ 84 slave_list3, \ 85 starting_register6, \ 86 slave_list6, \ 87 register1, \ 88 slave_value1, \ 89 starting_register5, \ 90 slave_list5 91 _, starting_register1, slave_list1 = args 92 label0.setText(str("read coils")) 93 label1.setText(str(starting_register1)) 94 label2.setText(str(slave_list1)) 95 96 97def modbus_read_discrete_inputs_cb(args): 98 global \ 99 label0, \ 100 label1, \ 101 label3, \ 102 label2, \ 103 wlan_sta, \ 104 modbustcpserver_0, \ 105 starting_register4, \ 106 slave_list4, \ 107 starting_register1, \ 108 slave_list1, \ 109 starting_register2, \ 110 slave_list2, \ 111 register2, \ 112 slave_value2, \ 113 starting_register3, \ 114 slave_list3, \ 115 starting_register6, \ 116 slave_list6, \ 117 register1, \ 118 slave_value1, \ 119 starting_register5, \ 120 slave_list5 121 _, starting_register2, slave_list2 = args 122 label0.setText(str("read discrete input")) 123 label1.setText(str(starting_register2)) 124 label2.setText(str(slave_list2)) 125 126 127def modbus_write_single_registers_cb(args): 128 global \ 129 label0, \ 130 label1, \ 131 label3, \ 132 label2, \ 133 wlan_sta, \ 134 modbustcpserver_0, \ 135 starting_register4, \ 136 slave_list4, \ 137 starting_register1, \ 138 slave_list1, \ 139 starting_register2, \ 140 slave_list2, \ 141 register2, \ 142 slave_value2, \ 143 starting_register3, \ 144 slave_list3, \ 145 starting_register6, \ 146 slave_list6, \ 147 register1, \ 148 slave_value1, \ 149 starting_register5, \ 150 slave_list5 151 _, register2, slave_value2 = args 152 label0.setText(str("write single registers")) 153 label1.setText(str(register2)) 154 label2.setText(str(slave_value2)) 155 156 157def modbus_read_holding_registers_cb(args): 158 global \ 159 label0, \ 160 label1, \ 161 label3, \ 162 label2, \ 163 wlan_sta, \ 164 modbustcpserver_0, \ 165 starting_register4, \ 166 slave_list4, \ 167 starting_register1, \ 168 slave_list1, \ 169 starting_register2, \ 170 slave_list2, \ 171 register2, \ 172 slave_value2, \ 173 starting_register3, \ 174 slave_list3, \ 175 starting_register6, \ 176 slave_list6, \ 177 register1, \ 178 slave_value1, \ 179 starting_register5, \ 180 slave_list5 181 _, starting_register3, slave_list3 = args 182 label0.setText(str("read holding register")) 183 label1.setText(str(starting_register3)) 184 label2.setText(str(slave_list3)) 185 186 187def modbus_write_multiple_registers_cb(args): 188 global \ 189 label0, \ 190 label1, \ 191 label3, \ 192 label2, \ 193 wlan_sta, \ 194 modbustcpserver_0, \ 195 starting_register4, \ 196 slave_list4, \ 197 starting_register1, \ 198 slave_list1, \ 199 starting_register2, \ 200 slave_list2, \ 201 register2, \ 202 slave_value2, \ 203 starting_register3, \ 204 slave_list3, \ 205 starting_register6, \ 206 slave_list6, \ 207 register1, \ 208 slave_value1, \ 209 starting_register5, \ 210 slave_list5 211 _, starting_register6, slave_list6 = args 212 label0.setText(str("write multiple registers")) 213 label1.setText(str(slave_list6)) 214 label2.setText(str(slave_list6)) 215 216 217def modbus_write_single_coil_cb(args): 218 global \ 219 label0, \ 220 label1, \ 221 label3, \ 222 label2, \ 223 wlan_sta, \ 224 modbustcpserver_0, \ 225 starting_register4, \ 226 slave_list4, \ 227 starting_register1, \ 228 slave_list1, \ 229 starting_register2, \ 230 slave_list2, \ 231 register2, \ 232 slave_value2, \ 233 starting_register3, \ 234 slave_list3, \ 235 starting_register6, \ 236 slave_list6, \ 237 register1, \ 238 slave_value1, \ 239 starting_register5, \ 240 slave_list5 241 _, register1, slave_value1 = args 242 label0.setText(str("write single coil")) 243 label1.setText(str(register1)) 244 label2.setText(str(slave_value1)) 245 246 247def modbus_write_multiple_coils_cb(args): 248 global \ 249 label0, \ 250 label1, \ 251 label3, \ 252 label2, \ 253 wlan_sta, \ 254 modbustcpserver_0, \ 255 starting_register4, \ 256 slave_list4, \ 257 starting_register1, \ 258 slave_list1, \ 259 starting_register2, \ 260 slave_list2, \ 261 register2, \ 262 slave_value2, \ 263 starting_register3, \ 264 slave_list3, \ 265 starting_register6, \ 266 slave_list6, \ 267 register1, \ 268 slave_value1, \ 269 starting_register5, \ 270 slave_list5 271 _, starting_register5, slave_list5 = args 272 label0.setText(str("write multiple coils")) 273 label0.setText(str(slave_list5)) 274 label0.setText(str(slave_list5)) 275 276 277def setup(): 278 global \ 279 label0, \ 280 label1, \ 281 label3, \ 282 label2, \ 283 wlan_sta, \ 284 modbustcpserver_0, \ 285 starting_register4, \ 286 slave_list4, \ 287 starting_register1, \ 288 slave_list1, \ 289 starting_register2, \ 290 slave_list2, \ 291 register2, \ 292 slave_value2, \ 293 starting_register3, \ 294 slave_list3, \ 295 starting_register6, \ 296 slave_list6, \ 297 register1, \ 298 slave_value1, \ 299 starting_register5, \ 300 slave_list5 301 302 M5.begin() 303 Widgets.setRotation(1) 304 Widgets.fillScreen(0x222222) 305 label0 = Widgets.Label("label0", 61, 54, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 306 label1 = Widgets.Label("label1", 58, 94, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 307 label3 = Widgets.Label("label3", 53, 11, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 308 label2 = Widgets.Label("label2", 58, 133, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) 309 310 wlan_sta = network.WLAN(network.STA_IF) 311 while not (wlan_sta.isconnected()): 312 pass 313 label3.setText(str(wlan_sta.ifconfig()[0])) 314 modbustcpserver_0 = modbus.ModbusTCPServer("0.0.0.0", 5000, device_address=1, verbose=False) 315 modbustcpserver_0.set_callback( 316 modbustcpserver_0.READ_INPUT_REGISTERS_EVENT, modbus_read_input_registers_cb 317 ) 318 modbustcpserver_0.set_callback(modbustcpserver_0.READ_COILS_EVENT, modbus_read_coils_cb) 319 modbustcpserver_0.set_callback( 320 modbustcpserver_0.READ_DISCRETE_INPUTS_EVENT, modbus_read_discrete_inputs_cb 321 ) 322 modbustcpserver_0.set_callback( 323 modbustcpserver_0.WRITE_SINGLE_REGISTER_EVENT, modbus_write_single_registers_cb 324 ) 325 modbustcpserver_0.set_callback( 326 modbustcpserver_0.READ_HOLDING_REGISTERS_EVENT, modbus_read_holding_registers_cb 327 ) 328 modbustcpserver_0.set_callback( 329 modbustcpserver_0.WRITE_MULTIPLE_REGISTERS_EVENT, modbus_write_multiple_registers_cb 330 ) 331 modbustcpserver_0.set_callback( 332 modbustcpserver_0.WRITE_SINGLE_COIL_EVENT, modbus_write_single_coil_cb 333 ) 334 modbustcpserver_0.set_callback( 335 modbustcpserver_0.WRITE_MULTIPLE_COILS_EVENT, modbus_write_multiple_coils_cb 336 ) 337 modbustcpserver_0.add_coil(1000, True) 338 modbustcpserver_0.add_coil(1001, False) 339 modbustcpserver_0.add_coil(1002, True) 340 modbustcpserver_0.add_coil(1003, False) 341 modbustcpserver_0.add_coil(1004, True) 342 modbustcpserver_0.add_discrete_input(1000, True) 343 modbustcpserver_0.add_discrete_input(1001, False) 344 modbustcpserver_0.add_discrete_input(1002, True) 345 modbustcpserver_0.add_discrete_input(1003, False) 346 modbustcpserver_0.add_discrete_input(1004, True) 347 modbustcpserver_0.add_holding_register(1000, 0x0102) 348 modbustcpserver_0.add_holding_register(1001, 0x0304) 349 modbustcpserver_0.add_holding_register(1002, 0x0506) 350 modbustcpserver_0.add_holding_register(1003, 0x0708) 351 modbustcpserver_0.add_holding_register(1004, 0x090A) 352 modbustcpserver_0.add_input_register(1000, 0x0102) 353 modbustcpserver_0.add_input_register(1001, 0x0304) 354 modbustcpserver_0.add_input_register(1002, 0x0506) 355 modbustcpserver_0.add_input_register(1003, 0x0708) 356 modbustcpserver_0.add_input_register(1004, 0x090A) 357 modbustcpserver_0.start() 358 359 360def loop(): 361 global \ 362 label0, \ 363 label1, \ 364 label3, \ 365 label2, \ 366 wlan_sta, \ 367 modbustcpserver_0, \ 368 starting_register4, \ 369 slave_list4, \ 370 starting_register1, \ 371 slave_list1, \ 372 starting_register2, \ 373 slave_list2, \ 374 register2, \ 375 slave_value2, \ 376 starting_register3, \ 377 slave_list3, \ 378 starting_register6, \ 379 slave_list6, \ 380 register1, \ 381 slave_value1, \ 382 starting_register5, \ 383 slave_list5 384 M5.update() 385 modbustcpserver_0.tick() 386 387 388if __name__ == "__main__": 389 try: 390 setup() 391 while True: 392 loop() 393 except (Exception, KeyboardInterrupt) as e: 394 try: 395 from utility import print_error_msg 396 397 print_error_msg(e) 398 except ImportError: 399 print("please update to latest firmware")
Example output:
None
API
ModbusTCPServer
- class modbus.ModbusTCPServer(host: str, port: int = 502, verbose: bool = False)
Create a ModbusTCPServer object.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
from modbus import ModbusTCPServer server = ModbusTCPServer('0.0.0.0', 502)
- start() None
Start the Modbus RTU slave.
UiFlow2 Code Block:

MicroPython Code Block:
server.start()
- add_coil(register: int, value: bool) None
Add a coil to the modbus register dictionary.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.add_coil(0, False)
- add_discrete_input(register: int, value: bool) None
Add a discrete input to the modbus register dictionary.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.add_discrete_input(0, False)
- add_holding_register(register: int, value: int) None
Add a holding register to the modbus register dictionary.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.add_holding_register(0, 0)
- add_input_register(register: int, value: int) None
Add an input register to the modbus register dictionary.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.add_input_register(0, 0)
- remove_coil(register: int) None
Remove a coil from the modbus register dictionary.
- Parameters:
register (int) – address of the coils. The address is 0x0000 to 0xFFFF.
UiFlow2 Code Block:

MicroPython Code Block:
server.remove_coil(0)
- remove_discrete_input(register: int) None
Remove a discrete input from the modbus register dictionary.
- Parameters:
register (int) – address of the discrete inputs. The address is 0x0000 to 0xFFFF.
UiFlow2 Code Block:

MicroPython Code Block:
server.remove_discrete_input(0)
- remove_holding_register(register: int) None
Remove a holding register from the modbus register dictionary.
- Parameters:
register (int) – address of the holding registers. The address is 0x0000 to 0xFFFF.
UiFlow2 Code Block:

MicroPython Code Block:
server.remove_holding_register(0)
- remove_input_register(register: int) None
Remove an input register from the modbus register dictionary.
- Parameters:
register (int) – address of the input registers. The address is 0x0000 to 0xFFFF.
UiFlow2 Code Block:

MicroPython Code Block:
server.remove_input_register(0)
- get_coil(register: int) bool
Get the coil value.
- Parameters:
register (int) – address of the coils. The address is 0x0000 to 0xFFFF.
- Returns:
The value of the coil.
UiFlow2 Code Block:

MicroPython Code Block:
server.get_coil(0)
- get_discrete_input(register: int) bool
Get the discrete input value.
- Parameters:
register (int) – address of the discrete inputs. The address is 0x0000 to 0xFFFF.
- Returns:
The value of the discrete input.
UiFlow2 Code Block:

MicroPython Code Block:
server.get_discrete_input(0)
- get_holding_register(register: int) int
Get the holding register value.
- Parameters:
register (int) – address of the holding registers. The address is 0x0000 to 0xFFFF.
- Returns:
The value of the holding register.
UiFlow2 Code Block:

MicroPython Code Block:
server.get_holding_register(0)
- get_input_register(register: int) int
Get the input register value.
- Parameters:
register (int) – address of the input registers. The address is 0x0000 to 0xFFFF.
- Returns:
The value of the input register.
UiFlow2 Code Block:

MicroPython Code Block:
server.get_input_register(0)
- set_coil(register: int, value: bool) None
Set the coil value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_coil(0, False)
- set_multi_coils(register: int, value: list) None
Set the multi coils value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_multi_coils(0, [False, True])
- set_discrete_input(register: int, value: bool) None
Set the discrete input value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_discrete_input(0, False)
- set_multi_discrete_input(register: int, value: list) None
Set the multi discrete inputs value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_multi_discrete_input(0, [False, True])
- set_holding_register(register: int, value: int) None
Set the holding register value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_holding_register(0, 0)
- set_multi_holding_register(register: int, value: list) None
Set the multi holding registers value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_multi_holding_register(0, [0, 1])
- set_input_register(register: int, value: int) None
Set the input register value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_input_register(0, 0)
- set_multi_input_register(register: int, value: list) None
Set the multi input registers value.
- Parameters:
UiFlow2 Code Block:

MicroPython Code Block:
server.set_multi_input_register(0, [0, 1])
- tick() None
Modbus RTU slave tick function. This function should be called in the main loop.
UiFlow2 Code Block:

MicroPython Code Block:
server.tick()
- set_callback(func_code: int, handler) None
Set the callback function for the function code.
- Parameters:
func_code (int) – Function code. The function code is 1 to 6, 15, 16. the symbol is defined in the modbus.ModbusTCPServer (*_EVENT etc.).
handler – Callback function.
UiFlow2 Code Block:








MicroPython Code Block:
def cb(arg): pass server.set_callback(1, cb)
- READ_COILS_EVENT
Function code 1 (Read Coils).
- READ_DISCRETE_INPUTS_EVENT
Function code 2 (Read Discrete Inputs).
- READ_HOLDING_REGISTERS_EVENT
Function code 3 (Read Holding Registers).
- READ_INPUT_REGISTERS_EVENT
Function code 4 (Read Input Registers).
- WRITE_SINGLE_COIL_EVENT
Function code 5 (Write Single Coil).
- WRITE_SINGLE_HOLDING_REGISTER_EVENT
Function code 6 (Write Single Holding Register).
- WRITE_MULTIPLE_COILS_EVENT
Function code 15 (Write Multiple Coils).
- WRITE_MULTIPLE_HOLDING_REGISTERS_EVENT
Function code 16 (Write Multiple Holding Registers).

