Open ondrej1024 opened 1 year ago
I did some more testing and found that when reading the response I always get first a single byte 0x00 and after that the actual response frame. The single byte causes the reported IndexError
in _exit_read
So I did a simple modification throwing away always the first single byte of the response. This basically works. However quite often the response frame is not received completely, leading to CRC error.
So I was wondering if software direction control via IO pin has actually been tested and if it is reliable?
Have you fitted a 120 ohm resistor on the line connection on the slave. I run RS485 over wifi and all my slaves need a 120 ohm resistor as they all think they are the last one on the cable.
I have a regular RS485 bus with 120 Ohm termination. The bus itself works fine. When using HW direction control I don't get any errors.
@ondrej1024 Hello!
So I was wondering if software direction control via IO pin has actually been tested and if it is reliable?
I'm using this lib for RS-485
using the MAX485CSA
chip, that use a control pin, like do you are using, and are working without errors mostly of time - here you can see one of my tests. I wrote mostly of time because sometimes happen Invalid CRC
reading COILS
WHEN first I write multiple COILS
and after that I try to read the COILS again - here you can see this problem happening. Bellow a example of error:
>>> host.read_coils(slave_addr=10, starting_addr=125, coil_qty=16)
[True, True, True, True, True, False, False, False, False, True, True, True, False, False, False, True]
>>> host.write_multiple_coils(slave_addr=10, starting_address=125, output_values=[1,1,0])
True
>>> host.read_coils(slave_addr=10, starting_addr=125, coil_qty=3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/lib/umodbus/common.py", line 136, in read_coils
File "/lib/umodbus/serial.py", line 289, in _send_receive
File "/lib/umodbus/serial.py", line 322, in _validate_resp_hdr
OSError: invalid response CRC
Look that first read_coils()
works, but after write_multiple_coils()
the read_coils()
stop to works, or sometimes works and sometimes not works
I don't know if your problem is the same of that, or if your problem has something to do with this problem, but the @brainelectronics opened an issue for that #52
I use only reading/writing holding registers, no coils.
Anyway I found that I have some issue with the ground reference of my circuitry. With a proper reference I always get a valid response from the slave, so SW direction control is working fine.
However I still see an initial 0x00 byte in the RX buffer immediately after sending the request. So I have to take care of this, otherwise I get a CRC error. I don't have an explanation for this.
Hey @ondrej1024 may you can give release 2.3.5 a try again? MicroPython v1.20.0 is recommended as it introduces the flush
function for UART, implemented in #75, for older MicroPython firmware versions the timing has been improved as well. In case the reported issue was based on a HW problem you might close this issue
Yes, I will test this the next days and report back.
I have tested release 2.3.5 now with MP 1.20.0 but I still see the same issue. I get CRC error.
This is the code I use:
from machine import Pin
from umodbus.serial import Serial as ModbusRTUMaster
GP_UART0_TX = 0 # RS485 DI
GP_UART0_RX = 1 # RS485 RO
GP_UART0_DC = 2 # RS485 DC
mbm0 = ModbusRTUMaster(pins=(Pin(GP_UART0_TX), Pin(GP_UART0_RX)), ctrl_pin=GP_UART0_DC, uart_id=0)
mbm0.read_holding_registers(1,1,1)
And this is the error message:
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
File "/lib/umodbus/common.py", line 199, in read_holding_registers
File "/lib/umodbus/serial.py", line 314, in _send_receive
File "/lib/umodbus/serial.py", line 347, in _validate_resp_hdr
OSError: invalid response CRC
The above code works fine with release 2.3.4 and this patched version of serial.py: serial.txt
Hi again @ondrej1024 may you can give release 2.3.7 another try again? I've added you proposed wait time after the flush. In case the reported issue was based on a HW problem you might close this issue
Just wanted to say this is likely a hardware issue and add a potential fix for anyone else that ends up here from searching.
I use the same SP3485. The datasheet says that if ~RE and DE are both pulled high (as they are when using a common GPIO to enable transmission) then the RO output should be High-Z. On my shoddy breadboard setup, RO was actually getting pulled low. This looks like a start bit on the UART RX, resulting in the reception of a 0x00 character.
Adding a pullup on RO is a hardware fix. If you need a software bodge fix, clear any bytes received before the peripheral should have had a chance to respond.
while self._uart.any() > 0:
# print('ditching bad rx')
self._uart.read()
For example, somewhere in the _send(...)
method around here (or just right before/after if you don't care too much about affecting the timings):
Comparison of without pullup resistor on RO vs with pullup, showing what looks like a failed RX to the UART as it is missing the stop bit. Top orange trace is RO (UART RX on the Pico I'm using).
Without:
With:
With the pullup in place, the expected packets are received and CRCs pass etc.
I agree, also my problem seems to be a hardware issue. There is no pullup on the RO line here and, although I haven't tried to solder one, I am pretty sure it would fix it. So I guess we can close this issue now.
Description
I am using a ST3485 RS485 transceiver with the DE/RE pins shortened and connected to a GPIO pin.
Running as Modbus master, the request is received correctly by the slave but the response is not received and
umodbus
throws an error (see below).I suspect some timing issue with the transceiver switching to read mode but can't quite find the root cause of this.
Any ideas?
Reproduction steps
1. Initialization:
mbm0 = ModbusRTUMaster(pins=(Pin(GP_UART0_TX), Pin(GP_UART0_RX)),ctrl_pin=GP_UART0_DC, uart_id=0)
2. Send request to slave
mbm0.read_holding_registers(42,1,1)
MicroPython version
MicroPython v1.19.1-994-ga4672149b
MicroPython board
Raspberry Pico
MicroPython Modbus version
Relevant log output
User code
No response
Additional informations
No response