2

I am new to MODBUS-RTU protocol. I have Raspberry Pi4 connected to a Environmental Sensor through USB 2.0 to RS485 Serial Converter Adapter Cable. My real struggle lies in receiving the data from the sensor. I have used the below code for fetching the data from the sensor using the serial port:

import serial
from time import sleep

ser = serial.Serial ("/dev/ttyUSB0", 9600)    #Open port with baud rate
while True:
    print(ser)
    received_data = ser.read()              #read serial port
    print(received_data)
    sleep(0.03)
    data_left = ser.inWaiting()             #check for remaining byte
    received_data += ser.read(data_left)
    print (received_data)                   #print received data

When i execute the above code i receive empty data. Kindly let me know how i can extract the data from the MODBUS-RTU device using USB 2.0 to RS485 Serial Converter Adapter Cable into pi?

The data sheet provides the following information.

Communication protocol

1.Standard MODBUS RTU protocol

1.Physical port definition

Baud rate——9600bps ,Data bits——8bits,check bit——NO(NO check ),Stop bit——1bit

I also want to know,whether i need to add any device in between so that it becomes easy for me to extract the data into pi using the python script.

Any other code which helps me in getting the data is much appriciated.

UPDATE: I have tried PyModbus. The code is given below.

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

from pymodbus.constants import Endian
from pymodbus.constants import Defaults
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.transaction import ModbusRtuFramer
Defaults.RetryOnEmpty = True

# set Modbus defaults
Defaults.Timeout = 5
Defaults.UnitId = 1
Defaults.Retries = 5

client = ModbusClient(method='rtu',
                        port='/dev/ttyUSB1',
                        stopbits=1,
                        bytesize=8,
                        timeout=3,
                        baudrate=9600,
                        parity='N')

connection = client.connect()
print ("Readout started")

#result = client.read_discrete_inputs(0)
result = client.read_holding_registers(3,4,unit=1)
#result = client.read_input_registers(0,1)
print(result)

But i get Modbus Error.

Readout started
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x1 0x3 0x0 0x3 0x0 0x4 0xb4 0x9
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x1 0x3 0x0 0x8 0x0 0x8 0x1 0x1a 0x2 0x2a 0x23 0x7a 0x98
DEBUG:pymodbus.framer.rtu_framer:Frame check failed, ignoring!!
DEBUG:pymodbus.framer.rtu_framer:Resetting frame - Current Frame in buffer - 0x1 0x3 0x0 0x8 0x0 0x8 0x1 0x1a 0x2 0x2a 0x23 0x7a 0x98
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response.

Can anybody help in correcting the above error.

Also i have tried changing the parity bit to E and extended timeout but i still get the same error.

Update-1:

Details of the sensor:

Model: BGT-W812 pro

Parameter:

1.Power supply :DC12V(recommand)

2.Maximum power consumption: Without heating:130mA/12V;heating:700mA/12V

3.Power type: 220V AC 、12V DC

4.Communication protocol:MODBUS RTU protocol

5.Output:RS485

Navigation in defining:

1:+12V (RED)

2:GND (BLUE)

3:RS485_A(YELLOW)

4:RS485_B (GREEN)

Product link:

[https://www.alibaba.com/product-detail/BGT-Temperature-Humidity-Air-Pressure-Wind_1600425200036.html][1]

Hardware Connection:

Black and Red Wires are connected to 12VDC.

The other side of the USB-RS485 converter is connected to the USB port of PI.

enter image description here

Update 2: Manual data

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

GK Raj
  • 21
  • 2
  • [Modbus](https://www.modbus.org/specs.php) is a client/server protocol; that is the client (your Pi in this case) makes a request and the server (the Sensor) responds. Your code does not appear to be making a request so its unsurprising that nothing is received. A Modbus library (e.g. [PyModbus](https://pymodbus.readthedocs.io/en/latest/), [MinimalModbus](https://minimalmodbus.readthedocs.io/en/stable/) [etc](https://stackoverflow.com/questions/17081442/python-modbus-library)) will help you get started. – Brits Jun 13 '22 at 20:48
  • Thanks @Brits I have tried PyModbus but i get Modbus Error. please check the update i have made on the querry. Kindly help. – GK Raj Jun 14 '22 at 09:22
  • The received data shown in the log (`0x1 0x3 0x0 0x8...`) looks vaguely like it should (the first `0x00` is an issue because that should hold the byte count). This seems to indicate that the sensor has received the request and responded but the response is corrupted. Without more information (e.g. model of the sensor, details of your wiring, two or three wire, termination etc) it's difficult to help further. – Brits Jun 14 '22 at 19:58
  • Hi @Brits, Thanks a tone for your response. Good to know that the device is responding. But let me know the mistake that i have done either in the hardware connections or in understanding the device. – GK Raj Jun 15 '22 at 04:18
  • That all looks fine (in some cases connecting GND can help but I doubt it will here). I cannot find any real info (manual etc) on that device (not uncommon with units from alibaba) so cannot really help. Sorry but I'd suggest contacting the supplier (you can report that the device is responding but the data is not as expected). Do you have a manual for the unit? (if so attempt to exactly replicate the example request given - sometimes the developers take shortcuts...). – Brits Jun 15 '22 at 08:05
  • @Brits I have contacted the supplier but i dont get any positive response from them. They just tell me that they use MODBUS RTU protocol and rest should be cracked from my end. So please let me know what else i can do to extract the required data. I have added the images of the manual. Hope that hels you. – GK Raj Jun 15 '22 at 09:11
  • It might be worth trying [modbuspoll](https://www.modbustools.com/modbus_poll.html)/[mbpoll](https://github.com/epsilonrt/mbpoll); the supplier may listen if those (known good) programs fail. Other than that try a different RS485 adapter and, perhaps, a [terminating resistor](https://stackoverflow.com/a/48953038/11810946) in case the issue is noise (especially if the cable is long). Unfortunately its difficult to help resolving this kind of thing remotely (and discussions like this are not really a good fit for stack overflow - possibly try [reddit](https://www.reddit.com/r/MODBUS/)). – Brits Jun 15 '22 at 09:41
  • Hi, I got the solution. I had to send correct command to get the data from the Device. I had to send the correct number of registers to get the data. I just changed this, "result = client.read_holding_registers(3,4,unit=1)" to this "result = client.read_holding_registers(0,9,unit=1)" – GK Raj Jun 17 '22 at 07:30
  • Great. Unfortunately these devices sometimes only partially comply with the Modbus spec (for example only accepting reads of a particluar range and returning invalid data if you request something else). Can be frustrating; great that you have a solution. – Brits Jun 17 '22 at 07:41

0 Answers0