Reading from UART and KeyboardInterrupt

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
dkulinski
Posts: 3
Joined: Wed Jan 04, 2017 3:57 am

Reading from UART and KeyboardInterrupt

Post by dkulinski » Wed Jan 04, 2017 4:07 am

I am reading a RDM6300 chip on the UART. I made a modification to the Micropython firmware in accordance to what Erni T. recommended in a similar situation. The RDM chip sends a \x02 followed by 12 ascii characters followed by a \x03. The \x03 of course will generate a KeyboardInterrupt so I wrapped my uart.read in a try block and pass on KeyboardInterrupt. However, the RDM6300 will output data as long as the tag is nearby and after a couple of reads the KeyboardInterrupt breaks the program loop and I'm back to a REPL prompt.

Here is the block of code I am using to test:
[code]
try:
chars = uart.read(14)
if chars:
print(chars)
print('\r\n')
except KeyboardInterrupt:
pass
[/code]

Any pointers as to what I am doing wrong? Can I disable KeyboardInterrupts?

Thanks for any assistance!

User avatar
ernitron
Posts: 84
Joined: Fri Jun 03, 2016 5:53 pm
Location: The Netherlands

Re: Reading from UART and KeyboardInterrupt

Post by ernitron » Wed Jan 04, 2017 7:42 pm

Well, first of all thanks for giving a try to the patch for control-c. I think that should be included in the original firmware as it doesn't hurt ;)

I think the problem is that the read will fail and exit before the 14th char can be read.

Therefore I would try a loop like:

Code: Select all

        chars = bytearray()
        while len(chars)  < 14:
            try:
                chars.extend(uart.read(14 - len(chars)))
            except:
                time.sleep_ms(100)
I am pretty sure that this code can be written much better and with more efficiency. But this is the idea. Let me/us know.

EDIT: few edits ;)

dkulinski
Posts: 3
Joined: Wed Jan 04, 2017 3:57 am

Re: Reading from UART and KeyboardInterrupt

Post by dkulinski » Thu Jan 05, 2017 2:19 pm

I tried the code you have suggested. It produces the same result, a couple of reads and then a KeyboardInterrupt shows up and dumps me to a REPL prompt. With my previous code I didn't suffer short reads very often. After a couple of minutes after boot up I get this debug information to show up and sometimes the unit fails to respond.

pm open,type:2 0

This is what I am seeing, sometimes after a couple of reads or in the case on the first read (excuse the lack of code tags, I can't seem to enable BBCode):

-------------------
PyRATE 0.1 READY
--------------------
Traceback (most recent ca+-----------------------------+
File "main.py", line 39| |
KeyboardInterrupt: | Cannot open /dev/ttyUSB0! |
| |
MicroPython v1.8.6-280-ge+-----------------------------+ module with ESP8266
Type "help()" for more information.
>>>
MicroPython v1.8.6-280-ge1f495a-dirty on 2017-01-03; ESP module with ESP8266
Type "help()" for more information.
>>> 040087AF6844
>>>
MicroPython v1.8.6-280-ge1f495a-dirty on 2017-01-03; ESP module with ESP8266
Type "help()" for more information.
>>> 040087AF6844
>>>
MicroPython v1.8.6-280-ge1f495a-dirty on 2017-01-03; ESP module with ESP8266
Type "help()" for more information.
>>> 040087AF6844
>>>
MicroPython v1.8.6-280-ge1f495a-dirty on 2017-01-03; ESP module with ESP8266
Type "help()" for more information.
>>> 040087AF6844
>>>
MicroPython v1.8.6-280-ge1f495a-dirty on 2017-01-03; ESP module with ESP8266
Type "help()" for more information.
>>> 040087AF6844
>>> pm open,type:2 0

Line 39 is:
time.sleep_ms(100)

User avatar
ernitron
Posts: 84
Joined: Fri Jun 03, 2016 5:53 pm
Location: The Netherlands

Re: Reading from UART and KeyboardInterrupt

Post by ernitron » Thu Jan 05, 2017 5:26 pm

I see. You have to consider that UART is asynchronous. So it can happen anytime and everywhere in your code causing exception.

My routine is faulty as the ^C in your case happens during the time.sleep.

I suggest:
1. Make the loop tight (i.e. substitute the time.sleep with pass)
2. try-catch all other points where your sensor can send data (i.e. put a try+except KeyboardInterrupt in the main loop or where you are processing data and do not expect a manual ^C)

Last resource is to patch the firmware and eliminate the exception in uart.c but of course you'll be without manual control.

User avatar
dhylands
Posts: 3593
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Reading from UART and KeyboardInterrupt

Post by dhylands » Thu Jan 05, 2017 6:13 pm

I know that on pyboard, you can call setinterrupt(-1) on the USB_VCP device to disable Control-C (needed for binary file transfer), and I know I'd like to see something similar on the UARTs.

Currently on the pyboard there is no Control-C handling on the UARTs (so when the REPL is directed that way you can't interrupt your code). It sounds like the ESP8266 is hard-coded to process Control-C on the UART.

So anyways, I just think that the correct solution is to implement setinterrupt on the UART on all platforms.

dkulinski
Posts: 3
Joined: Wed Jan 04, 2017 3:57 am

Re: Reading from UART and KeyboardInterrupt

Post by dkulinski » Thu Jan 05, 2017 11:59 pm

Ultimately I disabled the KeyboardInterrupt from the firmware on the UART. Now it is working flawlessly. Thanks for the assistance and I hope we do see a common solution to disable this in run time in the future.

crizeo
Posts: 42
Joined: Sun Aug 06, 2017 12:55 pm
Location: Germany

Re: Reading from UART and KeyboardInterrupt

Post by crizeo » Mon Aug 21, 2017 3:10 pm

How did you disable KeyboardInterrupts from the firmware?

Update: Probably found the solution by myself (for v1.8.6, but probably working for later versions as well). When building the micropython firmware I edited the uart.c file (in the micropython/esp8266 folder). There is a function called uart0_rx_intr_handler and in there an if-else that I removed:

Code: Select all

//if (RcvChar == mp_interrupt_char) {
//    mp_keyboard_interrupt();
//} else {
ringbuf_put(&input_buf, RcvChar);
//}

Post Reply