-
Notifications
You must be signed in to change notification settings - Fork 957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Very slow performance #237
Comments
Could you provide some more details on the client being used (sync/async), baudrate used and any script you used to measure the performance ? |
Thank you for your quick answer. I use the sync client and server, a baudrate of 921600 and the Linux To measure the performance of |
@pallix Thanks, Are you doing a write coil/holding registers or a read operation ? Also when you say one mega byte of data ,are you reading it from the file ? would be helpful, if you could share your code snippet. |
Sorry that I did not provide the code sample directly. Server side: slave = ModbusSlaveContext()
context = ModbusServerContext(slaves=slave, single=True)
framer = ModbusRtuFramer
StartSerialServer(port=PORT,
baudrate=BAUDRATE,
parity=PARITY,
context=context,
framer=framer,
timeout=TIMEOUT) Client side: ONE_MEGA_BYTE = 1024**2
client = ModbusSerialClient(method='rtu',
port=PORT,
baudrate=BAUDRATE,
parity=PARITY,
timeout=TIMEOUT,
retries=1000)
client.connect()
nb_bytes_sent = 0
builder = BinaryPayloadBuilder(endian=Endian.Little)
while nb_bytes_sent < ONE_MEGA_BYTE:
builder.reset()
builder.add_32bit_float(1.0)
builder.add_32bit_float(2.0)
builder.add_32bit_float(3.0)
builder.add_32bit_float(4.0)
builder.add_32bit_float(5.0)
payload = builder.build()
client.write_registers(0, payload, skip_encode=True, unit=1)
nb_bytes_sent += 4 * 5 |
Sorry for the late reply, There are multiple problems resulting in the slow timings. To begin with , For some reason the WriteRegisters Request doesn't come with response pdu size, and hence pymodbus waits at reading the bus till timeout (it actually is looking to read 1024 bytes which is default when the response pdu size is not calculated), There is another check when the number of bytes received is less than the expected size (in case of partial response) it again waits till the complete read timeout expecting the rest of the packets. So there are two timeouts that is taking in here + compulsory 3.5char timeout per read/write operation) which is resulting in increased time + the retry count of 1000 in your code consumes some more time when no response is received. |
Thanks for the reply! We checked the C benchmark and it is using much more registers (121) whereas the Python version throws an error when trying to pack more data than in this example. Do you know why I cannot send more than 20 bytes at once? |
The max number of registers supported by pymodbus in one transaction is 125, not sure what you mean by you can not send more than 20 bytes at once ?? Could you please show us how are you trying to pack the data ? |
I pack the example as in the code above. When adding a line such as:
then an error is thrown when sending the data. |
Not sure how you are building here payload, I can read up to 122 registers in one shot with float and read 125 registers in one shot
And this is my response
|
Can you show me the code of the server? When using your example, I get an
Is it necessary to read the registers after writing? |
I am using the server from here Just in case you want to use the synchronous server from pymodbus, here is the modification you need to make
|
Thank you. I tried your code. Unfortunately, I still get either:
or the previous error when the argument to |
@pallix could you try with the latest on the |
I get the same result. |
I have no idea what could be going wrong, Could you please share your entire code (both server and client) |
Thank you. I asked for permission to post the code. Client:
Server:
requirements.txt:
|
I installed pymodbus with |
@pallix , the only change I did was to add Here is the changes.
|
That is very kind of you to test this. You did not get a |
Nope, I did not get any such error. Could you paste the logs when you get these error (both from server and client) . Jus to confirm , can you try on other systems/os? |
Also, Please give a try at lower baudrates first (say 9600, 19200, 38400) and see if that works at those rates. |
Client:
Server:
You are right, it works with a lower baudrate! |
@pallix thanks for the confirmation, Issues with the speed are hard to debug and fix across different OS.I would keep this at lower priority for the time being.You can choose to keep this issue open if you like. I will be closing this as of now. |
Thank you very much for your support. |
No Problem, You are welcome. |
@dhoomakethu , how do I get around this time out issue on writing on a coil? I´m just trying to tur a LED on and off on an Arduino and every time the program writes on the coil it gets struck until timeout and them proceeds. |
A lot of the modbus requests and even more responses come without a length, that is something we cannot change and have to live with. pymodbus do not wait until timeout but waits differently depending on the type of connection. For tcp it is simple, it do not wait, for serial it wait the time to transmit 3.5 char (which is calculated from the baudrate), this is again a protocol demand which we cannot avoid. It is correct the default length is 1024, but it is superseded by the 3.5 char wait and not the general timeout. If your assumption is correct we would (using defaults) only be able to do 1 WriteRegisters every 10 seconds. For the fun of it, I just wrote a WriteCoil loop, on my production system, which runs on a raspberry pi4 connected to a Huawei SUN 2000 solar inverter. The system was able to make 123 call / second, which I consider fast (considering the protocol). My production system is using v3.1.3. Which version are you testing with ? Also it would be nice to see a debug log, showing the real timing. |
@janiversen I´m also working on understanding the log file and how to make it work, will post here when I make it work Thanks sir! import serial
import time
import pymodbus
from pymodbus.client import ModbusSerialClient
client = ModbusSerialClient( port="/dev/ttyAMA0", baudrate=19200, method = "rtu", bytesize=8, parity="N", stopbits=1, unit=10)
while True:
client.write_coil(0x000D, 1)
time.sleep(1)
client.write_coil(0x000D, 0)
time.sleep(1)
|
Where do you see a performance problem ? you are sleeping 2 seconds in each loop, get rid of that. |
I'm sorry sir. I forgot to remove those lines before posting the program. |
I am not sure I can help you. I am surprised that you get any results at all, with the code you have presented, since you never connect to a server, furthermore it is good practice to specify the slave. You should also check what is returned from write_coil since it might return some useful error descriptions. Have a look at our examples, they show how to properly test the returns. |
got the log to work
|
You might have got the log to work, but did you read it ? You are not getting any response, so no wonder it is slow, the library waits timeout for a response to arrive. If you had checked what write_coil returns you would have seen that it failed. |
Versions
Description
I have timed the sending of one mega byte of data with modbus RTU and the transfer spead is approximatively 7 KB/s.
When using
libmodbus
with RTU, I got a 10x performance improvement.I have set the same baudrate in both cases.
This difference seems very strange to me and I wonder if a bug is hidding somewhere.
The text was updated successfully, but these errors were encountered: