0

Sending a newline (\n) terminated string to an Arduino with serial.write().

Converting a python 2.x script to python 3.x the following produced a "unicode not supported" error:

cmd = "a string" 
cmd = cmd + "\n"
serial.write(cmd)

changing to

serial.write(cmd.encode('ascii'))

eliminated the error

However, I am unclear as to exactly what is transmitted by

serial.write(cmd.encode('ascii'))

A console session produced the following:

>>>cmd = "a string"
>>>print(cmd)
   a string
>>>cmd = cmd + "\n"
>>>print(cmd)
   a string
                              #note following blank line
>>>print(cmd.encode('ascii'))
   b'a string\n'

If I were to execute:

>>>serial.write(cmd.encode('ascii'))

exactly what would be sent? would it include the initial b, as in the print statement? would it include the single quotes? would it send the ascii byte code for the newline character (0x0A), or ascii byte codes for backslash (0x5C) and "n" (0x6E)?

1 Answers1

0

Ugh. Working with strings and byte strings in Python3 can be very frustrating and confusing when you first encounter them. This answer has a nice explanations of this.

PySerial works with byte strings. To write a string to a serial port, you'll have to encode() it to a byte string. And to read from the serial port into a string, you have to decode().

In your code, if you can keep everything as byte strings, you can avoid doing all of the encoding and decoding. But you have remember to type an extra b character:

cmd = b"a string" 
cmd = cmd + b"\n"
serial.write(cmd)

Or you can also choose to encode/decode:

cmd = "a string" 
cmd = cmd + "\n"
serial.write(cmd.encode('ascii'))

The Python interactive shell will represent well-known ascii chars as their escape codes:

>>> '\x0a';'\x0d'
'\n'
'\r'

And many chars will be left as a byte representation:

>>> '\x00'; '\x01'
'\x00'
'\x01'

Getting back to your Question, if you send

serial.write(b"a string\n")

the b does not get send and \n is sent as chr(10) or b'\x0a'.

bfris
  • 5,272
  • 1
  • 20
  • 37