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!
Reading from UART and KeyboardInterrupt
Re: Reading from UART and KeyboardInterrupt
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:
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
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)
EDIT: few edits
Re: Reading from UART and KeyboardInterrupt
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)
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)
Re: Reading from UART and KeyboardInterrupt
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.
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.
Re: Reading from UART and KeyboardInterrupt
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.
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.
Re: Reading from UART and KeyboardInterrupt
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.
Re: Reading from UART and KeyboardInterrupt
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:
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);
//}