Python Forum
Help reading data from serial RS485
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help reading data from serial RS485
#1
Hello ,
Hello ,
I'm trying to read RS485 data from one pi to another (using TTL to RS485 device)

on the "sender" side I have this simple code:
import time
import serial
from time import sleep
import random
import string

send = serial.Serial(
    port='/dev/serial0',
    baudrate = 9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
)


while True:
    letters = string.ascii_letters
    digits = string.digits
    data = ''.join(random.choice(letters) + random.choice(digits) for i in range(20))
    data = (data +"\n\r")
    send.write(data)
    print(data)
    time.sleep(0.2)
in the receiver side I have this code:
import serial

RS485 = serial.Serial(
    port='/dev/serial0',
    baudrate = 9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
)

while True:
    x = RS485.readline()
    print(x)



I can see the sender sending this data:
f6d6d0F9B3L1K2C6K0y6m0N2O4S9A8u5y2t0J7f2

H1r1W2X6X0B2i0Y4b0w8U2M6C8X3i1D1D5p9F2y5

f8J8m7z6y3m2U6I3U0Z7J6M4l7Z0B5v4F6H5e2Q2

L6Z0G8m1Q2Q2d6O3t7M8J7h8h8E8b8Z9H3P5I5R2

l3N3T7C2o3T3K3c8G2S5h3G6x6b1O4X1R5B6o1U0

O5S2S3m5L4J5Z7i3U6r5J8h1J2r5k6y8T4S6h7I7

B9E4t5S0k0K1k0T4w4j3t1i0K3w2A5Y9h9N6k2m5

u7E9p4O9D9X0O7V1h1Y6J1R4n3s0g6L2P1A3Z9q9

p3K1X6t0a5P1W4Q6N9G1S8L7C2U2q8k1f6G9O7Q3

r3M9t1J7r0q3c0A0d0z5R0I6b9k1t5f3Q7I5D3w6

I9o6U4F9u8p3m3q5Y3v3I5W0K9O8w7j8z1L8i4f5

Y0I2r5s0K2Q2j9g2Z9T4Y8a9M6W4V5W1C1X5k1K4
but on the receiver I get this :

b'@(\tB\xf7D\xe6\x81F\xb2\x1a@\xa8\x11d3\x8a`\x89@\xfa\x82\xfe\x18`*b\x12dd\x18\xa2@\xb6D\x92 2\x08\xa3@\r\x01B\x11"`\xf2\x12b\x18d\xe6\xa3\x89`w>B\x8fD"d\xf7\x89@\xc9\x82\xff\xa3\xa7@\xf6B\x98\xb2`M\xb2F\x03B\xb3\x82\xfe0+`D\x81DB\x99\x82F{&F\x0b\xfe\x11b\x99\x02F\x8d&d\x19\tB#`J\x81"\x92B\rD\x11b\x98\xb2D\xb2@;F\xe6+D\x0b\x1ab\xa8\xa3`\x99@\xcd\x19D\x10 \x91`\x0c\x7fd:@w\xb2@\x96@\x9bf\xe6*F#`\x89f\x0c\xb7b\x89\x11bd\xbe\xff\xb9\xacf@\t\x1aD\t\x8a@\x98\x86B~+ \x8aB\x10:bM\x8bf\xb2dww`\x83 \x11\x99FJD\x98wD\x913d\x99\xb2F\n'
b'\xfe\xa8@\x0bF\x99\x8b@\x9eFrd\x12`\x82\xfesd\xaab7\x07B;D\xa8\n'
b'd\xc9\x99  F63BD\x99b\x11B7b\x91\x81\x01B\x10\x02B\x19\t`3b:`\tD\xe6\x19ds\xb3B:D\x11Bm:@\td\xe6I\x91B\x12BN\xa2bwB\x8c\x82@3 \x83F\x82B\xea\x11b\x18\x82b\x08\xa2d\x91\x81\n'
b'`\xa2db\xba`\x07f\x91"D\x1a *+Bb7+F\x11@\x8aD\x01d\x81\x90D\x90oB\x91+FD\xec:d@H\xfew2F\x02@\x93d\x11FI+dJ\x01 D\x1fB#@\x11\xa2@`\x08\tF\x0b \xbcB\x8eg@\x01B\t\xb2BH`\x10+ ;\x1bd\x8d>B\x8d*d\x89B\x16b\xb2 B\x16@;B\x98d\x19D\xaa@;; \xa2@7\x03Bbb#b\xc9\x81@L\x82\xfe%\xabDw\x12B\x12`J\xafb\xb2bB\xe7\x18\x0ef\x10@\x10\xa2`\x88*b7@B\xe6\xaa\xc9\xbbDbnDw\xb2bI\xa7F\xbb\x81r\tFr\x1ab\xc8\xb2B\x98\x11B\x8eB\x82\xfe\xe8\x11Dv\x89d\x0cb\x91\x11Ds\xbb@\x82\xff3\x82@\xe8D\xc8\x0bB\[email protected] \xf2#F\xc9d;@\xb2\n'
**when I connect it to my computer I can see the data correcrt.


what am I missing \ doing wrong ?


** when I try to decode the answer
x = RS485.readline()
    data = str(x, 'utf-8')
    print(data)
I get this error:
'utf-8' codec can't decode byte 0xf2 in position 0: invalid continuation byte
Reply
#2
Serial expects data to be bytes and you give it a str. I am surprised this didn't raise an exception. What version of Python are you using? In pre-3.0 Python str and bytes were the same. Now str is made up of unicode characters.

This is some serial code I extracted from a recent project. I did some editing, so this code may not run as is.
import serial

class SerialDevice():
    def __init__(self, port_name='COM1', baudrate=19200, timeout=0.1):
        self.port = serial.Serial()
        self.port.port = port_name
        self.port.baudrate = baudrate
        self.port.timeout = timeout

    def open(self, port_name=None, baudrate=None, timeout=None):
        if port_name is not None:
            self.port.port = port_name
        if baudrate is not None:
            self.port.baudrate = baudrate
        if timeout is not None:
            self.port.timeout = timeout

        self.close()

        self.port.open()
        if not self.port.is_open:
            raise IOError(f'Open failed on port {self.port.port}')

    def close(self):
        if self.port.is_open:
            self.port.close()

    def send_cmd(self, command):
        """Send command and read reply"""
        if not self.port.is_open:
            raise IOError('Port is not open')
        self.port.write(f'{command}\r'.encode())
        reply = self.port.read_until(b'\r')   # My device uses /r as a terminator
        if not reply:
            raise IOError('Read timeout error')
        return reply.decode()
The main things you are missing are encoding the strs to bytes before sending/writing with a corresponding decoding on the other side, and a timeout. Every serial program that uses read (and especially readline) should specify a timeout.
Reply
#3
so what do I need to do?
what do I need to to make it work ?
change something in the send code?
the sender is using python2 and the receiver use python3

now I'm sending only this:
send.write(bytes('test\r\n'))
and I get this
b'\xbe\x1b\xff'
b'\xbb\x1b\xfe'
b'\xbb\x1b\xfe'
b'\xbb\x1b\xfe'
b'\xbb\x1e\xfe'
b'\xbb\x1b\xfe'
b';\x1b\xff'
b'\xbe\x1b\xff'
b';\x1a\xfe'
b'\xbb\x1b\xfe'
b'\xbb\x1b\xfe'
so I'm getting bytes - but how do I get from this the work 'test'? (which I have sent )?

I assume it's something very easy to do ?

Thanks,
Reply
#4
Since the sender is Python2, bytes and str should be the same. The Python3 side wil need to encode() to send and decode() to receive
Reply
#5
Still not working

maybe you can see what is wrong

Sender side python2 :
send = serial.Serial(
    port='/dev/serial0',
    baudrate = 9600,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout=1
while True:
    send.write('test')
    time.sleep(200)
Receiver side Python3:
while True:
    x = ser.read()
    data = str(x) -->not working et the same b'\xbb\x1b\xfe'
    data1 = str(x).decode('utf-8') --> error AttributeError: 'str' object has no attribute 'decode'

    print(data)
    print(data1)
?

Thanks ,
Reply
#6
Look at how I used encode and decode in my initial post.
Reply
#7
I don't understand what you are saying...

this is what I understand from you :

the sender side is OK
the problem is in the receiver side, need to add decode

and now what - this is not working as you can see

what I need to change in the receiver ?
can you show\write?

Thanks,
Reply
#8
bytes is a collection of bytes (8 bit values). str is a collection of unicode characters. encode() converts a str to bytes. decode() converts bytes to a str.

You are not using decode() correctly. data = x.decode(), not data = str(x).decode().

str(x) does not convert x from bytes to a str. it asks the class bytes to make a string representation of x, usually for the purpose of printing. bytes creates a str containing a bunch of backslashes and hex codes thinking that since it is "bytes" you want to see the hex values of the bytes.

x.decode(encoding) converts the bytes (x) to a str. This consists of grabbing one or two bytes at a time and looking up the associated unicode character. Without an "encoding" argument it assumes bytes were 8 bit ascii characters

str(x).decode() is an error str does not have a decode() method. Why would it? decode() is used to convert something else to a str. If you are already a str, you don't need to be converted to a str.

Even though you probably don't need to encode or decode in Python2 (I've never used it so I don't know for sure), I would still use encode() and decode() and bytes if such things are supported. Then the code would be mostly compatible with Python3.
Reply
#9
I did everything you suggested

on the reader part (Pyhton3)
I put:
x = ser.read()
print(x.decode())
and in the sender :
test = 'test1'.encode()
 send.write(test)
I still get en error
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbb in position 0: invalid start byte
can you show me what is wrong?


Thanks ,
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  pyserial/serial "has no attribute 'Serial' " gowb0w 9 3,902 Aug-24-2023, 07:56 AM
Last Post: gowb0w
Star Pyserial not reading serial.readline fast enough while using AccelStepper on Arduino MartyTinker 4 4,057 Mar-13-2023, 04:02 PM
Last Post: deanhystad
  Reading All The RAW Data Inside a PDF NBAComputerMan 4 1,341 Nov-30-2022, 10:54 PM
Last Post: Larz60+
  help with code for USB-RS485 korenron 3 3,653 Nov-17-2022, 09:04 AM
Last Post: wiseweezer
  Reading Data from JSON tpolim008 2 1,077 Sep-27-2022, 06:34 PM
Last Post: Larz60+
  Help with WebSocket reading data from anoter function korenron 0 1,328 Sep-19-2021, 11:08 AM
Last Post: korenron
  Fastest Way of Writing/Reading Data JamesA 1 2,187 Jul-27-2021, 03:52 PM
Last Post: Larz60+
  Reading data to python: turn into list or dataframe hhchenfx 2 5,368 Jun-01-2021, 10:28 AM
Last Post: Larz60+
  Reading data from mysql. stsxbel 2 2,202 May-23-2021, 06:56 PM
Last Post: stsxbel
  reading canbus data as hex korenron 9 6,284 Dec-30-2020, 01:52 PM
Last Post: korenron

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020