Odd UART behaviour #10674
-
I have build a simple RS422 converter to interface with a ModBus Device using the UART interface. The electrical diagram looks similar to this: https://github.com/dkjonas/Wavin-AHC-9000-mqtt/blob/master/electronics/schematic.png with the exception that I replaced the NodeMCU ESP8266 with the PICO and connected TX to GPIO0, TX to GPIO1, 3V3 to VSYS and the connection on the drawing going to GPIO5 to GPIO10 on the PICO. I measured the voltages and its spot on 3.3V. The PICO boots up fine and runs stable. I initialize the UART with:
(note the RX buf 49 is sized to meet the requirements for the largest/longest message I can receive from the modbus device - baudrate. bits, partity etc. are dictated by the ModBus device spec). I then send a command to trigger a response from the ModBus device using this routine (data is a bytearray containing the command and a CRC code at the end - the modbus will calculate the CRC again and see if it matched. If it does not match it sends an error back.)
Then I wait the specified silent period between the send and receive operation (again its a modbus spec, 1.75ms) and start reading the incoming data:
On the ESP8266 this worked flawlessly and I had clean communication with the ModBus device. However moving this to the PICO i sometimes get "random data" in the RX buffer and sometimes the write/read cycle happens without any issue. If i get "random data" and thus a CRC error calculation i resend the command and try reading again. Usually it then succeeds after the 1st or second attempts (sometimes up to 4 tries) and I get the correct response I have checked if the "random data" in the RX buffer could be an error signal from the ModBus device, however its not. If the Modbus device did not understand what I send it does not respond at all. If i send a correct command but where the CRC does not match, the modbus device will send the applicable error code back. But none of the data on the RX buffer makes any sense in relation to the ModBus spec/error codes. I have done some testing and can see that the RX buffer starts containing data right after I finish writing (despite me flushing it before the write operation) and while the control pin (GPIO10) is still high (which prevents the MAX3072E chip to actually send anything to the PICO). The modbus specification clearly states that we only can expect a response when the Modbus device as received and replied to a correct command. It will not just send random things out. But where is the data coming from then? Is this a buffer overflow of some kind in the internal micro code or micropython implementation? Where random data can makes its way into the RX buffers memory? As mentioned the same code functions without any issue and no random data in the RX buffer on the ESP8266. Im running: rp2-pico-w-20230203-unstable-v1.19.1-852-g9ea64a36a |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 16 replies
-
I guess that the garbage on RX is related to not switching the direction at the right time, maybe too late. Hint: Instead of the |
Beta Was this translation helpful? Give feedback.
-
Just a note: my test showed that uart.flush() may return from the call up to 1 ms after the transmission of the last byte has started. At 38400 baud that would be ~750µs after the end of transmission. You do not use that here, but it should better be changed to make it more dependable, that just exactly one character time delay has to be added. |
Beta Was this translation helpful? Give feedback.
-
Just a note: if you still have a wait loop with calling machine.idle() in your _raw_send function, replace idle() by a short sleep (like sleep_us(100)). machine.idle() calls MICROPY_EVENT_POLL_HOOK, and that will wait up to 1 ms. That may still cause the wrong receives. |
Beta Was this translation helpful? Give feedback.
Just a note: my test showed that uart.flush() may return from the call up to 1 ms after the transmission of the last byte has started. At 38400 baud that would be ~750µs after the end of transmission. You do not use that here, but it should better be changed to make it more dependable, that just exactly one character time delay has to be added.
That does not help you here, but your problem may be caused by a similar effect.