Open nickbedbury opened 5 years ago
modbus_tk should calculate a timeout for your baud rate thanks to utils.calculate_rtu_inter_char
. For baud rate below 19200, we return a fixed value of 0.0005 sec. I wonder if, it shouldn't rounded up to 0.0006 sec. Can you please give a try and check if it solves the problem?
You may also try to change that behavior by setting custom values to the interframe_multiplier
and the interchar_multiplier
args of the RtuServer constructor. By default, we have 3.5 and 1.5, but you can give the value you want.
I had tried with interchar_multiplier=2
and interframe_multiplier=5
but that didn't seem to be enough without the extra sleep I introduced.
Glad to find the same topic, as I was learning raspberry this days, and try to build up a remote slave client. While master send read holding register was fine, but send write multiple register even only 2 bytes alway cause slave invalid CRC requrest, something like(1, cst.WRITE_MULTIPLE_REGISTERS, 0, output_value = [ 1,2]). I tried the method from Ijean set interframe_multiplier = 20 ; interchar_multiplier = 5, then it works under baudrate = 9600. I did not stuy the logic behind for the 2 variables, this just for your reference.
It would be interesting to hear what kind of hardware you are using. For a USB serial port adapter, the USB host would typically poll the adapter for new data at 1000 Hz as far as I understand. Sub-ms timeouts don't really make sense in that situation.
I had this same problem. Increasing the interframe_multiplier
worked for me. I have a Modbus RTU slave with a baudrate of 9600 and increased the frame timeout multiplier to 8.
With a baud of 9600 I get a _t0
of 0.001145833333
from utils.calculate_rtu_inter_char
so a serial timeout of 0.009166666664
and a serial inter_byte_timeout of 0.001718749999
.
Looking at this old stackoverflow question and then the pyserial library, at lines like,
vtime = int(self._inter_byte_timeout * 10)
and
vtime = int(self._timeout * 10)
I am wondering how much of that precision gets captured.
Also how the calculation in utils.calculate_rtu_inter_char
was derived.
At the speed of 115200, the library was very unstable. I picked up different delays for packets of different sizes. I don't know why it works :)
if response:
if self._serial.in_waiting > 0:
# Most likely master timed out on this request and started a new one
# for which we already received atleast 1 byte
LOGGER.warning("Not sending response because there is new request pending")
else:
gpio.output(port.PG9, gpio.HIGH)
self._serial.write(response)
if len(response) > 20:
time.sleep(0.0037)
else:
time.sleep(0.0019)
self._serial.flush()
gpio.output(port.PG9, gpio.LOW)
time.sleep(self.get_timeout())
Hi all,
For what it's worth, I use this library in quite a few industrial applications and have had fantastic success even up to 2.5m baud (yes that said 2,500,000baud) using a wave share USB RS485 convertor and on some embedded devices we use.
If you can document this a bit further with easy to reproduce steps I'm happy to assign someone on our team the job to look into it further.
(we aren't affiliated with modbustk excluding 1 commit I've made but we have a major interest in this library working reliably and are keen to support.)
On Sun, Jun 13, 2021, 12:37 AM Dmitry @.***> wrote:
At the speed of 115200, the library was very unstable. I picked up different delays for packets of different sizes.
if response: if self._serial.in_waiting > 0: # Most likely master timed out on this request and started a new one # for which we already received atleast 1 byte LOGGER.warning("Not sending response because there is new request pending") else: gpio.output(port.PG9, gpio.HIGH) self._serial.write(response) if len(response) > 20: time.sleep(0.0037) else: time.sleep(0.0019) self._serial.flush() gpio.output(port.PG9, gpio.LOW) time.sleep(self.get_timeout())
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ljean/modbus-tk/issues/112#issuecomment-860062068, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHFD2JKPOTWZGEFCVVZHDHTTSNWKFANCNFSM4HMQ3NXA .
Hi all, For what it's worth, I use this library in quite a few industrial applications and have had fantastic success even up to 2.5m baud (yes that said 2,500,000baud) using a wave share USB RS485 convertor and on some embedded devices we use. If you can document this a bit further with easy to reproduce steps I'm happy to assign someone on our team the job to look into it further. (we aren't affiliated with modbustk excluding 1 commit I've made but we have a major interest in this library working reliably and are keen to support.) … On Sun, Jun 13, 2021, 12:37 AM Dmitry @.***> wrote: At the speed of 115200, the library was very unstable. I picked up different delays for packets of different sizes. if response: if self._serial.in_waiting > 0: # Most likely master timed out on this request and started a new one # for which we already received atleast 1 byte LOGGER.warning("Not sending response because there is new request pending") else: gpio.output(port.PG9, gpio.HIGH) self._serial.write(response) if len(response) > 20: time.sleep(0.0037) else: time.sleep(0.0019) self._serial.flush() gpio.output(port.PG9, gpio.LOW) time.sleep(self.get_timeout()) — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#112 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHFD2JKPOTWZGEFCVVZHDHTTSNWKFANCNFSM4HMQ3NXA .
I do not know if this can help others. I'm using an orange pi one with ADM1485ARZ. At the speed of 9600, everything worked well. At the speed of 115200, some packets were lost.
I've been having trouble getting an RTU serial slave to receive requests fully. The slave seems to cut messages partway, causing CRC and framing errors.
Adding a small delay in
modbus_rtu.py
after the 1st blocking read seems to help:In my scenario, the master/slave are using 9600 baud, so perhaps that's part of the issue. At faster baud rates, all the bytes would come in faster. I created the slave with code as follows: