Closed wpyoga closed 1 year ago
@wpyoga Thank you very much for this PR :partying_face:
I will test it as soon is possible with the MAX485 using control pin, and I will report the result tests here!
@wpyoga Works like a charm with the MAX485 using control pin :partying_face:
I'm using the semi official examples to run Slave RTU
(rtu_client_example.py) and Master RTU
(rtu_host_example.py) and I have no CRC errors anymore. Ps: I call semi official examples because we (@brainelectronics) is waiting the PR #56 be merged to merge that examples (sync
and async
) too. Follow the tests:
Slave RTU (sync):
$ mpremote run rtu_client_example.py
MicroPython infos: (sysname='esp32', nodename='esp32', release='1.20.0', version='v1.20.0 on 2023-04-26', machine='ESP32S3 module (spiram) with ESP32S3')
Used micropthon-modbus version: 0.0.0
Using pins (17, 18) with UART ID 1
Setting up registers ...
Register setup done
Serving as RTU client on address 10 at 115200 baud
my_coil_get_cb, called on getting COILS at 123, currently: [1, False, False, False, False, False, False, False, False, False, False, False]
my_coil_set_cb, called on setting COILS at 123 to: [False]
my_coil_get_cb, called on getting COILS at 123, currently: [False, False, False, False, False, False, False, False, False, False, False, False]
my_hr_get_cb, called on getting HREGS at 93, currently: [19]
my_hr_set_sb, called on setting HREGS at 93 to: [44]
my_hr_get_cb, called on getting HREGS at 93, currently: [44]
my_di_get_cb, called on getting ISTS at 67, currently: [0]
my_ir_get_cb, called on getting IREGS at 10, currently: [60001]
Incremented current value by +1 before sending response
Resetting register data to default values ...
Default values restored
Master RTU (sync):
$ mpremote run rtu_host_example.py
MicroPython infos: (sysname='esp32', nodename='esp32', release='1.20.0', version='v1.20.0 on 2023-04-26', machine='ESP32S3 module (spiram) with ESP32S3')
Used micropthon-modbus version: 0.0.0
Using pins (17, 18) with UART ID 1
Requesting and updating data on RTU client at address 10 with 115200 baud
Status of COIL 123: [True, False, False, False, False, False, False, False, False, False, False, False]
Result of setting COIL 123 to True
Status of COIL 123: [False, False, False, False, False, False, False, False, False, False, False, False]
Status of HREG 93: (19,)
Result of setting HREG 93 to True
Status of HREG 93: (44,)
Status of IST 67: [False]
Status of IREG 10: (60002,)
Resetting register data to default values...
Result of setting COIL 42: True
Finished requesting/setting data on client
So nice! Great work @wpyoga. Big thank you again to @beyonlo for testing. Will merge and release this tomorrow.
Thanks guys! I'm glad I could help, I was intially only trying to fix issues I saw on my end :)
@beyonlo could you re-do your tests? I had to add support for MicroPython v1.19.1 and earlier as UART.flush()
got introduced in 1.20.0, but some of my products are running on MicroPython v1.18. I did some quick tests locally with my setups at 9600, 57600 and 115200 baud which look good, see screenshots. The changes of @wpyoga are not affected by my additions
@brainelectronics As requested, I re-do the tests using the release https://github.com/brainelectronics/micropython-modbus/archive/refs/tags/2.3.5.tar.gz but the version do not show 2.3.5
, it show 0.0.0
- why? I tested in 9600
, 57600
and 115200
and all works, but here I will paste just using the 115200
:
Slave RTU (sync) - (rtu_client_example.py):
$ mpremote run rtu_client_example.py
MicroPython infos: (sysname='esp32', nodename='esp32', release='1.20.0', version='v1.20.0 on 2023-04-26', machine='ESP32S3 module (spiram) with ESP32S3')
Used micropthon-modbus version: 0.0.0
Using pins (37, 38) with UART ID 1
Setting up registers ...
Register setup done
Serving as RTU client on address 10 at 115200 baud
my_coil_get_cb, called on getting COILS at 123, currently: [1, False, False, False, False, False, False, False, False, False, False, False]
my_coil_set_cb, called on setting COILS at 123 to: [False]
my_coil_get_cb, called on getting COILS at 123, currently: [False, False, False, False, False, False, False, False, False, False, False, False]
my_hr_get_cb, called on getting HREGS at 93, currently: [19]
my_hr_set_sb, called on setting HREGS at 93 to: [44]
my_hr_get_cb, called on getting HREGS at 93, currently: [44]
my_di_get_cb, called on getting ISTS at 67, currently: [0]
my_ir_get_cb, called on getting IREGS at 10, currently: [60001]
Incremented current value by +1 before sending response
Resetting register data to default values ...
Default values restored
Master RTU (sync) - (rtu_host_example.py):
$ mpremote run rtu_host_example.py
MicroPython infos: (sysname='esp32', nodename='esp32', release='1.20.0', version='v1.20.0 on 2023-04-26', machine='ESP32S3 module (spiram) with ESP32S3')
Used micropthon-modbus version: 0.0.0
Using pins (17, 18) with UART ID 1
Requesting and updating data on RTU client at address 10 with 115200 baud
Status of COIL 123: [True, False, False, False, False, False, False, False, False, False, False, False]
Result of setting COIL 123 to True
Status of COIL 123: [False, False, False, False, False, False, False, False, False, False, False, False]
Status of HREG 93: (19,)
Result of setting HREG 93 to True
Status of HREG 93: (44,)
Status of IST 67: [False]
Status of IREG 10: (60002,)
Resetting register data to default values...
Result of setting COIL 42: True
Finished requesting/setting data on client
This pull request fixes timing issues when sending a command and receiving a response:
The missing initial bytes issue is apparent when we use a TTL-to-RS485 converter board that does not have automatic flow control. This is usually in the form of an EN pin, or DE & ~RE pin jumpered together. They are equivalent. This can be seen in the extremely popular MAX485 chip. This is caused by disabling the EN pin too late -- thus messing up the initial slave response.
The fix for the issue with receiving long slave responses is not perfect, but should be good enough for now. I was able to consistently trigger this issue by reading many (64, 96, and even 125) registers at once. An ideal solution would involve letting the user/caller specify the timeout value for reading a response.
P.S. Apologies to @brainelectronics , I did not see your PR #73 before going with this approach. However, I believe this solution will fix both your problem (ticks rollover) and the initial bytes being truncated.
P.P.S. This pull request should (may) also fix these issues:
52
68 by @ondrej1024
50 by @j-broome