2

I am connecting a Modbus gateway to an RTU acquisition system. I am using a MOXA Gateway MB3480 with a RS485 (2 wires) connector. The thing is that I can't read the data all the time; I receive a time-out error.

My settings:

  • Port in RTU slave mode, baudrate 9600, parity none. I have tried it with and without a resistor in the bus.

enter image description here

What I have tried:

  • Request data with QModMaster, most of the times the result is: time-out error.
  • Request data with Python. Same result. Code:
from pymodbus.pdu import ModbusRequest
from pyModbusTCP.client import ModbusClient
import time

c = ModbusClient(host="192.168.88.4", port=502, unit_id=2, auto_open=True, auto_close=True)

while True:
    try: 
        regs = c.read_holding_registers(6, 1)
        b = regs[0]/1000.0
        a = round((b-4)/0.16,2)
        print(a)
    except:
        print("Read error")
    time.sleep(3)
  • I have tried an USB adapter and with a Raspberry Pi running Modbus RTU, it works; I can read the data. After changing the wires to the Moxa's gate, it only works sometimes. I have got the GND signal connected too.

  • I have tried sniffing the traffic with Traffic Monitor from Mgate Manager. I can see illegal packet (CRC) in the comments.

enter image description here

enter image description here

  • I have tried updating the firmware.

Where can the problem come from?

jonathanjo
  • 12,049
  • 3
  • 27
  • 60
  • Could you post a little diagram or photo of the connections? it's not clear how the computer is connected to the Moxa and whether you're trying to read the Moxa or something downstream from there. Also: please include the initialisation portion of the python code. Thanks :-) – jonathanjo Nov 24 '22 at 13:11
  • What part of the question is about electrical engineering? And is there even a question, you just say you are getting errors and what have you tried. Aren't you just trying to use a gateway device with some programs and Python module and it does not work, while a makeshift Rpi Rs485 device works? What if the device is broken so it does not work? – Justme Nov 24 '22 at 13:34
  • @Justme I think industrial buses, RS485, acquisition boards and sensor reading is quite about electrical engineering ;) The gateways must be ok. I have got three different new units from the same MOXA series. – Developing Electronics Nov 24 '22 at 13:59
  • @jonathanjo I have edited the question. Done. Thanks! – Developing Electronics Nov 24 '22 at 13:59
  • I tried your Python against some Modbus/TCP devices I have and it works fine. There does appear to be an RTU CRC error in your 02 03 02 1c c0 **34 c0** (I make it f4 d4), though 64 38 appears correct. Coule you elaborate on what that is supposed to be monitoring?) e4 80 appears wrong too, I make it fc 44. See [modbus 1.2](https://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf) s6.2.2. – jonathanjo Nov 24 '22 at 15:31
  • My suggestion would be to snoop the serial and see if you get the same thing when you connect directly to RTU as when over MB/TCP -> Moxa -> RTU. – jonathanjo Nov 24 '22 at 16:27
  • Please show whole conversation as depicted in the table picture, with timing. What is `00 03 00 00 00 06 ...`? May it happen that two (or more) devices start talking at the same time and you see the garbage? (that's why I ask for timing) – Anonymous Nov 24 '22 at 19:06
  • @jonathanjo The device is monitoring one SENECA device (https://www.seneca.it/es/linee-di-prodotto/acquisizione-dati-e-automazione/sistemi-io-modbus-rtu/moduli-io-analogici/z-8ai/) with 4-20 mA sensor connected to that acquisition system. – Developing Electronics Nov 25 '22 at 07:33

1 Answers1

4

From your table:

enter image description here

It looks as we'd expect for a gateway: it receives a modbus request on its MB/TCP side, and relays it out on its MB/RTU side.

The message 02 03 00 06 00 01 is slave=2, func=read_holding_registers, start=6, quantity=1. 64 38 is the correct CRC.

However the reply has the problem. The message 02 03 02 10 1c itself looks sensible: client=2 (as expected), func=read-holding-registers-without-error (as expected), bytecount=2 (as expected), bytes=10 1c (are these good?). The CRC is received as 64 7c but it should be f0 4d according to calculation (see later for detail).

As the CRC is incorrect, the receiver (the gateway) discards it. The transmitter considers this transaction complete, and doesn't resend. In due course the receiver (gateway) or client PC times out and generates the error.

Questions

  1. Do you have any RTU messages at all which the gateway accepted without bad CRC? (You say it works "sometimes": can we see the monitor table of a message which had no CRC error?)
  2. Is 0x10, 0x1c a reasonable response from the far unit for holding reg 6?
  3. I am suspecting the serial line. Do you have any way to look at the signal on the serial line with either an oscilloscope or another serial receiver?
  4. Is it possible you have multiple devices with address 2? They'll reply at the same time, correctly triggering a CRC error in the receiving device (gateway). (EDIT: From comments, this proved to be the source of the problem: a second device on the bus.)
  5. You say "USB adapter/Raspberry Pi/Modbus RTU: works": can you get the raw bytes and add them to the question? Ideally the same read-holding-registers(6, 1); ideally with the same reply(0x10, 0x1c).

CRC checking on the serial messages:

02 03 00 06 00 01   calc 64 38
02 03 02 10 1c   calc f0 4d
# python3 from modbus algorithm flow chart p40
# https://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf

def modbuscrc(msg):
    crc = 0xffff
    for b in msg:
        print("%02x " % b, end="")
        crc ^= b
        for i in range(0, 8):
            carry = crc & 0x01
            crc = (crc >> 1) & 0x7fff
            if carry:
                crc ^= 0xa001
    print("  calc %02x %02x" % (crc & 0xff, crc >> 8))
    return crc

modbuscrc([0x02, 0x03, 0x00, 0x06, 0x00, 0x01])
modbuscrc([0x02, 0x03, 0x02, 0x10, 0x1c])
jonathanjo
  • 12,049
  • 3
  • 27
  • 60