ESP32-EVB connected to MOD-RS485-ISO unable to query Modbus Device

Started by tylerkolden, June 25, 2023, 12:00:21 AM

Previous topic - Next topic

tylerkolden

My goal is to read Modbus registers from a device that supports RS485.  To accomplish this, I am using an ESP32-EVB flashed with Micropython v1.20.0.  I have a MOD-RS485-ISO connected via the UEXT port.  The problem is that the ESP32 cannot read registers from the Modbus device using the MOD-RS485-ISO device.  The MOD-RS485-ISO is in full duplex mode, with both the Z-B and Y-A jumpers removed.

https://drive.google.com/file/d/1IEMX1hoUW_-3RtXtr2j32D8SK5d6x1_6/view?usp=sharing

Confirm micropython version
import sys
print(sys.version)

Output
# 3.4.0; MicroPython v1.20.0 on 2023-04-26
Connect ESP32 to local wifi network and install umodbus
import machine
import network
import time
import mip
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect('SSID', 'PASSWORD')
time.sleep(1)
print('Device connected to network: {}'.format(station.isconnected()))
mip.install('github:brainelectronics/micropython-modbus')
print('Installation completed')
machine.soft_reset()

MOD-RS485-ISO Board Connection
# imports
from machine import SoftI2C, Pin

# ESP32 - Pin assignment
# Init I2C using pins GPIO16 (SCL) & GPIO13 (SDA)
i2c = SoftI2C(scl=Pin(16), sda=Pin(13))

# Default address of the MOD-RS485-ISO
device_address = 0x22
# Register map starts at address 0x20
starting_register = 0x20

# Define a buffer for the read data
data_buffer = bytearray(8)

# Use the readfrom_mem method to read 10 bytes from the starting_register
i2c.readfrom_mem_into(device_address, starting_register, data_buffer)

# Print each byte in the buffer
for i in range(len(data_buffer)):
    print("Register {}: {}".format(20 + i, str(hex(data_buffer[i]))))

Output
Register 20: 0x25
Register 21: 0x3
Register 22: 0x22
Register 23: 0x0
Register 24: 0x3
Register 25: 0x12
Register 26: 0x0
Register 27: 0x0

Query Modbus Registers with MOD-RS485-ISO in full duplex
# imports
from umodbus.serial import Serial as ModbusMaster

# registers
slave_address = 1
holding_register_start = 1
holding_register_quantity = 10

# host connection
host = ModbusMaster(
                pins=(4,36),           # UEXT UART 1
                baudrate=38400,  # modbus device specific
                data_bits=8,          # modbus device specific
                stop_bits=1,          # modbus device specific
                parity=None,         # modbus device specific
                uart_id=1               # modbus device specific
            )

# read holding registers
host.read_holding_registers(slave_address,starting_addr=holding_register_start,register_qty=holding_register_quantity,signed=False)

Output
Traceback (most recent call last):
  File "<stdin>", line 20, in <module>
  File "/lib/umodbus/common.py", line 199, in read_holding_registers
  File "/lib/umodbus/serial.py", line 289, in _send_receive
  File "/lib/umodbus/serial.py", line 313, in _validate_resp_hdr
OSError: no data received from slave

When the MOD-RS485-ISO is in half duplex with the Z-B and Y-A jumpers in place, the following output is shown

(256,)

If the holding_register_start variable is changed from 1 to 10, the output printed with the above code increases by a factor of 10

(2560,)

To confirm the Modbus device is communicating properly over RS485, I installed Modbus Poll and used this USB to RS485 adapter with the same serial settings as in the Micropython code.  It successfully reads registers from the device.





I would be very grateful for your help in determining how to get the MOD-RS485-ISO to successfully query the modbus device over RS485.

LubOlimex

Technical support and documentation manager at Olimex

tylerkolden

Thank you, LubOlimex.  The I2C register, 0x24, contains 0x03, meaning TX/RX are enabled.  The red and green LEDs on the MOD-RS485-ISO are also on.  Additionally, I wrote 0x00 to register, 0x24 to turn them off, and write 0x03 to turn them on again.  That worked successfully but did not cause the MOD-RS485-ISO to read Modbus registers over RS485.

The Micropython Modbus library works well on the ESP32 and I have used it with the RS232 adapter

Do you have any other ideas as to why the MOD-RS485-ISO device is having difficulty?

LubOlimex

Mainly because MOD-RS485-ISO was made with main microcontroller filled with custom firmware with commands to make the usage easier and that assumes you won't be using modbus but directly the internal firmware. There are just RS485 convertors that don't have main microcontroller or firmware and they work better with modbus. That being said I've seen people in the past using MOD-RS485-ISO with modbus successfully but I can't give you the solution since I don't have experience with modbus myself.
Technical support and documentation manager at Olimex

tylerkolden

Thank you for the helpful info!  I'll explore other RS485 to TTL adapters.