2
\$\begingroup\$

I am trying to connect a Turbidity sensor that operates using Modbus to a Raspberry Pi. The sensor is an industrial-grade device and comes with the needed communication protocols (http://www.sonbus.com/upload/pdf/XM8518.pdf). I connected to Raspberry Pi to a Waveshare RS485 (https://thepihut.com/products/rs485-board) module, which was then connected to the Turbidity sensor. The connections are given in the diagram below.

enter image description here

I've also added an image of the setup for reference.

enter image description here

The code I used is given below. I tried minimalmodbus here.

import serial
import minimalmodbus
import RPi.GPIO as GPIO
import time

RSE_PIN = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(RSE_PIN, GPIO.OUT)

instrument = minimalmodbus.Instrument('/dev/ttyS0', 1) 
instrument.serial.baudrate = 9600   
instrument.serial.bytesize = 8  
instrument.serial.parity = serial.PARITY_NONE  
instrument.serial.stopbits = 1 
instrument.serial.timeout = 0.5  

instrument.mode = minimalmodbus.MODE_RTU

def read_turbidity():
    try:
        GPIO.output(RSE_PIN, GPIO.HIGH)
        time.sleep(0.02)
        
        raw_value = instrument.read_register(0, 3) # registeraddress, functioncode
   
        GPIO.output(RSE_PIN, GPIO.LOW)
        
        turbidity_value = raw_value / 100.0
        
        print(f"Raw Value (decimal): {raw_value}")
        print(f"Turbidity Value: {turbidity_value} UNT")
        
    except IOError as e:
        print(f"Failed to read from sensor: {e}")
        GPIO.output(RSE_PIN, GPIO.LOW)
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
        GPIO.output(RSE_PIN, GPIO.LOW)

if __name__ == "__main__":
    try:
        print("Starting turbidity sensor reading. Press Ctrl+C to stop.")
        while True:
            read_turbidity()
            time.sleep(5)  
    except KeyboardInterrupt:
        print("Reading stopped by user.")
    finally:
        GPIO.cleanup()
        print("GPIO cleanup complete.")

Problem is, my device is not giving back any response at all. I am getting an IOError. I've done the usual checks, I tried connected my TX directly to RX to see whether I am getting back a response and that works fine. I also tried switching A and B around to no avail. Is there something I need to change in my code or wiring? I would appreciate any help.

\$\endgroup\$
2
  • \$\begingroup\$ Not the reason for your problem but the grounding is wrong. The module thing needs to be grounded together with the sensor using a signal ground. Same with the module and the Rasp pi. Signal ground being one of the mandatory signals of RS485. As your schematic is now, you drag in the dirty supply ground as the only signal reference. \$\endgroup\$ Commented Sep 2 at 11:27
  • \$\begingroup\$ @Lundin The grounding looks like it's as good as it can be. Lab supply is connected directly to sensor cable and RS485 module ground connects to same point. \$\endgroup\$ Commented Sep 2 at 12:50

2 Answers 2

2
\$\begingroup\$

Your code cannot read back the result if the RS-485 is in transmit mode and reception is disabled while the library tries to receive a result.

I don't have an answer what you should do to make it work - it's an out-of-scope software problem how to make some random Python library to handle how your hardware is made. Besides the library documentation already discusses how to handle the TX/RX mode switching.

So, as per the sensor library documentation, you need to either let the sensor library to control the GPIO pin because it knows when it wants to send a command and receive a response, or you need to let the UART driver handle the GPIO pin when it transmits so then the sensor driver simply opens the UART port in such a mode that the GPIO state is correct for transmission and receive. Most often UART drivers have a feature to open them in RS485 compatible mode where RTS is used as the transmit enable pin.

\$\endgroup\$
0
\$\begingroup\$

It has been more than 2 weeks since your post so I don't know whether you had figure out the issue yet. But in any case, it is very important to read datasheet and user manual of the device that you first time use it. Here is what I see from WaveShare RS485 user manual: WaveShare RS485 User manual section 2.2.2

Your code did exactly the opposite of switching the RSE pin to LOW before transmission and HIGH after the transmission.

\$\endgroup\$
5
  • \$\begingroup\$ The problem is more fine-grained than what you say. The RSE is set manually but in reality the function that tries to read something must be able to transmit data to send a command what to read and switch to receive mode for listening to the sensor data. It's the serial port driver or the library that should change the transmit/receive mode, it will not work if mode is changed outside the library only via GPIO like that. And, the sensor library manual says how the direction changes can be handled so OP can read manual and choose how to handle the issue so that the library or port can handle it \$\endgroup\$ Commented Sep 20 at 11:02
  • \$\begingroup\$ @justme, I know it is not ideal, but controlling GPIO from user space software is not necessary "don't work", the 3.5 charter time before Slave start to transmit is about 4ms at 9600bps, see this discussion on the library that OP is using. Personally I don't code embedded with python and therefore I didn't commit on OP's code. \$\endgroup\$ Commented Sep 20 at 13:31
  • \$\begingroup\$ Yes but as you see, you cannot set the GPIO into transmit mode because then the library call cannot receive, and you cannot set the GPIO into receive mode because the library call cannot transmit. And the library code must transmit a command and receive a response, so either the library or the UART driver must be able to control the switch between transmit and receive mode. And now it is not possible. And, sensor library has examples how to do it. \$\endgroup\$ Commented Sep 20 at 14:00
  • \$\begingroup\$ @hcheung this seems to be the issue with my setup. Once I made sure the the RSE pin was high during transmission and low when receiving, the device began to respond and provided turbidity readings as expected. \$\endgroup\$ Commented Oct 2 at 15:33
  • \$\begingroup\$ Glad that this work out for you. If this is the case, please mark this post as the answer and upvote it. \$\endgroup\$ Commented Oct 3 at 1:29

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.