简体   繁体   中英

PyModbus failing to read input registers in RTU Over TCP

I tried to read Modbus signal using pymodbus but got error The source is as follows:
There is a MAC address notification function when the server responds to TCP. How can Modbus communication be possible without error? How do I remove the TCP header part?

在此处输入图片说明

The manual is the address below:https://www.eztcp.com/en/download/pds_files/an_ezmanager_en.pdf

from pymodbus.client.sync import ModbusTcpClient
from pymodbus.transaction import ModbusRtuFramer as ModbusFramer
import time

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

def run_read_data(ip, port_num, unit_num):
    while True:
        client = ModbusTcpClient(ip, port=port_num, framer=ModbusFramer)
        con = client.connect()
        while con :
            rr = client.read_input_registers(0,10, unit=unit_num)        
            try:
                print(rr,rr.registers)

            except Exception as e:
                print(f"{type(e).__name__}: {e}")
  
                time.sleep(2)
                client.close()
                time.sleep(2)
                break
            time.sleep(1)
        time.sleep(1)

if __name__ == "__main__":
    ip = "x.x.x.x" 
    port_num = x
    unit_num = 0x1
    run_read_data(ip, port_num,unit_num)

and the result is this:

DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x18 0x4 0x0 0x0 0x0 0xa 0x72 0x4
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x30 0x30 0x33 0x30 0x66 0x39 0x31 0x31 0x34 0x30 0x38 0x35 0xd 0xa 0x18 0x4 0x14 0xe8 0xf9 0x2 0x45 0xf3 0x88 0x1 0x22
DEBUG:pymodbus.framer.rtu_framer:CRC invalid, discarding header!!
DEBUG:pymodbus.framer.rtu_framer:Resetting frame - Current Frame in buffer - 0x30 0x30 0x33 0x30 0x66 0x39 0x31 0x31 0x34 0x30 0x38 0x35 0xd 0xa 0x18 0x4 0x14 0xe8 0xf9 0x2 0x45 0xf3 0x88 0x1 0x22
DEBUG:pymodbus.framer.rtu_framer:Frame check failed, ignoring!!
DEBUG:pymodbus.framer.rtu_framer:Resetting frame - Current Frame in buffer -
DEBUG:pymodbus.transaction:Getting transaction 24
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
AttributeError: 'ModbusIOException' object has no attribute 'registers'
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x18 0x4 0x0 0x0 0x0 0xa 0x72 0x4
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x30 0x30 0x33 0x30 0x66 0x39 0x31 0x31 0x34 0x30 0x38 0x35 0xd 0xa 0x18 0x4 0x14 0xe9 0x9f 0x2 0x45 0xf3 0xd5 0x1 0x22
DEBUG:pymodbus.framer.rtu_framer:CRC invalid, discarding header!!
DEBUG:pymodbus.framer.rtu_framer:Resetting frame - Current Frame in buffer - 0x30 0x30 0x33 0x30 0x66 0x39 0x31 0x31 0x34 0x30 0x38 0x35 0xd 0xa 0x18 0x4 0x14 0xe9 0x9f 0x2 0x45 0xf3 0xd5 0x1 0x22
DEBUG:pymodbus.framer.rtu_framer:Frame check failed, ignoring!!
DEBUG:pymodbus.framer.rtu_framer:Resetting frame - Current Frame in buffer -
DEBUG:pymodbus.transaction:Getting transaction 24
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
AttributeError: 'ModbusIOException' object has no attribute 'registers'

The message you are getting is invalid, you can see that CRC check failed - the problem is with modbusTCP server. Because of that response has no atribute registers what causes an exception. However, if you want to see what error looks like, you should print rr without anything else.

Good way to check if there was an error is to use isError() methond:

if rr.isError():
    # handle error
else:
    # proceed with response

If you're trying to decode message you should use BinaryPayloadDecoder as follows:

decoder = BinaryPaloadDecoder.fromRegisters(rr.registers)
value = decoder.decode_32bit_float()

Full reference here .

Unfortunately, I don't know what you mean by "How do I remove the TCP header part".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM