Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am having difficulties with unicode strings serialport.write("\x23o0 \x23f") not being supported

We are having difficulty with the following code

#Get the heading from the IMU
#Translate the IMU from magnetic north to true north since the calcs use true north
def getcurheading():
# The escape character for # is \x23 in hex
    serialport.write("\x23o0 \x23f")
    headresponse = serialport.readline()
#   print(headresponse)
    words = headresponse.split(",")
    if len(words) > 2:
        try:
            curheading = (float(words[0])) + 180
            if curheading + Declination > 360: curheading = curheading - 360 + Declination
            else: curheading = curheading + Declination
        except:
            curheading = 999
#   print(curheading)
        return curheading

Here is the error reported:

Traceback (most recent call last):
  File "solarrobot7-core.py", line 256, in <module>
    if (getcurheading() < getsolarheading()) and (getsolarangle() > 2) and (getcurheading() != 999):
  File "solarrobot7-core.py", line 118, in getcurheading
    serialport.write("\x23o0 \x23f")
  File "/usr/local/lib/python3.2/dist-packages/serial/serialposix.py", line 518, in write
    d = to_bytes(data)
  File "/usr/local/lib/python3.2/dist-packages/serial/serialutil.py", line 58, in to_bytes
    raise TypeError('unicode strings are not supported, please encode to bytes: %r' % (seq,))
TypeError: unicode strings are not supported, please encode to bytes: '#o0 #f'

It looks like i can use:

a_string = '\x23o0 \x23f Python'
by = a_string.encode('utf-8')
serialport.write(“\x23o0 \x23f “) a serialport.write(by)

Is this correct? Since i'm not a coder i'm not sure if this fix is correct. i've tried it and the code continues until it throws another error which appears to be related to this step. This is why we're backtracking to see if this is correct before moving on.

like image 544
frazelle09 Avatar asked Feb 08 '23 22:02

frazelle09


1 Answers

In Python 3.X, strings such as "abc" by default are Unicode strings. Strings must be encoded for transmission, or just start with a byte string b"abc" (note the b). Either of these will work:

serialport.write(b"\x23o0 \x23f")

or:

serialport.write("\x23o0 \x23f".encode('ascii'))

Note that specifying an encoding is optional and defaults to utf8.

bytearray is a mutable form of a byte string and isn't really needed here. It should have given you an error without an encoding on Python 3:

>>> bytearray("abc")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
>>> bytearray("abc",'ascii')
bytearray(b'abc')

You can edit bytearrays:

>>> bytes = bytearray("abc",'ascii')
>>> bytes[1]=50
>>> bytes
bytearray(b'a2c')

but not byte strings:

>>> bytes = b'abc'
>>> bytes[1] = 50
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment
like image 181
Mark Tolonen Avatar answered Mar 11 '23 02:03

Mark Tolonen