Neu: Die KI-Firewall überwacht die gesamte Plattform und erklärt jeden Vorfall in einfachen Worten. So funktioniert es

Pi as Modbus RTU master for six PIC slaves on one RS-485 line: replies collide and get garbled

Pi as Modbus RTU master for six PIC slaves on one RS-485 line: replies collide and get garbled

Gelöst 5 4

Small retrofit: six old PIC18 boards on a mixing line, each one a Modbus RTU slave (IDs 11 to 16, 38400 8N1) on one RS-485 pair, about 40 m. A Raspberry Pi 4 polls them and reports into Hermetry.

Polling them one at a time from a laptop works. From the Pi, polling all six in a loop, about one in five replies is garbage or a CRC error, worse at the end of the line. Pi side is the onboard UART with a MAX3485, DE/RE driven by a GPIO from my Python code before and after each write.

pymodbus.exceptions.ModbusIOException: Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response
CRC check failed: 0x5a3e != 0x1b07

Is this a timing issue with the GPIO direction switching?

♥ 0

Termination and bias resistors? 40 m at 38400 without them can do exactly this.

♥ 0

120 R at both ends. No bias resistors anywhere, I’d assumed the PIC boards had them.

♥ 0

Not my field, but our building contractor had similar issues on a long cable and it turned out to be grounding. Just in case.

♥ 0

Yes, it’s the GPIO timing, and the missing bias doesn’t help. I had almost the same line on six pump controllers.

Driving DE/RE from Python is too slow and too jittery. After the write, your code switches back to receive only when Linux gets round to it. At 38400 a slave can start answering within a couple of milliseconds, so the start of the reply is lost or you’re still driving the line while the slave talks. Fix it in hardware: a USB-RS485 adapter with automatic direction control (FTDI-based ones are good), or let the kernel do it on the UART with rs485 mode. The adapter is the five-minute fix.

Then the line itself:

  • Bias: one pull-up on A and one pull-down on B, only once on the bus (560 R to 1 k is typical), so the idle line is defined.
  • Common ground wire between all nodes.
  • Give pymodbus a sane timeout and a pause between slaves, some old firmware needs a breather.
client = ModbusSerialClient(port="/dev/ttyUSB0", baudrate=38400, parity="N",
                            stopbits=1, bytesize=8, timeout=0.3, retries=2)
for unit in range(11, 17):
    rr = client.read_holding_registers(0, count=4, slave=unit)
    time.sleep(0.02)

Then report all six as children of the Pi on v1/gw/telemetry, keyed by name („mixer-11“ and so on). Each one gets its own device in Hermetry, and you can put a Device offline rule on their profile.

Akzeptierte Lösung♥ 1

USB-RS485 with auto direction plus 680 R bias resistors at the Pi end: zero CRC errors over 10,000 polls. Children show up in Hermetry as mixer-11 to mixer-16. Ciaran, thanks.

♥ 2
Ansicht von 6 Beiträgen – 1 bis 6 (von insgesamt 6)
  • Du musst angemeldet sein, um auf dieses Thema antworten zu können.

Mitdiskutieren

Melde dich an, um Fragen zu stellen und zu beantworten, hilfreiche Beiträge mit „Gefällt mir“ zu markieren und die Antwort zu kennzeichnen, die dein Problem gelöst hat. Jeder Beitrag bringt Punkte und Stufen.

Teilen