1313from machine import Pin
1414import struct
1515import time
16- import machine
1716
1817# custom packages
1918from . import const as Const
@@ -96,6 +95,8 @@ def __init__(self,
9695 :param ctrl_pin: The control pin
9796 :type ctrl_pin: int
9897 """
98+ # UART flush function is introduced in Micropython v1.20.0
99+ self ._has_uart_flush = callable (getattr (UART , "flush" , None ))
99100 self ._uart = UART (uart_id ,
100101 baudrate = baudrate ,
101102 bits = data_bits ,
@@ -258,7 +259,9 @@ def _send(self, modbus_pdu: bytes, slave_addr: int) -> None:
258259
259260 if self ._ctrlPin :
260261 self ._ctrlPin .on ()
261- time .sleep_us (1000 ) # wait until the control pin really changed
262+ # wait until the control pin really changed
263+ # 85-95us (ESP32 @ 160/240MHz)
264+ time .sleep_us (200 )
262265
263266 # the timing of this part is critical:
264267 # - if we disable output too early,
@@ -267,8 +270,19 @@ def _send(self, modbus_pdu: bytes, slave_addr: int) -> None:
267270 # the incoming response will lose some data at the beginning
268271 # easiest to just wait for the bytes to be sent out on the wire
269272
273+ send_start_time = time .ticks_us ()
274+ # 360-400us @ 9600-115200 baud (measured) (ESP32 @ 160/240MHz)
270275 self ._uart .write (modbus_adu )
271- self ._uart .flush ()
276+ send_finish_time = time .ticks_us ()
277+ if self ._has_uart_flush :
278+ self ._uart .flush ()
279+ else :
280+ sleep_time_us = (
281+ self ._t1char * len (modbus_adu ) - # total frame time in us
282+ time .ticks_diff (send_finish_time , send_start_time ) +
283+ 100 # only required at baudrates above 57600, but hey 100us
284+ )
285+ time .sleep_us (sleep_time_us )
272286
273287 if self ._ctrlPin :
274288 self ._ctrlPin .off ()
0 commit comments