2

I am failing to communicate with a device using minimalmodbus, Modbus RTU.

I have connected the device to a raspberry pi via a usb to rs-485 adapter (FTDI chip) A to A and B to B.

The device configurations are as follows:

  • Port settings:

    • Baud rate: 9600
    • Parity: No
    • Stop bits: 1
    • Silent Interval: 70 ms.
    • Transmission Mode: RTU
  • Interface 2 Wire RS485

    • Connector of ECM: DB9
    • Connections: A on pins 1, 4. B on pins 6, 9

Modbus Holding registers (simplified for the purpose of this example)

  • Swapped Floating point format:
    • 40001 (address 0) Parameter 1
    • 40003 (address 2) Parameter 2

I have tried using raw serial commands to communicate with the device, as well as using pymodbus, and now on my latest attempt minimal modbus. Please see below my code attempt using minimalmodbus.

Also, i know the serial adapter works as i use it for various other serial sensors. Only difference is that i am working with modbus now.

import minimalmodbus

instrument = minimalmodbus.Instrument('/dev/tty/USB1',1)

instrument.debug = True
instrument.handle_local_echo = True # The serial device echos back every write, hence this
instrument.serial.baudrate = 9600
instrument.serial.timeout = 1

value = instrument.read_register(0,2)

print value

I expected to receive some sort of reply even if an error or incorrect, but i am getting nothing. the debug output of minimalmodbus says "IOError: No communication with the instrument(no answer)"

Is there any obvious mistakes in my code vs the sensor requriements? I confirmed my wiring with the manufacturer, and is correct.

LecauseAndThePi
  • 155
  • 1
  • 4
  • Is the function code correct? You could try `read_register(0, 2, 3)` instead. – Bosz Jul 24 '19 at 11:25
  • Can you test you modbus slave with another master an confirm that it is working? – JWo Jul 24 '19 at 11:27
  • @Bosz yes the function code should be correct. I tried your solution and still same issue. – LecauseAndThePi Jul 24 '19 at 11:30
  • @JWo I only have the raspberry pi (3b+) and my laptop that i can use as a master. Would still be using python either way. i might try to run it from my laptop. – LecauseAndThePi Jul 24 '19 at 11:32
  • Before I used python I used NodeRed with this lib: https://flows.nodered.org/node/node-red-contrib-modbus with the usb to rs485 converter. I used it on the pi and my linux mint laptop. On windows I had to install a driver for the usb converter. – JWo Jul 24 '19 at 11:42
  • 1
    Can you post a link to your USB-to-RS485 cable? Modbus over half-duplex needs a direction control signal, does your cable has hardware direction control? – Marcos G. Jul 24 '19 at 11:49
  • @MarcosG. I am using FTDI chip USB-RS485-WE-1800-BT. I'm not sure what you mean, i have only connected A to A and B to B from device to adapter, so only 2 wires. Adapter: https://uk.rs-online.com/web/p/kvm-mixed-cable-assemblies/6877834/ – LecauseAndThePi Jul 24 '19 at 12:44
  • False alarm, your cable does have direction control. But I still think you have a hardware issue. Are you connecting both pair of pins on the SUB-D9? I mean pins 1 and 4 to A and 6 and 9 to be. What sensor are you connecting to? – Marcos G. Jul 24 '19 at 12:59
  • Another though: I found that on a laptop or Rpi sometimes you need to connect the GND on both sides depending on the power supply you're using, have you tried that? – Marcos G. Jul 24 '19 at 13:01
  • And the last thought: why are you using local echo? For Modbus it should be disabled but with your setup I don't think it's having any effect (because of the direction control I mentioned earlier) – Marcos G. Jul 24 '19 at 13:07
  • @MarcosG. Yes i have 1,4 joined together going into A, and 6,9 joined together goign into B. They do share ground. I need the local echo handling because otherwise minimalmodbus thinks tht the echo is the response form the sensor. I can clearly see that the the first few bytes are jsut an echo of the command sent out. – LecauseAndThePi Jul 24 '19 at 13:57
  • OK I see... That echo you see might actually be the problem. According to the manual the hardware echo should be disabled by default, have you changed it? If so I would disable it again just in case. – Marcos G. Jul 24 '19 at 14:02
  • @MarcosG. i ahd it disabled initially. the issue is that if it is disabled, the software tries to parse it as the reply from the device, and does not actualyl wait to receive the reply. Thank you for the thoughts thought! i appriciate the help – LecauseAndThePi Jul 24 '19 at 14:07
  • I think you misunderstood what I meant. The reason you need this `instrument.handle_local_echo = True ` is your cable is listening to its own messages on the bus. But that's a hardware setting on your cable. My point is that hardware setting is disabled by default, so have you activated your hardware echo? It might also be it came eneabled by defaault for some strange reason. – Marcos G. Jul 24 '19 at 14:13
  • There might actually be a bigger issue involved. If you look at section 5.4 of the [manual](https://docs-emea.rs-online.com/webdocs/0da7/0900766b80da71f7.pdf): it says the echo function is shared together with the TXEN (TX enable) signal and that's actually the one you need for Modbus (otherwise there is no arbitration on the bus). It's actually quite easy to enable and disable it, if you want I can write you a couple of pointers in an answer – Marcos G. Jul 24 '19 at 14:16
  • @MarcosG. Tha would be great! i thikn you mean disabling ont he actual chip right? don't have a clue how i would go about it. – LecauseAndThePi Jul 24 '19 at 14:20
  • OK, it's surprisingly easy, just a sec. I'll write you an answer – Marcos G. Jul 24 '19 at 14:20

2 Answers2

1

I don't see an obvious error from your side. That's rather difficult since you are working with hardware. I'll provide some of my code. I used it for a prototype, which was a Raspberry Pi 3B with a USB to RS485 converter (This one).

from modbus import minimalmodbus
import serial
import time
from mqtt.client import Client as mqtt_client

class Slave:

    def __init__(self, serial_port: str = '/dev/ttyUSB0', slave_id: int = 5,
                 baudrate: int = 38400, byte_size: int = 8,
                 parity: str = serial.PARITY_NONE, stopbits: int = 1,
                 timeout: float = 1.0):
        self.slave = minimalmodbus.Instrument(serial_port, slave_id)
        self.slave.serial.baudrate = baudrate
        self.slave.serial.bytesize = byte_size
        self.slave.serial.parity = parity
        self.slave.serial.stopbits = stopbits
        self.slave.serial.timeout = timeout
        self.registers = ["header", "zero", "life_beat",
                          "test_int", "test_float"]
        self.output = mqtt_client()
...

When I read a register I used e.g.:

self.slave.read_register(2)
//or
self.slave.read_float(5)

I'm not sure which python version I used. I think it was 3.6.x.

JWo
  • 650
  • 1
  • 6
  • 23
  • Thank you for sharing your code. I will try to set up a class same as you did, althought it looks like it's very similar to my test code regarding the minimalmodbus side of things. – LecauseAndThePi Jul 24 '19 at 11:33
0

Quoting from the manual of your cable:

The USB-RS485-WE cable allows for local echo to be enabled/disabled by changing a bit in the FT232R EEPROM. If CBUS4 in the EEPROM is set for “PWRON#” local echo is enabled. If CBUS4 in the EEPROM is set for “TXDEN” local echo is disabled. Users can set this with MPROG from www.ftdichip.com The default for the local echo is disabled (CBUS4 set for “TXDEN)

Phew! lots of info in there. According to the thread of comments on your question you activated the software echo handling on minimalModbus because otherwise your routine would not wait for the response from the device on the other end. That makes one think whether your cable has the local echo enabled or disabled.

Fortunately, you can check that very easily. As the manual says just go get MPROG here. Extract and run (yeap, you need Windows for this tool, but you can run it on a Virtual Machine).

Connect your cable to the USB port (don't forget to send the device to the virtual machine if you are running one) and select Tools-->Read and Parse on MPROG.

This is what you should get:

MPROG screenshot

Make sure you have TXEN selected on box C4. According to the manual, you should have TXEN by default, if you see PWRON# it means the local echo is active. Disable it and you should be good to go to use Modbus.

Marcos G.
  • 3,371
  • 2
  • 8
  • 16