Skip to content
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

Closed
pallix opened this issue Nov 7, 2017 · 33 comments
Closed

Very slow performance #237

pallix opened this issue Nov 7, 2017 · 33 comments

Comments

@pallix
Copy link

pallix commented Nov 7, 2017

Versions

  • Python: 2.7.6
  • OS: Ubuntu 14.04
  • Pymodbus: 1.3.2
  • Modbus Hardware (if used):

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.

@dhoomakethu
Copy link
Contributor

Could you provide some more details on the client being used (sync/async), baudrate used and any script you used to measure the performance ?

@pallix
Copy link
Author

pallix commented Nov 7, 2017

Thank you for your quick answer.

I use the sync client and server, a baudrate of 921600 and the Linux time command to measure performance of pymodbus.

To measure the performance of libmodbus, programs are provided by the library in the tests folder.

@dhoomakethu
Copy link
Contributor

@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.

@pallix
Copy link
Author

pallix commented Nov 8, 2017

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

@dhoomakethu
Copy link
Contributor

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.

@dhoomakethu dhoomakethu added this to the 1.4.0 milestone Nov 12, 2017
@dhoomakethu dhoomakethu mentioned this issue Nov 12, 2017
21 tasks
@pallix
Copy link
Author

pallix commented Nov 13, 2017

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?

@dhoomakethu
Copy link
Contributor

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 ?

@pallix
Copy link
Author

pallix commented Nov 13, 2017

I pack the example as in the code above. When adding a line such as:

builder.add_32bit_float(6.0)

then an error is thrown when sending the data.

@dhoomakethu
Copy link
Contributor

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

def make_payload(size):
    builder = BinaryPayloadBuilder(endian=Endian.Little)
    builder.reset()
    size = size//4
    val = 1.0
    for x in range(size):
        builder.add_32bit_float(val)
        val += 1.0
    payload = builder.build()
    return payload

def write_r(payload):
    return client.write_registers(0, payload, skip_encode=True, unit=1)

def read_r():
    return client.read_holding_registers(0, 125, unit=1)
start = time.time()
while nb_bytes_sent < ONE_MEGA_BYTE:
    r = write_r(make_payload(247))
    print(r)
    r = read_r()
    print(r)
    #
    nb_bytes_sent += 20
    break

And this is my response

DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:send: 0x1 0x10 0x0 0x0 0x0 0x7a 0xf4 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0 0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0 0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0 0x0 0xb8 0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0 0x0 0xf8 0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0 0x0 0x1c 0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0 0x0 0x3c 0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0 0x0 0x5c 0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x13 0xe7
DEBUG:pymodbus.client.sync:will sleep to wait for 3.5 char
DEBUG:pymodbus.transaction:recv: 0x1 0x10 0x0 0x0 0x0 0x7a 0x41 0xea
DEBUG:pymodbus.factory:Factory Response[16]
DEBUG:pymodbus.transaction:adding transaction 0
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.transaction:send: 0x1 0x3 0x0 0x0 0x0 0x7d 0x85 0xeb
WriteMultipleRegisterResponse (0,122)
DEBUG:pymodbus.client.sync:will sleep to wait for 3.5 char
ReadRegisterResponse (125)
DEBUG:pymodbus.transaction:recv: 0x1 0x3 0xfa 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0 0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0 0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0 0x0 0xb8 0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0 0x0 0xf8 0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0 0x0 0x1c 0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0 0x0 0x3c 0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0 0x0 0x5c 0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x0 0x1 0x0 0x1 0x0 0x1 0xe0 0x1e
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:adding transaction 0
DEBUG:pymodbus.transaction:getting transaction 2

@pallix
Copy link
Author

pallix commented Nov 13, 2017

Can you show me the code of the server? When using your example, I get an

ERROR:pymodbus.server.sync:Socket error occurred Modbus Error: [Invalid Message] <pymodbus.pdu.IllegalFunctionRequest object at 0x7fe60ac16e50>

Is it necessary to read the registers after writing?

@dhoomakethu
Copy link
Contributor

dhoomakethu commented Nov 13, 2017

I am using the server from here
https://github.com/riptideio/modbus-simulator

Just in case you want to use the synchronous server from pymodbus, here is the modification you need to make

store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [17]*255),
    co = ModbusSequentialDataBlock(0, [17]*255),
    hr = ModbusSequentialDataBlock(0, [17]*255),
    ir = ModbusSequentialDataBlock(0, [17]*255))
context = ModbusServerContext(slaves={1: store}, single=False)
``

@pallix
Copy link
Author

pallix commented Nov 14, 2017

Thank you. I tried your code. Unfortunately, I still get either:

Socket error occurred unpack requires a string argument of length 4

or the previous error when the argument to make_payload is 24 or smore.

@dhoomakethu
Copy link
Contributor

@pallix could you try with the latest on the dev branch?

@pallix
Copy link
Author

pallix commented Nov 14, 2017

I get the same result.

@dhoomakethu
Copy link
Contributor

dhoomakethu commented Nov 14, 2017

I have no idea what could be going wrong, Could you please share your entire code (both server and client)

@pallix
Copy link
Author

pallix commented Nov 14, 2017

Thank you. I asked for permission to post the code. Client:

#!/usr/bin/python

import argparse
import logging

from pymodbus.client.sync import ModbusSerialClient
from pymodbus.client.sync import ModbusTcpClient
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.constants import Endian
from pymodbus.exceptions import ModbusIOException

logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

ONE_MEGA_BYTE = 1024**2
PAYLOAD_SIZE = 20
REGISTERS_COUNT = 8 # 40000 # 65535
PORT = '/dev/ttyAP0'
BAUDRATE = 921600
PARITY = 'E'
TIMEOUT = 0.0

def dlog(msg):
    log.log(logging.DEBUG, msg)

def create_client(mode='rtu'):
    if(mode == 'rtu'):
        return ModbusSerialClient(method='rtu',
                                  port=PORT,
                                  baudrate=BAUDRATE,
                                  parity=PARITY,
                                  timeout=TIMEOUT,
                                  retries=1000)
    elif(mode == 'ascii'):
        return ModbusSerialClient(method='ascii',
                                  port=PORT,
                                  baudrate=BAUDRATE,
                                  parity=PARITY,
                                  timeout=TIMEOUT,
                                  retries=1000)
    elif(mode == 'tcp'):
        return ModbusTcpClient(port=9000)
    else:
        raise ValueError('Invalid argument ' + mode)

def make_payload(size):
    builder = BinaryPayloadBuilder(endian=Endian.Little)
    builder.reset()
    size = size//4
    val = 1.0
    for x in range(size):
        builder.add_32bit_float(val)
        val += 1.0
    payload = builder.build()
    return payload

PAYLOAD_SIZE = 120

def test_performance(mode='rtu'):
    with create_client(mode) as client:
        dlog('connect')
        client.connect()
        nb_bytes_sent = 0
        while nb_bytes_sent < ONE_MEGA_BYTE:
            address = 0
            payload = make_payload(PAYLOAD_SIZE)
            rq = client.write_registers(address, payload, skip_encode=True, unit=1)
            if isinstance(rq, ModbusIOException):
                raise rq
            #            client.read_holding_registers(0, 125, unit=1)
            nb_bytes_sent += PAYLOAD_SIZE
            print 'nb_bytes_sent ',
            print nb_bytes_sent
        client.close()

def parse_arguments():
    parser = argparse.ArgumentParser(description="Mobus benchmark")
    parser.add_argument('--mode',
                        dest='mode',
                        action='store',
                        default='rtu',
                        help="communication mode: rtu (default), ascii or tcp"
                        )
    args = parser.parse_args()
    return args

if __name__ == '__main__':
    args = parse_arguments()
    test_performance(mode=args.mode)

Server:

#!/usr/bin/python

import argparse
import logging

from pymodbus.server.sync import StartSerialServer
from pymodbus.server.sync import StartTcpServer
from pymodbus.datastore import *
from pymodbus.transaction import *
from pymodbus.factory import ServerDecoder

PORT = '/dev/ttyAP1'
BAUDRATE = 921600
PARITY = 'E'
TIMEOUT = 0.0

def setup_logging():
    logging.basiconfig()
    log = logging.getLogger()
    log.setLevel(logging.DEBUG)

def get_context():
    store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [17]*255),
    co = ModbusSequentialDataBlock(0, [17]*255),
    hr = ModbusSequentialDataBlock(0, [17]*255),
    ir = ModbusSequentialDataBlock(0, [17]*255))
    context = ModbusServerContext(slaves={1: store}, single=False)
    return context

def start_server(mode='rtu'):
    context = get_context()
    if(mode == 'rtu'):
        framer = ModbusRtuFramer
        StartSerialServer(port=PORT,
                          baudrate=BAUDRATE,
                          parity=PARITY,
                          context=context,
                          framer=framer,
                          timeout=TIMEOUT)
    elif(mode == 'ascii'):
        framer = ModbusAsciiFramer
        StartSerialServer(port=PORT,
                          baudrate=BAUDRATE,
                          parity=PARITY,
                          context=context,
                          framer=framer,
                          timeout=TIMEOUT)
    elif(mode == 'tcp'):
        StartTcpServer(context,
                       address=('localhost',9000),
                       handler=handler
        )
    else:
        raise ValueError('Invalid argument' + mode)

def handler(*args):
    print 'received ' + args

def parse_arguments():
    parser = argparse.ArgumentParser(description="Mobus benchmark")
    parser.add_argument('--mode',
                        dest='mode',
                        action='store',
                        default='rtu',
                        help="communication mode: rtu (default), ascii or tcp"
                        )
    args = parser.parse_args()
    return args

if __name__ == '__main__':
    args = parse_arguments()
    setup_logging()
    start_server(mode=args.mode)

requirements.txt:

Automat==0.6.0
Landscape-Client==14.12
PAM==0.4.2
Twisted==17.9.0
Twisted-Core==13.2.0
apt-xapian-index==0.45
argparse==1.2.1
asn1crypto==0.23.0
attrs==17.2.0
cffi==1.11.2
chardet==2.0.1
colorama==0.2.5
configobj==4.7.2
constantly==15.1.0
cryptography==2.1.2
enum==0.4.6
enum34==1.1.6
html5lib==0.999
hyperlink==17.3.1
idna==2.6
incremental==17.5.0
ipaddress==1.0.18
pyOpenSSL==0.15.1
pyasn1==0.3.7
pyasn1-modules==0.1.5
pycparser==2.18

# pymodbus==1.3.2
pyserial==3.4
python-apt===0.9.3.5ubuntu2
python-debian===0.1.21-nmu2ubuntu2
requests==2.2.1
service-identity==17.0.0
six==1.11.0
ssh-import-id==3.21
urllib3==1.7.1
wheel==0.24.0
wsgiref==0.1.2
zope.interface==4.4.3

@pallix
Copy link
Author

pallix commented Nov 14, 2017

I installed pymodbus with pip install --user --upgrade git+https://github.com/riptideio/pymodbus.git@dev

@dhoomakethu
Copy link
Contributor

@pallix , the only change I did was to add retry_on_empty=True in the client initialisation and I could get your code working with out any problem, note I am running this on Mac OSX high sierra with dummy serial ports (/dev/ttyp0 for server and /dev/ptpy0 for client). Also I am using PAYLOAD_SIZE = 250 instead of 120 for RTU but sticked to 120 for ascii. I could get the 1 MB transaction in approximately 12 seconds for modbus rtu and around 15 seconds for ascii at the max baudrate supported 230400 (I have tried 9600, 19200, 38400, , 57600, 115200). I will try it on a ubuntu machine and update.

Here is the changes.

def create_client(mode='rtu'):
    if(mode == 'rtu'):
        return ModbusSerialClient(method='rtu',
                                  port=PORT,
                                  baudrate=BAUDRATE,
                                  parity=PARITY,
                                  timeout=TIMEOUT,
                                  # write_timeout=WRITE_TIMEOUT,
                                  retries=1000,
                                  retry_on_empty=True
                                  )
    elif(mode == 'ascii'):
        return ModbusSerialClient(method='ascii',
                                  port=PORT,
                                  baudrate=BAUDRATE,
                                  parity=PARITY,
                                  timeout=TIMEOUT,
                                  retries=1000,
                                  retry_on_empty=True)
    elif(mode == 'tcp'):
        return ModbusTcpClient(port=9000)

@pallix
Copy link
Author

pallix commented Nov 14, 2017

That is very kind of you to test this.

You did not get a Socket error occurred unpack requires a string argument of length 4 on the server side? I tried adding retry_on_empty=True, still get the error.

@dhoomakethu
Copy link
Contributor

dhoomakethu commented Nov 14, 2017

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?

@dhoomakethu
Copy link
Contributor

Also, Please give a try at lower baudrates first (say 9600, 19200, 38400) and see if that works at those rates.

@pallix
Copy link
Author

pallix commented Nov 14, 2017

Client:

DEBUG:pymodbus.transaction:send: 0x1 0x10 0x0 0x0 0x0 0x7c 0xf8 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0 0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0 0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0 0x0 0xb8 0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0 0x0 0xf8 0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0 0x0 0x1c 0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0 0x0 0x3c 0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0 0x0 0x5c 0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x0 0x0 0x78 0x42 0x4a 0x72
DEBUG:pymodbus.client.sync:will sleep to wait for 3.5 char
DEBUG:pymodbus.transaction:send: 0x1 0x10 0x0 0x0 0x0 0x7c 0xf8 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0 0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0 0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0 0x0 0xb8 0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0 0x0 0xf8 0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0 0x0 0x1c 0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0 0x0 0x3c 0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0 0x0 0x5c 0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x0 0x0 0x78 0x42 0x4a 0x72
DEBUG:pymodbus.client.sync:will sleep to wait for 3.5 char
DEBUG:pymodbus.transaction:send: 0x1 0x10 0x0 0x0 0x0 0x7c 0xf8 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0 0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0 0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0 0x0 0xb8 0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0 0x0 0xf8 0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0 0x0 0x1c 0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0 0x0 0x3c 0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0 0x0 0x5c 0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x0 0x0 0x78 0x42 0x4a 0x72
[...]
DEBUG:pymodbus.client.sync:will sleep to wait for 3.5 char
DEBUG:pymodbus.transaction:send: 0x1 0x10 0x0 0x0 0x0 0x7c 0xf8 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0 0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0 0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0 0x0 0xb8 0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0 0x0 0xf8 0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0 0x0 0x1c 0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0 0x0 0x3c 0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0 0x0 0x5c 0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x0 0x0 0x78 0x42 0x4a 0x72
DEBUG:pymodbus.client.sync:will sleep to wait for 3.5 char
DEBUG:pymodbus.transaction:getting transaction 1
Traceback (most recent call last):
  File "./modbus_client.py", line 91, in <module>
    test_performance(mode=args.mode)
  File "./modbus_client.py", line 71, in test_performance
    raise rq
pymodbus.exceptions.ModbusIOException: Modbus Error: [Input/Output] No Response received from the remote unit

Server:

DEBUG:pymodbus.server.sync:Client Connected [/dev/ttyAP1:/dev/ttyAP1]
DEBUG:pymodbus.server.sync:Started thread to serve client
DEBUG:pymodbus.server.sync:0x1 0x10 0x0 0x0 0x0 0x7c 0xf8 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0
DEBUG:pymodbus.factory:Factory Request[1]
ERROR:pymodbus.server.sync:Socket error occurred unpack requires a string argument of length 4
DEBUG:pymodbus.server.sync:0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0
DEBUG:pymodbus.server.sync:0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0 0x0 0xb8
DEBUG:pymodbus.server.sync:0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0 0x0 0xf8
DEBUG:pymodbus.server.sync:0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0 0x0 0x1c
DEBUG:pymodbus.server.sync:0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0 0x0 0x3c
DEBUG:pymodbus.server.sync:0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0 0x0 0x5c
DEBUG:pymodbus.server.sync:0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x0 0x0 0x78 0x42 0x4a 0x72
DEBUG:pymodbus.server.sync:0x1 0x10 0x0 0x0 0x0 0x7c 0xf8 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0
DEBUG:pymodbus.factory:Factory Request[1]
ERROR:pymodbus.server.sync:Socket error occurred unpack requires a string argument of length 4
DEBUG:pymodbus.server.sync:0x0 0xe0 0x40 0x0 0x0 0x0 0x41 0x0 0x0 0x10 0x41 0x0 0x0 0x20 0x41 0x0 0x0 0x30 0x41 0x0 0x0 0x40 0x41 0x0 0x0 0x50 0x41 0x0 0x0 0x60 0x41 0x0
DEBUG:pymodbus.server.sync:0x0 0x70 0x41 0x0 0x0 0x80 0x41 0x0 0x0 0x88 0x41 0x0 0x0 0x90 0x41 0x0 0x0 0x98 0x41 0x0 0x0 0xa0 0x41 0x0 0x0 0xa8 0x41 0x0 0x0 0xb0 0x41 0x0
DEBUG:pymodbus.server.sync:0x0 0xb8 0x41 0x0 0x0 0xc0 0x41 0x0 0x0 0xc8 0x41 0x0 0x0 0xd0 0x41 0x0 0x0 0xd8 0x41 0x0 0x0 0xe0 0x41 0x0 0x0 0xe8 0x41 0x0 0x0 0xf0 0x41 0x0
DEBUG:pymodbus.server.sync:0x0 0xf8 0x41 0x0 0x0 0x0 0x42 0x0 0x0 0x4 0x42 0x0 0x0 0x8 0x42 0x0 0x0 0xc 0x42 0x0 0x0 0x10 0x42 0x0 0x0 0x14 0x42 0x0 0x0 0x18 0x42 0x0
DEBUG:pymodbus.server.sync:0x0 0x1c 0x42 0x0 0x0 0x20 0x42 0x0 0x0 0x24 0x42 0x0 0x0 0x28 0x42 0x0 0x0 0x2c 0x42 0x0 0x0 0x30 0x42 0x0 0x0 0x34 0x42 0x0 0x0 0x38 0x42 0x0
DEBUG:pymodbus.server.sync:0x0 0x3c 0x42 0x0 0x0 0x40 0x42 0x0 0x0 0x44 0x42 0x0 0x0 0x48 0x42 0x0 0x0 0x4c 0x42 0x0 0x0 0x50 0x42 0x0 0x0 0x54 0x42 0x0 0x0 0x58 0x42 0x0
DEBUG:pymodbus.server.sync:0x0 0x5c 0x42 0x0 0x0 0x60 0x42 0x0 0x0 0x64 0x42 0x0 0x0 0x68 0x42 0x0 0x0 0x6c 0x42 0x0 0x0 0x70 0x42 0x0 0x0 0x74 0x42 0x0 0x0 0x78 0x42 0x4a
DEBUG:pymodbus.server.sync:0x72
DEBUG:pymodbus.server.sync:0x1 0x10 0x0 0x0 0x0 0x7c 0xf8 0x0 0x0 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xc0 0x40 0x0
DEBUG:pymodbus.factory:Factory Request[1]
[...]

You are right, it works with a lower baudrate!

@dhoomakethu
Copy link
Contributor

@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.

@pallix
Copy link
Author

pallix commented Nov 14, 2017

Thank you very much for your support.

@dhoomakethu
Copy link
Contributor

No Problem, You are welcome.

@guigfort
Copy link

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.

@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.

@janiversen
Copy link
Collaborator

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.

@guigfort
Copy link

guigfort commented Mar 17, 2023

@janiversen
This is the code that I´m using just trying to understand how the python and modbus communication works. it is running on a raspberry pi CM4 on a waveshare CM4-ETH-RS485-BASE-B board (I also used a regular RPI 4). my slave device is an arduino running with code also bellow (´m sorry the code is messy but I did not wrote my own yet)

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)
Arduino code

``` //Testato con QModMaster
//https://github.com/yaacov/ArduinoModbusSlave

#include <ModbusSlave.h>


Modbus slave(Serial1, 1, 2);

void setup() {
    // RS485 control pin must be output
  pinMode(2, OUTPUT);

  pinMode(13, OUTPUT);  //LED // Alterado da porta 12 para porta 13
  pinMode(5, INPUT);    //Button

  
    /* register handler functions.
     * into the modbus slave callback vector.
     */
    slave.cbVector[CB_READ_COILS] = readDigital;
    slave.cbVector[CB_READ_DISCRETE_INPUTS] = readDigital;
    slave.cbVector[CB_WRITE_COILS] = writeDigitalOut;
    slave.cbVector[CB_READ_INPUT_REGISTERS] = readAnalogIn;
    slave.cbVector[CB_WRITE_HOLDING_REGISTERS] = writeRegister;
    
    // set Serial and slave at baud 19200.
    Serial.begin( 19200 );
    Serial1.begin(19200); 
    slave.begin( 19200 );
}

void loop() {
    /* listen for modbus commands con serial port.
     *
     * on a request, handle the request.
     * if the request has a user handler function registered in cbVector.
     * call the user handler function.
     */ 
    slave.poll();
}

/**
 * Handle Write Holding Register(s) (FC=06, FC=16)
 * write data into eeprom.
 */
uint8_t writeRegister(uint8_t fc, uint16_t address, uint16_t length) {
    uint16_t value;
    uint16_t registerIndex;
    Serial.print("FC=06/16: ");
  Serial.println(fc);
  Serial.println(address);
  Serial.println(length);

    
    for (int i = 0; i < length; i++) {
        // get uint16_t value from the request buffer.
        value = slave.readRegisterFromBuffer(i);
        Serial.println(value);
        analogWrite(6, value);
        
    }

    return STATUS_OK;
}


/**
 * Handel Read Input Registers (FC=04)
 * write back the values from analog in pins (input registers).
 */
uint8_t readAnalogIn(uint8_t fc, uint16_t address, uint16_t length) {
  Serial.print("FC=04: ");
  Serial.println(fc);
  Serial.println(address);
  Serial.println(length);
    // read analog input
    for (int i = 0; i < length; i++) {
        // write uint16_t value to the response buffer.
        slave.writeRegisterToBuffer(i, analogRead(A0));
    }
    return STATUS_OK;
}


/**
 * Handle Read Input Status (FC=01/02)
 * write back the values from digital pins (input status).
 *
 * handler functions must return void and take:
 *      uint8_t  fc - function code.
 *      uint16_t address - first register/coil address.
 *      uint16_t length/status - length of data / coil status.
 */
uint8_t readDigital(uint8_t fc, uint16_t address, uint16_t length) {
  Serial.print("FC=01/02: ");
  Serial.println(fc);
  Serial.println(address);
  Serial.println(length);

    // read digital input
    for (int i = 0; i < length; i++) {
        // write one boolean (1 bit) to the response buffer.
        int bt = 0;
        if (i == 0) bt = digitalRead(5);
        slave.writeCoilToBuffer(i, bt);
    }

    return STATUS_OK;
}

/**
 * Handle Force Single Coil (FC=05) and Force Multiple Coils (FC=15)
 * set digital output pins (coils).
 */
uint8_t writeDigitalOut(uint8_t fc, uint16_t address, uint16_t length) {
  Serial.print("FC=05: ");
  Serial.println(fc);
  Serial.println(address);
  Serial.println(length);
  Serial.println(slave.readCoilFromBuffer(0));
  
  if (address == 13) {
    digitalWrite(13, slave.readCoilFromBuffer(0));

  }

    return STATUS_OK;
}

@janiversen
Copy link
Collaborator

Where do you see a performance problem ? you are sleeping 2 seconds in each loop, get rid of that.

@guigfort
Copy link

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.
Even without the sleep times it takes around 3 to 4 seconds to change between the writing commands.
The arduino takes the data right away, but the python is still stuck for a few seconds before moving to the next line.
I tested adding a time out of 0.1 just for testing and afther that it moves fast. But I don't know if that would be the right thing to do. Because the way I see the timeout should give me a red flag of communication loss.

@janiversen
Copy link
Collaborator

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.

@guigfort
Copy link

got the log to work
here is what I have

DEBUG|2023-03-19 00:15:05,131|Current transaction state - IDLE
DEBUG|2023-03-19 00:15:05,131|Running transaction 1
DEBUG|2023-03-19 00:15:05,132|SEND: 0x0 0x5 0x0 0xd 0xff 0x0 0x1c 0x28
DEBUG|2023-03-19 00:15:05,132|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:05,132|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:15:11,148|Transaction failed. (Modbus Error: [Invalid Message] No response received, expected at least 4 bytes (0 received)) 
DEBUG|2023-03-19 00:15:11,149|Frame - [b''] not ready
DEBUG|2023-03-19 00:15:11,149|Getting transaction 0
DEBUG|2023-03-19 00:15:11,149|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:15:12,153|Current transaction state - TRANSACTION_COMPLETE
DEBUG|2023-03-19 00:15:12,153|Running transaction 2
DEBUG|2023-03-19 00:15:12,154|SEND: 0x0 0x5 0x0 0xd 0x0 0x0 0x5d 0xd8
DEBUG|2023-03-19 00:15:12,154|Changing state to IDLE - Last Frame End - None Current Time stamp - 1679199312.154304
DEBUG|2023-03-19 00:15:12,156|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:12,157|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:15:18,171|No response received, Expected 8 bytes Received 0 bytes !!!!
DEBUG|2023-03-19 00:15:18,172|Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG|2023-03-19 00:15:18,172|RECV: 
DEBUG|2023-03-19 00:15:18,173|Frame - [b''] not ready
DEBUG|2023-03-19 00:15:18,174|Getting transaction 0
DEBUG|2023-03-19 00:15:18,174|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:15:19,177|Current transaction state - TRANSACTION_COMPLETE
DEBUG|2023-03-19 00:15:19,178|Running transaction 3
DEBUG|2023-03-19 00:15:19,179|SEND: 0x0 0x5 0x0 0xd 0xff 0x0 0x1c 0x28
DEBUG|2023-03-19 00:15:19,179|Changing state to IDLE - Last Frame End - None Current Time stamp - 1679199319.179343
DEBUG|2023-03-19 00:15:19,181|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:19,182|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:15:25,197|No response received, Expected 8 bytes Received 0 bytes !!!!
DEBUG|2023-03-19 00:15:25,197|Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG|2023-03-19 00:15:25,198|RECV: 
DEBUG|2023-03-19 00:15:25,198|Frame - [b''] not ready
DEBUG|2023-03-19 00:15:25,198|Getting transaction 0
DEBUG|2023-03-19 00:15:25,199|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:15:26,202|Current transaction state - TRANSACTION_COMPLETE
DEBUG|2023-03-19 00:15:26,203|Running transaction 4
DEBUG|2023-03-19 00:15:26,203|SEND: 0x0 0x5 0x0 0xd 0x0 0x0 0x5d 0xd8
DEBUG|2023-03-19 00:15:26,204|Changing state to IDLE - Last Frame End - None Current Time stamp - 1679199326.204105
DEBUG|2023-03-19 00:15:26,206|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:26,207|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:15:32,221|No response received, Expected 8 bytes Received 0 bytes !!!!
DEBUG|2023-03-19 00:15:32,221|Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG|2023-03-19 00:15:32,222|RECV: 
DEBUG|2023-03-19 00:15:32,222|Frame - [b''] not ready
DEBUG|2023-03-19 00:15:32,223|Getting transaction 0
DEBUG|2023-03-19 00:15:32,223|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:15:33,226|Current transaction state - TRANSACTION_COMPLETE
DEBUG|2023-03-19 00:15:33,227|Running transaction 5
DEBUG|2023-03-19 00:15:33,227|SEND: 0x0 0x5 0x0 0xd 0xff 0x0 0x1c 0x28
DEBUG|2023-03-19 00:15:33,228|Changing state to IDLE - Last Frame End - None Current Time stamp - 1679199333.228218
DEBUG|2023-03-19 00:15:33,230|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:33,231|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:15:39,244|No response received, Expected 8 bytes Received 0 bytes !!!!
DEBUG|2023-03-19 00:15:39,245|Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG|2023-03-19 00:15:39,245|RECV: 
DEBUG|2023-03-19 00:15:39,246|Frame - [b''] not ready
DEBUG|2023-03-19 00:15:39,246|Getting transaction 0
DEBUG|2023-03-19 00:15:39,247|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:15:40,250|Current transaction state - TRANSACTION_COMPLETE
DEBUG|2023-03-19 00:15:40,250|Running transaction 6
DEBUG|2023-03-19 00:15:40,251|SEND: 0x0 0x5 0x0 0xd 0x0 0x0 0x5d 0xd8
DEBUG|2023-03-19 00:15:40,251|Changing state to IDLE - Last Frame End - None Current Time stamp - 1679199340.251634
DEBUG|2023-03-19 00:15:40,254|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:40,254|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:15:46,269|No response received, Expected 8 bytes Received 0 bytes !!!!
DEBUG|2023-03-19 00:15:46,269|Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG|2023-03-19 00:15:46,270|RECV: 
DEBUG|2023-03-19 00:15:46,270|Frame - [b''] not ready
DEBUG|2023-03-19 00:15:46,270|Getting transaction 0
DEBUG|2023-03-19 00:15:46,271|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:15:47,274|Current transaction state - TRANSACTION_COMPLETE
DEBUG|2023-03-19 00:15:47,275|Running transaction 7
DEBUG|2023-03-19 00:15:47,275|SEND: 0x0 0x5 0x0 0xd 0xff 0x0 0x1c 0x28
DEBUG|2023-03-19 00:15:47,276|Changing state to IDLE - Last Frame End - None Current Time stamp - 1679199347.276296
DEBUG|2023-03-19 00:15:47,278|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:47,279|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:15:53,294|No response received, Expected 8 bytes Received 0 bytes !!!!
DEBUG|2023-03-19 00:15:53,295|Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG|2023-03-19 00:15:53,295|RECV: 
DEBUG|2023-03-19 00:15:53,295|Frame - [b''] not ready
DEBUG|2023-03-19 00:15:53,296|Getting transaction 0
DEBUG|2023-03-19 00:15:53,297|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:15:54,300|Current transaction state - TRANSACTION_COMPLETE
DEBUG|2023-03-19 00:15:54,300|Running transaction 8
DEBUG|2023-03-19 00:15:54,301|SEND: 0x0 0x5 0x0 0xd 0x0 0x0 0x5d 0xd8
DEBUG|2023-03-19 00:15:54,301|Changing state to IDLE - Last Frame End - None Current Time stamp - 1679199354.301449
DEBUG|2023-03-19 00:15:54,303|New Transaction state "SENDING"
DEBUG|2023-03-19 00:15:54,304|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:16:00,318|No response received, Expected 8 bytes Received 0 bytes !!!!
DEBUG|2023-03-19 00:16:00,319|Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG|2023-03-19 00:16:00,319|RECV: 
DEBUG|2023-03-19 00:16:00,320|Frame - [b''] not ready
DEBUG|2023-03-19 00:16:00,320|Getting transaction 0
DEBUG|2023-03-19 00:16:00,321|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
DEBUG|2023-03-19 00:16:01,351|connect
DEBUG|2023-03-19 00:16:01,353|Current transaction state - IDLE
DEBUG|2023-03-19 00:16:01,353|Running transaction 1
DEBUG|2023-03-19 00:16:01,354|SEND: 0x0 0x10 0x0 0x0 0x0 0xa 0x14 0x80 0x3f 0x0 0x0 0x0 0x40 0x0 0x0 0x40 0x40 0x0 0x0 0x80 0x40 0x0 0x0 0xa0 0x40 0x0 0x0 0xf7 0xd
DEBUG|2023-03-19 00:16:01,354|New Transaction state "SENDING"
DEBUG|2023-03-19 00:16:01,354|Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG|2023-03-19 00:16:07,369|Transaction failed. (Modbus Error: [Invalid Message] No response received, expected at least 4 bytes (0 received)) 
DEBUG|2023-03-19 00:16:07,370|Frame - [b''] not ready
DEBUG|2023-03-19 00:16:07,370|Getting transaction 0
DEBUG|2023-03-19 00:16:07,371|Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"

@janiversen
Copy link
Collaborator

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants