adafruit / jupyter_micropython_kernel Goto Github PK
View Code? Open in Web Editor NEWJupyter kernel to interact with a MicroPython or CircuitPython board over its serial REPL.
License: MIT License
Jupyter kernel to interact with a MicroPython or CircuitPython board over its serial REPL.
License: MIT License
Currently only works through a serial line (which is pretty good), but a wifi connection would be a good alternative. Control it through %magic commands
The Kernel -> Interrupt command on the menubar should send a Control-C to the device and interrupt the program
I think this is implemented using the replwrap technology seen here
https://github.com/takluyver/bash_kernel/blob/master/bash_kernel/kernel.py
Environment (Anaconda on Windows 10):
(micropython) c:\aProject\jupyter_micropython_kernel>python -V
Python 3.6.0 :: Anaconda 4.3.0 (64-bit)
MicroPython v1.8.7-65-g7d08bc2 on 2017-01-23; PYBv1.1 with STM32F405RG
Running:
led = pyb.LED(2)
while True:
led.toggle()
pyb.delay(1000)
The LED flashes about 5 times, then the above error occurs on the console where I started the notebook. The stack trace is below. I tried increasing the timeout from 10 to 20 at line 247 of pyboard.py, this resulted in about 10 flashes before the error occurred. Decreasing the delay in the above code to 500ms resulted in about 20 flashes.
ERROR:tornado.general:Uncaught exception, closing connection.
Traceback (most recent call last):
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 414, in _run_callback
callback(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 276, in dispatcher
return self.dispatch_shell(stream, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 228, in dispatch_shell
handler(stream, idents, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 390, in execute_request
user_expressions, allow_stdin)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\kernel.py", line 47, in do_execute
result, error = self._board.exec_raw(code)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 249, in exec_raw
return self.follow(timeout, data_consumer)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 213, in follow
raise PyboardError('timeout waiting for first EOF reception')
jupyter_micropython_kernel.pyboard.PyboardError: timeout waiting for first EOF reception
ERROR:tornado.general:Uncaught exception, closing connection.
Traceback (most recent call last):
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 414, in _run_callback
callback(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 276, in dispatcher
return self.dispatch_shell(stream, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 228, in dispatch_shell
handler(stream, idents, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 390, in execute_request
user_expressions, allow_stdin)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\kernel.py", line 47, in do_execute
result, error = self._board.exec_raw(code)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 249, in exec_raw
return self.follow(timeout, data_consumer)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 213, in follow
raise PyboardError('timeout waiting for first EOF reception')
jupyter_micropython_kernel.pyboard.PyboardError: timeout waiting for first EOF reception
ERROR:tornado.general:Uncaught exception, closing connection.
Traceback (most recent call last):
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 440, in _handle_events
self._handle_recv()
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 472, in _handle_recv
self._run_callback(callback, msg)
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 414, in _run_callback
callback(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 276, in dispatcher
return self.dispatch_shell(stream, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 228, in dispatch_shell
handler(stream, idents, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 390, in execute_request
user_expressions, allow_stdin)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\kernel.py", line 47, in do_execute
result, error = self._board.exec_raw(code)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 249, in exec_raw
return self.follow(timeout, data_consumer)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 213, in follow
raise PyboardError('timeout waiting for first EOF reception')
jupyter_micropython_kernel.pyboard.PyboardError: timeout waiting for first EOF reception
ERROR:tornado.general:Uncaught exception, closing connection.
Traceback (most recent call last):
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 440, in _handle_events
self._handle_recv()
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 472, in _handle_recv
self._run_callback(callback, msg)
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 414, in _run_callback
callback(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 276, in dispatcher
return self.dispatch_shell(stream, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 228, in dispatch_shell
handler(stream, idents, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 390, in execute_request
user_expressions, allow_stdin)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\kernel.py", line 47, in do_execute
result, error = self._board.exec_raw(code)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 249, in exec_raw
return self.follow(timeout, data_consumer)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 213, in follow
raise PyboardError('timeout waiting for first EOF reception')
jupyter_micropython_kernel.pyboard.PyboardError: timeout waiting for first EOF reception
Traceback (most recent call last):
File "C:\tools\Anaconda3\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\tools\Anaconda3\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\__main__.py", line 22, in <module>
IPKernelApp.launch_instance(kernel_class=make_micropython_kernel(port, baud))
File "C:\tools\Anaconda3\lib\site-packages\traitlets\config\application.py", line 658, in launch_instance
app.start()
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelapp.py", line 474, in start
ioloop.IOLoop.instance().start()
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\ioloop.py", line 177, in start
super(ZMQIOLoop, self).start()
File "C:\tools\Anaconda3\lib\site-packages\tornado\ioloop.py", line 887, in start
handler_func(fd_obj, events)
File "C:\tools\Anaconda3\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 440, in _handle_events
self._handle_recv()
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 472, in _handle_recv
self._run_callback(callback, msg)
File "C:\tools\Anaconda3\lib\site-packages\zmq\eventloop\zmqstream.py", line 414, in _run_callback
callback(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\tornado\stack_context.py", line 275, in null_wrapper
return fn(*args, **kwargs)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 276, in dispatcher
return self.dispatch_shell(stream, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 228, in dispatch_shell
handler(stream, idents, msg)
File "C:\tools\Anaconda3\lib\site-packages\ipykernel\kernelbase.py", line 390, in execute_request
user_expressions, allow_stdin)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\kernel.py", line 47, in do_execute
result, error = self._board.exec_raw(code)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 249, in exec_raw
return self.follow(timeout, data_consumer)
File "c:\aProject\jupyter_micropython_kernel\jupyter_micropython_kernel\pyboard.py", line 213, in follow
raise PyboardError('timeout waiting for first EOF reception')
jupyter_micropython_kernel.pyboard.PyboardError: timeout waiting for first EOF reception
[I 19:37:53.059 NotebookApp] KernelRestarter: restarting kernel (1/5)
WARNING:root:kernel 42b2a430-b002-4b0b-a5b3-389c71ac699a restarted
Sometimes you need to upload actual module files. A magic command at the start of the cell, like:
%upload filename.py
should upload the contents of the cell and save it as filename.py (it could also be text or html).
This would make a good transition, from immediate hacking of code, to modules.
And, until automatic cross-compiling happens, as in this ticket:
micropython/micropython#2709
%uploadmpy filename.mpy
should cross-compile the cell and then upload it.
Cross-compilation is an inconvenient evil, necessitated by the shortness of memory in the ESP8266, because pre-compilation consumes less RAM. There is a more extreme version called frozen modules that @ShrimpingIt had to resort to, but I've not had to go that far.
Updated my trinket M0 to CircuitPython 2.2.3 and the jupyter integration is no longer working. In my logs I get:
[I 20:19:36.190 NotebookApp] Saving file at /Documents/Github/Useful-python/Mircropython/Micropython with Adafruit M0 7-2-2018.ipynb
DEBUG:jupyter_micropython_kernel.kernel:Opening MicroPython board connection on port: /dev/cu.usbmodem14341 baud: 115200
Traceback (most recent call last):
File "/anaconda3/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/anaconda3/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/anaconda3/lib/python3.6/site-packages/jupyter_micropython_kernel-0.1.0-py3.6.egg/jupyter_micropython_kernel/__main__.py", line 22, in <module>
IPKernelApp.launch_instance(kernel_class=make_micropython_kernel(port, baud))
File "/anaconda3/lib/python3.6/site-packages/traitlets/config/application.py", line 657, in launch_instance
app.initialize(argv)
File "<decorator-gen-123>", line 2, in initialize
File "/anaconda3/lib/python3.6/site-packages/traitlets/config/application.py", line 87, in catch_config_error
return method(app, *args, **kwargs)
File "/anaconda3/lib/python3.6/site-packages/ipykernel/kernelapp.py", line 457, in initialize
self.init_kernel()
File "/anaconda3/lib/python3.6/site-packages/ipykernel/kernelapp.py", line 368, in init_kernel
user_ns=self.user_ns,
File "/anaconda3/lib/python3.6/site-packages/traitlets/config/configurable.py", line 412, in instance
inst = cls(*args, **kwargs)
File "/anaconda3/lib/python3.6/site-packages/jupyter_micropython_kernel-0.1.0-py3.6.egg/jupyter_micropython_kernel/kernel.py", line 42, in __init__
self._board.enter_raw_repl()
File "/anaconda3/lib/python3.6/site-packages/jupyter_micropython_kernel-0.1.0-py3.6.egg/jupyter_micropython_kernel/pyboard.py", line 204, in enter_raw_repl
raise PyboardError('could not enter raw repl')
It's quite a hack to get the kernel.json file into the correct place. I'm sure there's a proper way of doing this to make it easier. (I don't know it either)
In Linux by running the command:
jupyter kernelspec list
I found that my kernels were in fact at:
~/anaconda3/share/jupyter/kernels/
instead of:
~/.local/share/jupyter/kernels
Hiding these settings in kernel.json in some obscure directory is a slight problem -- especially when the port can change when you plug it into a different USB lead.
Could we use one of the magic commands, like %config be able to transmit these settings to the kernel?
http://ipython.readthedocs.io/en/stable/interactive/magics.html
I proposed this idea as part of Micropython -- having independently re-invented the idea 5 months after @tdicola without the actual capability of making it work)
micropython/webrepl#32
This is such an important enough interface that it should be more widely referenced.
The Arduino/Processing combination provided the capability to print the readings of a sensor from a loop to the serial.out and direct it to a processing script that parsed the numbers and created a realtime graph.
https://itp.nyu.edu/physcomp/labs/labs-serial-communication/serial-output-from-an-arduino/
Note that in the implementation it takes two separate programs to make this happen.
This could have been done using multiple kernels in the same notebook, but this kind of thing didn't work out so well in practice: jupyterhub/jupyterhub#202
You could still do this using a different notebook page that could either read from a file, serial socket or websocket that's being filled by a micropython script/cell contents from the first notebook page.
(Graphing numbers that were printed to the serial buffer was seen as so fundamental it got put into the IDE https://www.youtube.com/watch?v=Q7rJkEjdoYE )
The following workflow could then be supported:
This is a feature of normal jupyter notebooks, so you don't have to do print(x) on the last line. Just do x.
This might be very hard to do, due to the implementation, but it's a very handy convention you get used to with normal jupyter notebooks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.