Problem reading RS485 communication packets with raspberry pi using python

I'm having trouble reading packets over a serial line, in the modbus protocol. I want to read the temperature from my thermometer that uses RS485 communication, so I used raspberry pi in combination with waveshare rs485 can hat.

Here is a code sample.

   #!/usr/bin/python3

import RPi.GPIO as GPIO
import serial
import time
from prectime import processor_sleep

rsp = 4
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(rsp, GPIO.OUT)
GPIO.output(rsp, 0)
a = float(7.5)
command = [0x02,0x04,0x00,0x05,0x00,0x01,0x21,0xF8]
r = str(0)

ser = serial.Serial('/dev/ttyS0', 9600, timeout = 0.1)

while len(str(r)) < 31:
    GPIO.output(rsp, 1)
    ser.write(command)
    processor_sleep(a)
    GPIO.output(rsp, 0)
    r = ser.readline()
    print(r,' --- ',a)
    a = a + 0.1
    processor_sleep(1000)

ser.close()

My prectime library with the processorsleep () function is here.

import time

def processor_sleep(ms):
    _ = time.perf_counter() + ms/1000
    while time.perf_counter() < _:
        pass

As soon as I connect the sniffer in parallel to the line I can see that the initiating packet is received and answered by the sensor correctly, however, when I try to read the same answer via python the result is this:

b''  ---  7.5
b''  ---  7.6
b''  ---  7.699999999999999
b'\x02\x04\x02\x01S\xbc\x9d'  ---  7.799999999999999
b'\x02\x04\x02\x01S\xbc\x9d'  ---  7.899999999999999
b'\x02\x04\x02\x01S\xbc\x9d'  ---  7.999999999999998
b'\x02\x04\x02\x01S\xbc\x9d'  ---  8.099999999999998

and it should look like (from sniffer)

b'\x02\x04\x02\x01\x52\xbc\x9d'

I don't know what's going on, sometimes it happens that I catch the packet well, but it's rare.

Thanks in advance.

Upvotes: 1

Views: 2026

Answers (1)

Marcos G.
Marcos G.

Reputation: 3496

This topic has been already discussed at length.

Just go here and follow the rabbit hole of links in my answer. You should be able to solve your problem.

I would go for the libmodbus solution (there is a Python wrapper too) but you can also stay with pymodbus if you want.

Anyway, what sawdust says in the comments is also very good advice. The easiest would be to invest 10 bucks and buy a transceiver that is able to toggle itself. Yours is not, unfortunately.

Upvotes: 1

Related Questions