Skip to content

Commit c7cd786

Browse files
committed
Fix receive missing initial bytes by blocking instead of polling
1 parent 06aeda0 commit c7cd786

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

umodbus/serial.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -242,32 +242,36 @@ def _send(self, modbus_pdu: bytes, slave_addr: int) -> None:
242242
"""
243243
Send Modbus frame via UART
244244
245-
If a flow control pin has been setup, it will be controller accordingly
245+
If a flow control pin has been setup, it will be controlled accordingly
246246
247247
:param modbus_pdu: The modbus Protocol Data Unit
248248
:type modbus_pdu: bytes
249249
:param slave_addr: The slave address
250250
:type slave_addr: int
251251
"""
252-
serial_pdu = bytearray()
253-
serial_pdu.append(slave_addr)
254-
serial_pdu.extend(modbus_pdu)
255-
256-
crc = self._calculate_crc16(serial_pdu)
257-
serial_pdu.extend(crc)
252+
# modbus_adu: Modbus Application Data Unit
253+
# consists of the Modbus PDU, with slave address prepended and checksum appended
254+
modbus_adu = bytearray()
255+
modbus_adu.append(slave_addr)
256+
modbus_adu.extend(modbus_pdu)
257+
modbus_adu.extend(self._calculate_crc16(modbus_adu))
258258

259259
if self._ctrlPin:
260-
self._ctrlPin(1)
260+
self._ctrlPin.on()
261261
time.sleep_us(1000) # wait until the control pin really changed
262-
send_start_time = time.ticks_us()
263262

264-
self._uart.write(serial_pdu)
263+
# the timing of this part is critical:
264+
# - if we disable output too early,
265+
# the command will not be received in full
266+
# - if we disable output too late,
267+
# the incoming response will lose some data at the beginning
268+
# easiest to just wait for the bytes to be sent out on the wire
269+
270+
self._uart.write(modbus_adu)
271+
self._uart.flush()
265272

266273
if self._ctrlPin:
267-
total_frame_time_us = self._t1char * len(serial_pdu)
268-
while time.ticks_us() <= send_start_time + total_frame_time_us:
269-
machine.idle()
270-
self._ctrlPin(0)
274+
self._ctrlPin.off()
271275

272276
def _send_receive(self,
273277
modbus_pdu: bytes,
@@ -286,7 +290,7 @@ def _send_receive(self,
286290
:returns: Validated response content
287291
:rtype: bytes
288292
"""
289-
# flush the Rx FIFO
293+
# flush the Rx FIFO buffer
290294
self._uart.read()
291295

292296
self._send(modbus_pdu=modbus_pdu, slave_addr=slave_addr)

0 commit comments

Comments
 (0)