Skip to content

Commit ea37dc2

Browse files
Merge pull request #10 from brainelectronics/bugfix/improve-docs-and-add-examples
Improve docs and add examples
2 parents b2b042a + 27d1f44 commit ea37dc2

9 files changed

+363
-82
lines changed

README.md

+21-78
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,25 @@ comment of [`main.py`](main.py).
122122
Act as host, get Modbus data via RTU or TCP from a client device
123123

124124
```python
125+
# import modbus host classes
126+
from umodbus.tcp import TCP as ModbusTCPMaster
127+
from umodbus.serial import Serial as ModbusRTUMaster
128+
125129
# RTU Master setup
126130
# act as host, get Modbus data via RTU from a client device
131+
# ModbusRTUMaster can make serial requests to a client device to get/set data
127132
rtu_pins = (25, 26) # (TX, RX)
128133
slave_addr = 10 # bus address of client
129134
host = ModbusRTUMaster(
130135
baudrate=9600, # optional, default 9600
131-
data_bits=8, # optional, default 7
136+
data_bits=8, # optional, default 8
132137
stop_bits=1, # optional, default 1
133138
parity=None, # optional, default None
134139
pins=rtu_pins)
135140

136141
# TCP Master setup
137142
# act as host, get Modbus data via TCP from a client device
143+
# ModbusTCPMaster can make TCP requests to a client device to get/set data
138144
host = ModbusTCPMaster(
139145
slave_ip=192.168.178.34,
140146
slave_port=180,
@@ -144,7 +150,7 @@ host = ModbusTCPMaster(
144150
coil_address = 123
145151
coil_status = host.read_coils(
146152
slave_addr=slave_addr,
147-
starting_addr=123,
153+
starting_addr=coil_address,
148154
coil_qty=1)
149155
print('Status of coil {}: {}'.format(coil_status, coil_address))
150156

@@ -167,7 +173,7 @@ print('Status of hreg {}: {}'.format(hreg_address, register_value))
167173

168174
# WRITE HREGS
169175
new_hreg_val = 44
170-
operation_status = self.host.write_single_register(
176+
operation_status = host.write_single_register(
171177
slave_addr=slave_addr,
172178
register_address=hreg_address,
173179
register_value=new_hreg_val,
@@ -176,15 +182,15 @@ print('Result of setting hreg {} to {}'.format(hreg_address, operation_status))
176182

177183
# READ ISTS
178184
ist_address = 67
179-
input_status = self.host.read_discrete_inputs(
185+
input_status = host.read_discrete_inputs(
180186
slave_addr=slave_addr,
181187
starting_addr=ist_address,
182188
input_qty=1)
183189
print('Status of ist {}: {}'.format(ist_address, input_status))
184190

185191
# READ IREGS
186192
ireg_address = 10
187-
register_value = self.host.read_input_registers(
193+
register_value = host.read_input_registers(
188194
slave_addr=slave_addr,
189195
starting_addr=ireg_address,
190196
register_qty=2,
@@ -194,82 +200,18 @@ print('Status of ireg {}: {}'.format(ireg_address, register_value))
194200

195201
### Slave implementation
196202

197-
Act as client, provide Modbus data via RTU or TCP to a host device
203+
Act as client, provide Modbus data via RTU or TCP to a host device.
198204

199-
```python
200-
# RTU Slave setup
201-
# act as client, provide Modbus data via RTU to a host device
202-
rtu_pins = (25, 26) # (TX, RX)
203-
slave_addr = 10 # address on bus as client
204-
client = ModbusRTU(
205-
addr=slave_addr, # address on bus
206-
baudrate=9600, # optional, default 9600
207-
data_bits=8, # optional, default 7
208-
stop_bits=stop_bits, # optional, default 1
209-
parity=parity, # optional, default None
210-
pins=rtu_pins)
205+
See [Modbus TCP Client example](examples/tcp_client_example.py) and
206+
[Modbus RTU Client example](examples/rtu_client_example.py)
211207

212-
# TCP Slave setup
213-
# act as client, provide Modbus data via TCP to a host device
214-
local_ip = '192.168.4.1' # IP address
215-
tcp_port = 502 # port to listen to
208+
Both examples are using [example register definitions](examples/example.json)
216209

217-
"""
218-
# to get from MicroPython core functions use this
219-
import network
220-
station = network.WLAN(network.STA_IF)
221-
if station.active():
222-
if station.isconnected():
223-
local_ip = station.ifconfig()[0]
224-
"""
225-
226-
client = ModbusTCP()
227-
is_bound = False
228-
229-
# check whether client has been bound to an IP and port
230-
is_bound = client.get_bound_status()
231-
232-
if not is_bound:
233-
client.bind(local_ip=local_ip, local_port=tcp_port)
234-
235-
# commond slave register setup, to be used with the Master example above
236-
register_definitions = {
237-
"COILS": {
238-
"EXAMPLE_COIL": {
239-
"register": 123,
240-
"len": 1,
241-
}
242-
},
243-
"HREGS": {
244-
"EXAMPLE_HREG": {
245-
"register": 93,
246-
"len": 1,
247-
}
248-
},
249-
"ISTS": {
250-
"EXAMPLE_ISTS": {
251-
"register": 67,
252-
"len": 1,
253-
}
254-
},
255-
"IREGS": {
256-
"EXAMPLE_IREG": {
257-
"register": 10,
258-
"len": 2,
259-
}
260-
}
261-
}
262-
263-
"""
264-
# alternatively the register definitions can also be loaded from a JSON file
265-
import json
266-
267-
with open('registers/modbusRegisters-MyEVSE.json', 'r') as file:
268-
register_definitions = json.load(file)
269-
"""
270-
271-
client.setup_registers(registers=register_definitions, use_default_vals=True)
272-
```
210+
Use the provided example scripts [read RTU](examples/read_registers_rtu.sh) or
211+
[read TCP](examples/read_registers_tcp.sh) to read the data from the devices.
212+
This requires the [modules submodule][ref-github-be-python-modules] to be
213+
cloned as well and the required packages being installed as described in the
214+
modules README file.
273215

274216
### Register configuration
275217

@@ -308,6 +250,7 @@ of this library.
308250
[ref-pycom-modbus]: https://github.com/pycom/pycom-modbus
309251
[ref-remote-upy-shell]: https://github.com/dhylands/rshell
310252
[ref-github-be-mircopython-modules]: https://github.com/brainelectronics/micropython-modules
253+
[ref-github-be-python-modules]: https://github.com/brainelectronics/python-modules
311254
[ref-myevse-be]: https://brainelectronics.de/
312255
[ref-myevse-tindie]: https://www.tindie.com/stores/brainelectronics/
313256
[ref-giampiero7]: https://github.com/giampiero7

changelog.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
<!-- ## [Unreleased] -->
1616

1717
## Released
18+
## [1.1.1] - 2022-11-09
19+
### Fixed
20+
- Default value of `setup_registers` function parameter `use_default_vals`
21+
changed to `False` to avoid confusion behaviour if not explicitly defined,
22+
see [issue 13][ref-issue-13]
23+
- Missing function docstring added to `setup_registers` function
24+
- `write_single_coil` allows `0`, `1`, `False`, `True`, `0x0` or `0xFF00`
25+
instead of `0x0` and `0xFF00` only as set value, see [issue 14][ref-issue-14]
26+
1827
## [1.1.0] - 2022-11-03
1928
### Added
2029
- `float_to_bin`, `bin_to_float`, `int_to_bin` functions added to
@@ -85,12 +94,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8594
- PEP8 style issues on all files of [`lib/uModbus`](lib/uModbus)
8695

8796
<!-- Links -->
88-
[Unreleased]: https://github.com/brainelectronics/micropython-modbus/compare/1.1.0...develop
97+
[Unreleased]: https://github.com/brainelectronics/micropython-modbus/compare/1.1.1...develop
8998

99+
[1.1.1]: https://github.com/brainelectronics/micropython-modbus/tree/1.1.1
90100
[1.1.0]: https://github.com/brainelectronics/micropython-modbus/tree/1.1.0
91101
[1.0.0]: https://github.com/brainelectronics/micropython-modbus/tree/1.0.0
92102
[0.1.0]: https://github.com/brainelectronics/micropython-modbus/tree/0.1.0
93103

104+
[ref-issue-13]: https://github.com/brainelectronics/micropython-modbus/issues/13
105+
[ref-issue-14]: https://github.com/brainelectronics/micropython-modbus/issues/14
94106
[ref-pep440]: https://peps.python.org/pep-0440/
95107
[ref-pypi]: https://pypi.org/
96108
[ref-pfalcon-picoweb-sdist-upip]: https://github.com/pfalcon/picoweb/blob/b74428ebdde97ed1795338c13a3bdf05d71366a0/sdist_upip.py

examples/example.json

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"COILS": {
3+
"EXAMPLE_COIL": {
4+
"register": 123,
5+
"len": 1,
6+
"description": "Example COILS register, Coils (setter+getter) [0, 1]",
7+
"range": "",
8+
"unit": ""
9+
}
10+
},
11+
"HREGS": {
12+
"EXAMPLE_HREG": {
13+
"register": 93,
14+
"len": 1,
15+
"description": "Example HREGS register, Hregs (setter+getter) [0, 65535]",
16+
"range": "",
17+
"unit": ""
18+
}
19+
},
20+
"ISTS": {
21+
"EXAMPLE_ISTS": {
22+
"register": 67,
23+
"len": 1,
24+
"description": "Example ISTS register, Ists (only getter) [0, 1]",
25+
"range": "",
26+
"unit": ""
27+
}
28+
},
29+
"IREGS": {
30+
"EXAMPLE_IREG": {
31+
"register": 10,
32+
"len": 1,
33+
"description": "Example IREGS register, Iregs (only getter) [0, 65535]",
34+
"range": "",
35+
"unit": ""
36+
}
37+
}
38+
}

examples/read_registers_rtu.sh

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
# title :read_registers_rtu.sh
3+
# description :Read Modbus registers via Serial RTU based on register JSON
4+
# author :brainelectronics
5+
# date :20220708
6+
# version :0.1.0
7+
# usage :sh read_registers_rtu.sh \
8+
# /dev/tty.SLAB_USBtoUART \
9+
# example.json \
10+
# 10
11+
# Register file and modbus unit are optional
12+
# notes :Install python3 and its requirements file to use this script.
13+
# bash_version :3.2.53(1)-release
14+
#=============================================================================
15+
16+
connection_port=$1
17+
register_file_path=$2
18+
modbus_unit=$3
19+
20+
if [[ -z "$register_file_path" ]]; then
21+
register_file_path=example.json
22+
echo "No register file given, using default at $register_file_path"
23+
fi
24+
25+
if [[ -z "$modbus_unit" ]]; then
26+
modbus_unit=10
27+
echo "No modbus unit given, using default $modbus_unit"
28+
fi
29+
30+
echo "Read registers defined in $register_file_path via RS485 on $connection_port @ $modbus_unit"
31+
32+
python3 ../modules/read_device_info_registers.py \
33+
--file=$register_file_path \
34+
--connection=rtu \
35+
--address=$connection_port \
36+
--unit=$modbus_unit \
37+
--baudrate=9600 \
38+
--print \
39+
--pretty \
40+
--debug \
41+
--verbose=3

examples/read_registers_tcp.sh

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
# title :read_registers_tcp.sh
3+
# description :Read Modbus registers via TCP based on register JSON
4+
# author :brainelectronics
5+
# date :20220708
6+
# version :0.1.0
7+
# usage :sh read_registers_tcp.sh \
8+
# 192.168.178.188 \
9+
# example.json \
10+
# 502
11+
# Register file and modbus port are optional
12+
# notes :Install python3 and its requirements file to use this script.
13+
# bash_version :3.2.53(1)-release
14+
#=============================================================================
15+
16+
connection_address=$1
17+
register_file_path=$2
18+
modbus_port=$3
19+
20+
if [[ -z "$register_file_path" ]]; then
21+
register_file_path=example.json
22+
echo "No register file given, using default at $register_file_path"
23+
fi
24+
25+
if [[ -z "$modbus_port" ]]; then
26+
modbus_port=255
27+
echo "No modbus unit given, using default $modbus_port"
28+
fi
29+
30+
echo "Read registers defined in $register_file_path via TCP from $connection_address"
31+
32+
python3 ../modules/read_device_info_registers.py \
33+
--file=$register_file_path \
34+
--connection=tcp \
35+
--address=$connection_address \
36+
--port=$modbus_port \
37+
--print \
38+
--pretty \
39+
--debug \
40+
--verbose=3

0 commit comments

Comments
 (0)