class ModbusTCPServer – Modbus TCP server

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).

Micropython Example:

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

UIFLOW2 Example:

example.png

cores3_tcp_server_example.m5f2

Constructors

class modbus.ModbusTCPServer(host: str, port: int = 502, verbose: bool = False)

Create a ModbusTCPServer object.

参数:
  • host (str) – Hostname or IP address.

  • port (int) – Port number.

  • verbose (bool) – Verbose mode.

UIFLOW2:

init.png

Methods

ModbusTCPServer.start() None

Start the Modbus RTU slave.

UIFLOW2:

start.png

ModbusTCPServer.stop() None

Stop the Modbus RTU slave.

UIFLOW2:

stop.png

ModbusTCPServer.add_coil(register: int, value: bool) None

Add a coil to the modbus register dictionary.

参数:
  • register (int) – address of the coils. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to add. The value is True or False.

UIFLOW2:

add_coil.png

ModbusTCPServer.add_discrete_input(register: int, value: bool) None

Add a discrete input to the modbus register dictionary.

参数:
  • register (int) – address of the discrete inputs. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to add. The value is True or False.

UIFLOW2:

add_discrete_input.png

ModbusTCPServer.add_holding_register(register: int, value: int) None

Add a holding register to the modbus register dictionary.

参数:
  • register (int) – address of the holding registers. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to add. The value is 0x0000 to 0xFFFF.

UIFLOW2:

add_holding_register.png

ModbusTCPServer.add_input_register(register: int, value: int) None

Add an input register to the modbus register dictionary.

参数:
  • register (int) – address of the input registers. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to add. The value is 0x0000 to 0xFFFF.

UIFLOW2:

add_input_register.png

ModbusTCPServer.remove_coil(register: int) None

Remove a coil from the modbus register dictionary.

参数:

register (int) – address of the coils. The address is 0x0000 to 0xFFFF.

UIFLOW2:

remove_coil.png

ModbusTCPServer.remove_discrete_input(register: int) None

Remove a discrete input from the modbus register dictionary.

参数:

register (int) – address of the discrete inputs. The address is 0x0000 to 0xFFFF.

UIFLOW2:

remove_discrete_input.png

ModbusTCPServer.remove_holding_register(register: int) None

Remove a holding register from the modbus register dictionary.

参数:

register (int) – address of the holding registers. The address is 0x0000 to 0xFFFF.

UIFLOW2:

remove_holding_register.png

ModbusTCPServer.remove_input_register(register: int) None

Remove an input register from the modbus register dictionary.

参数:

register (int) – address of the input registers. The address is 0x0000 to 0xFFFF.

UIFLOW2:

remove_input_register.png

ModbusTCPServer.get_coil(register: int) bool

Get the coil value.

参数:

register (int) – address of the coils. The address is 0x0000 to 0xFFFF.

返回:

The value of the coil.

UIFLOW2:

get_coil.png

ModbusTCPServer.get_discrete_input(register: int) bool

Get the discrete input value.

参数:

register (int) – address of the discrete inputs. The address is 0x0000 to 0xFFFF.

返回:

The value of the discrete input.

UIFLOW2:

get_discrete_input.png

ModbusTCPServer.get_holding_register(register: int) int

Get the holding register value.

参数:

register (int) – address of the holding registers. The address is 0x0000 to 0xFFFF.

返回:

The value of the holding register.

UIFLOW2:

get_holding_register.png

ModbusTCPServer.get_input_register(register: int) int

Get the input register value.

参数:

register (int) – address of the input registers. The address is 0x0000 to 0xFFFF.

返回:

The value of the input register.

UIFLOW2:

get_input_register.png

ModbusTCPServer.set_coil(register: int, value: bool) None

Set the coil value.

参数:
  • register (int) – address of the coils. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to set. The value is True or False.

UIFLOW2:

set_coil.png

ModbusTCPServer.set_multi_coils(register: int, value: list) None

Set the multi coils value.

参数:
  • register (int) – address of the coils. The address is 0x0000 to 0xFFFF.

  • value (list) – Values to set. The value is a list of True or False.

UIFLOW2:

set_multi_coils.png

ModbusTCPServer.set_discrete_input(register: int, value: bool) None

Set the discrete input value.

参数:
  • register (int) – address of the discrete inputs. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to set. The value is True or False.

UIFLOW2:

set_discrete_input.png

ModbusTCPServer.set_multi_discrete_input(register: int, value: list) None

Set the multi discrete inputs value.

参数:
  • register (int) – address of the discrete inputs. The address is 0x0000 to 0xFFFF.

  • value (list) – Values to set. The value is a list of True or False.

UIFLOW2:

set_multi_discrete_input.png

ModbusTCPServer.set_holding_register(register: int, value: int) None

Set the holding register value.

参数:
  • register (int) – address of the holding registers. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to set. The value is 0x0000 to 0xFFFF.

UIFLOW2:

set_holding_register.png

ModbusTCPServer.set_multi_holding_register(register: int, value: list) None

Set the multi holding registers value.

参数:
  • register (int) – address of the holding registers. The address is 0x0000 to 0xFFFF.

  • value (list) – Values to set. The value is a list of 0x0000 to 0xFFFF.

UIFLOW2:

set_multi_holding_register.png

ModbusTCPServer.set_input_register(register: int, value: int) None

Set the input register value.

参数:
  • register (int) – address of the input registers. The address is 0x0000 to 0xFFFF.

  • value (int) – Value to set. The value is 0x0000 to 0xFFFF.

UIFLOW2:

set_input_register.png

ModbusTCPServer.set_multi_input_register(register: int, value: list) None

Set the multi input registers value.

参数:
  • register (int) – address of the input registers. The address is 0x0000 to 0xFFFF.

  • value (list) – Values to set. The value is a list of 0x0000 to 0xFFFF.

UIFLOW2:

set_multi_input_register.png

ModbusTCPServer.tick() None

Modbus RTU slave tick function. This function should be called in the main loop.

UIFLOW2:

tick.png

ModbusTCPServer.set_callback(func_code: int, handler) None

Set the callback function for the function code.

参数:
  • 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:

read_coils_callback.png

read_discrete_inputs_callback.png

read_holding_registers_callback.png

read_input_registers_callback.png

write_multiple_coils_callback.png

write_multiple_registers_callback.png

write_single_coil_callback.png

write_single_register_callback.png

Constants

ModbusTCPServer.READ_COILS_EVENT

Function code 1 (Read Coils).

ModbusTCPServer.READ_DISCRETE_INPUTS_EVENT

Function code 2 (Read Discrete Inputs).

ModbusTCPServer.READ_HOLDING_REGISTERS_EVENT

Function code 3 (Read Holding Registers).

ModbusTCPServer.READ_INPUT_REGISTERS_EVENT

Function code 4 (Read Input Registers).

ModbusTCPServer.WRITE_SINGLE_COIL_EVENT

Function code 5 (Write Single Coil).

ModbusTCPServer.WRITE_SINGLE_HOLDING_REGISTER_EVENT

Function code 6 (Write Single Holding Register).

ModbusTCPServer.WRITE_MULTIPLE_COILS_EVENT

Function code 15 (Write Multiple Coils).

ModbusTCPServer.WRITE_MULTIPLE_HOLDING_REGISTERS_EVENT

Function code 16 (Write Multiple Holding Registers).