Nouveau : le pare-feu IA surveille toute la plateforme et explique chaque incident en termes simples. Découvrez comment ça marche

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

Résolu 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.

Solution acceptée♥ 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
6 sujets de 1 à 6 (sur un total de 6)
  • Vous devez être connecté pour répondre à ce sujet.

Rejoignez la discussion

Connectez-vous pour poser et répondre à des questions, aimer les messages utiles et marquer la réponse qui a résolu votre problème. Chaque contribution rapporte des points et des niveaux.

Partager