micropython / micropython-esp32

Old port of MicroPython to the ESP32 -- new port is at https://github.com/micropython/micropython
MIT License
673 stars 216 forks source link

UART.writechar() implementation / UART.write single byte behavior #174

Closed 0xDBFB7 closed 6 years ago

0xDBFB7 commented 6 years ago

Since there's no UART.writechar() implementation, it is currently impossible to use protocols like Xmodem, insofar as I can see.


I'm pretty sure this is expected behavior,

If I do this:

sam_uart.write('\x7f')

or this:

sam_uart.write(chr(127))

And then check the output on a hex viewer, I get

0x7f

Which is correct. If I do this:

sam_uart.write(chr(128))

or this:

sam_uart.write('\x80')

I get

0xc2 0x80

If I do this:

sam_uart.write(chr(255))

I get

0xC3 0xBF

However, on an Arduino, this isn't the behavior - Serial.write, when given one byte, writes that byte verbatim.

Had me tearing my hair out.

MrSurly commented 6 years ago

It's sending the UTF8 encoding. What happens when you use a 'bytearray'?

write(b'\x80')

On Sep 1, 2017 13:40, "Daniel Correia" notifications@github.com wrote:

Since there's no UART.writechar() implementation, it is currently impossible to use protocols like Xmodem.

-- I'm pretty sure this is expected behavior,

If I do this:

sam_uart.write('\x7f')

or this:

sam_uart.write(chr(127))

And then check the output on a hex viewer, I get

0x7f

Which is correct. If I do this:

sam_uart.write(chr(128))

or this:

sam_uart.write('\x80')

I get

0xc2 0x80

If I do this:

sam_uart.write(chr(255))

I get

0xC3 0xBF

However, on an Arduino, this isn't the behavior - Serial.write, when given one byte, writes that byte verbatim.

Had me tearing my hair out.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/micropython/micropython-esp32/issues/174, or mute the thread https://github.com/notifications/unsubscribe-auth/AAYHCDFvJl88Uib6kiw3Ko1DUNND7YK2ks5seGvAgaJpZM4PKnBm .

0xDBFB7 commented 6 years ago

@MrSurly That works! However, bytearray doesn't work - it has the same problem.

MrSurly commented 6 years ago

I'm confused, did it work, or didn't it?

On Sep 1, 2017 15:39, "Daniel Correia" notifications@github.com wrote:

@MrSurly https://github.com/mrsurly That works! However, bytearray doesn't work - it has the same problem.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/micropython/micropython-esp32/issues/174#issuecomment-326698230, or mute the thread https://github.com/notifications/unsubscribe-auth/AAYHCNwn_jGsDnSCkWtWhExyOKRY_0Wpks5seIeEgaJpZM4PKnBm .

0xDBFB7 commented 6 years ago

@MrSurly Sorry, b'\x80' works, but bytearray('\x80') doesn't.

0xDBFB7 commented 6 years ago

@MrSurly For the record, bytes([0x80]) worked. Thanks for your help.

dpgeorge commented 6 years ago

but bytearray('\x80') doesn't.

That's because that piece of code converts the string "\x80" to a utf8 encoded byte stream. You can use bytearray([0x80]) or bytearray(b'\x80'), but the most efficient thing is b'\x80'.

0xDBFB7 commented 6 years ago

@dpgeorge Yup, serves me right to not learn the workings of python 3 strings before raising an issue :)

nickzoic commented 6 years ago

I'd argue this is a bug in MicroPython, because bytearray('\x80') should throw a TypeError in Python3.

Python 3.5.2 (default, Nov 17 2016, 17:05:23)

>>> bytearray([0x80])
bytearray(b'\x80')

>>> bytearray(b'\x80')
bytearray(b'\x80')

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

>>> bytearray('\x80', 'utf-8')
bytearray(b'\xc2\x80')

... throwing these exceptions is annoying, but less annoying than not throwing them!

dpgeorge commented 6 years ago

I'd argue this is a bug in MicroPython, because bytearray('\x80') should throw a TypeError in Python3.

Yes good point.