![]() |
Help reading data from serial RS485 - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Help reading data from serial RS485 (/thread-35503.html) |
Help reading data from serial RS485 - korenron - Nov-10-2021 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 Y0I2r5s0K2Q2j9g2Z9T4Y8a9M6W4V5W1C1X5k1K4but 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 RE: Help reading data from serial RS485 - deanhystad - Nov-10-2021 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. RE: Help reading data from serial RS485 - korenron - Nov-11-2021 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, RE: Help reading data from serial RS485 - deanhystad - Nov-11-2021 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 RE: Help reading data from serial RS485 - korenron - Nov-11-2021 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 , RE: Help reading data from serial RS485 - deanhystad - Nov-11-2021 Look at how I used encode and decode in my initial post. RE: Help reading data from serial RS485 - korenron - Nov-11-2021 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, RE: Help reading data from serial RS485 - deanhystad - Nov-11-2021 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. RE: Help reading data from serial RS485 - korenron - Nov-14-2021 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 bytecan you show me what is wrong? Thanks , |