I'm porting a codebase for the Lasersaur laser cutter from Python2 to Python3, and I'm having a bit of trouble decoding the serial data coming in from the onboard Arduino. The data comes in as a byte stream that mixes hex and unicode data, like so:
bytes: b'AC\xfb\xff\xff\xbfx\x85\x80\x80\xc0y\x80\x80\x80\xc0z'
data: A C 251 255 255 x 133 128 128 y 128 128 128 z
Python2 was able to steamroll over the mixed-type data, and read in the serial data as a string of characters, after which ord()
was used to determine if the character represented data or a status character. You can see how this is implemented in the original Python2 code starting at line 367 here.
ord(data): 65 67 251 255 255 120 133 128 128 121 128 128 128 122
Python3 is more stringent about encodings, and throws me the following error when I try bytes.decode('utf-8')
, because it gets to the first hex data b'x\fb'
and chokes because it's a different format. Messing around with a few different codecs doesn't give any better results.
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfb in position 2: invalid start byte
I found this StackOverflow thread which addresses what I need pretty much exactly, but it seems that the error handling in Python 3 no longer works the same, and throws me this error when I try the solution there: TypeError: 'UnicodeDecodeError' object is not subscriptable
.
I could modify the onboard code on the Arduino in order to get a saner serial encoding, but the main reason I'm porting to Python3 is that I can't get the right (read: old) Python2 libraries in order to execute the code and I don't want to run into the scenario where I inadvertently get to a state where it's impossible to communicate with the onboard arduino.
What I'd like to do is mimic the original functionality as closely as possible, and get out either a string of characters that I can call ord()
on, or a mix of characters and numbers in a list. I'm a bit lost on how to do this.