Skip to content

Commit 01d6d48

Browse files
committed
update documentation
Signed-off-by: Jos Verlinde <jos_verlinde@hotmail.com>
1 parent 14848fb commit 01d6d48

14 files changed

Lines changed: 1013 additions & 24213 deletions

development_status.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
# initial
3+
4+
- [x] run a code cell on a MCU
5+
- [x] mpremote primitives
6+
- [x] list connected boards and loop through them
7+
- [x] switch the active MCU
8+
- [x] avoid resetting MCU between cells ( use `resume`)
9+
- [x] soft-reset a MCU
10+
- [/] hard-reset a MCU
11+
- only works on non-rp2040 devices
12+
- report / fix hardware reset issue on rp2040 `machine.reset()` ?
13+
- [x] mount folder
14+
- [?] recursive delete wipe files from MCU - as a built-in magic ? / wait for / create PR for mpremote update ?
15+
- [x] cellmagic to copy cell content to specific files on the MCS
16+
- [x] %%micropython --writefile main.py
17+
- [x] %%micropython --readfile boot.py
18+
19+
20+
**`!mpremote` can be use to run any other command**
21+
- [x] **`!mpremote`** mip install
22+
- [x] direct - copy file / files to / from
23+
- [x] ls and other file operations
24+
- [ ] Notebook essentials
25+
- [x] load magics from `%pip install micropython-magic`
26+
- [x] get the output from the MCU into a python variable `local = %eval remote`
27+
- eval is not quite the same as mpremote
28+
- [x] retain type through json - works for the majority of standard types
29+
- [?] can this be done with repr(instead) of json ?
30+
- [x] plot data from a MCU
31+
- [x] using bqplot ( > pyplot > vscode-Jupyter)
32+
- [/] add documentation / sample
33+
-
34+
- [ ] copy/echo MCU global vars to local vars ( sync_from / sync_to)?
35+
- [ ] get a data series onto the notebook and plot the outcome
36+
- [x] loop one by one and update plot
37+
- [ ] get larger series
38+
- [ ] loop and update plot
39+
https://ipywidgets.readthedocs.io/en/7.x/examples/Widget%20Asynchronous.html#Updating-a-widget-in-the-background
40+
- [ ] long running via mqtt / async / folder mount ?
41+
- [ ] is there a way to avoid needing to set %%micropython on all cells ?
42+
this could be done via an input_transformer - but keeping the state between cells may be quite hard / confusing
43+
- [ ] %timeit / %%timeit for micropython code to avoid measuring the mpremote startup overhead
44+
45+
Samples
46+
- [x] Install
47+
- [x] basic board control
48+
- [x] blink
49+
- [x] list connected boards and loop through them
50+
- [~] read sensor and build series ( file / list / plot)
51+
- [ ] flash a mcu with new firmware ( sample per port )
52+
- [ ] mip install
53+
- [ ] upload a repo / folder to a MCU
54+
55+
## development
56+
## Testing
57+
58+
- using Pytest
59+
- using testbook for testing notebooks
60+
- located in the `./tests/` folder
61+
- tests are paired with notebooks that contain the cells and magic commands to be tested
62+
- tests have not been mocked - and therefore require a connected MCU to run ( rp2040 )
63+
64+
- [x] Local on windows
65+
- [x] on windows
66+
- [x] on linux
67+
- [ ] on MacOS
68+
- Manual test:
69+
- [x] jupyter notebook
70+
- [x] jupyter labs
71+
72+
- [ ] CI - using WOKWI as a device simulator ?
73+
Blocked as WOKWI CI does not implement serial connection
74+

docs/logo.jpg

84.4 KB
Loading

docs/logo_M.jpg

36.5 KB
Loading

docs/logo_S.jpg

21.6 KB
Loading

readme.md

Lines changed: 57 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# micropython-magic
2-
[![CodeFactor](https://www.codefactor.io/repository/github/josverl/micropython-magic/badge/main)](https://www.codefactor.io/repository/github/josverl/micropython-magic/overview/main)
2+
![PyPI](https://img.shields.io/pypi/v/micropython-magic?style=plastic)
3+
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/micropython-magic?style=plastic)
4+
![PyPI - License](https://img.shields.io/pypi/l/micropython-magic?style=plastic)
5+
![PyPI - Downloads](https://img.shields.io/pypi/dm/micropython-magic?style=plastic)
6+
7+
<img src="docs/logo_S.jpg" width="100" align="right">
8+
9+
310

411
These Jupyter magic methods allow MicroPython to be used from within any Jupyter Notebook or JupyterLab (formerly IPython Notebook)
512
The magics make use of the [mpremote tool](https://github.com/micropython/micropython/blob/master/tools/mpremote/README.md) to enable communication with the MCUs
@@ -9,20 +16,19 @@ This allows:
916
* Mixing of Host and MCU Code ( and languages if you wish)
1017
* Creating graphs of the data captured by MCU sensors
1118
* create re-uasable sequences ( download/compile firmware - flash firmware - uploade code - run expiriment - same outcome)
12-
* create and execute tests that require orchestration across multiple MCUs and hosts
19+
* Create and execute tests that require orchestration across multiple MCUs and hosts
1320
* Rapid Prototyping
14-
* Capturing the results and outputs in a consistent way
21+
* Capturing the results and outputs of your expiriments in a consistent way
1522
* Mixing documentation with code
1623

1724

18-
19-
## Samples
25+
## A few of the possibilities
2026

2127
<table>
2228

2329
<tr>
2430
<td>
25-
Plot cpu temperature
31+
Live Plot of the cpu temperature
2632

2733
<img src="docs/cpu_plot.gif" width="300" />
2834
</td>
@@ -98,12 +104,23 @@ Tested in VSCode with
98104
- [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) extension
99105
- [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) extension
100106

107+
## More Examples
108+
109+
Please refer to the [samples folder](samples/) for more examples
110+
111+
112+
1. [install](samples/install.ipynb) - install the magic
113+
1. [board_control](samples/board_control.ipynb) - basic board control
114+
1. [board_selection.](samples/board_selection.ipynb) - list connected boards and loop through them
115+
1. [device_info](samples/device_info.ipynb) - Get simple access to port, board and hardware and firmware information
116+
1. [WOKWI](samples/wokwi.ipynb) - Use MicroPython magic with WOKWI as a simulator (no device needed)
117+
1. [Plot rp2 CPU temp](samples/plot_cpu_temp_rp2.ipynb) - create a plot of the CPU temperature of a rp2040 MCU(bqplot)
118+
1. [Display Memory Map](samples/mem_info.ipynb) - Micropython memory map visualizer
119+
1. [Plot Memory Usage](samples/mem_info-plot.ipynb) - plot the memory usage of a Micropython script running on a MCU over time
120+
121+
<!-- 1. [](samples/mem_info_list.ipynb) - not currently working used to trace the m -->
122+
101123

102-
## Advanced
103-
List the connected devices
104-
```python
105-
%mpy --list
106-
```
107124

108125
## Automatically load the magic on startup
109126

@@ -114,77 +131,39 @@ In order to automatically load the magic on startup, you can add the following t
114131
- add the following to the configuration file (`.../.ipython/profile_default/ipython_config.py`)
115132

116133
```python
117-
c = get_config() #noqa
134+
c = get_config()
118135

119136
c.InteractiveShellApp.extensions = [
120137
'micropython_magic'
121138
]
122139
```
140+
## Configuration options
141+
142+
Configuration can be done via the `%config` magic
143+
144+
```python
145+
%config MicroPythonMagic
146+
147+
MicroPythonMagic(Magics) options
148+
------------------------------
149+
MicroPythonMagic.loglevel=<UseEnum>
150+
Choices: any of ['TRACE', 'DEBUG', 'INFO', 'WARNING', 'ERROR']
151+
Current: <LogLevel.WARNING: 'WARNING'>
152+
MicroPythonMagic.timeout=<Float>
153+
Current: 300.0
154+
155+
# example
156+
%config MicroPythonMagic.loglevel = 'TRACE'
157+
```
158+
- loglevel : set the loglevel for the magic ( default WARNING)
159+
- timeout : set the timeout for the mpremote connection ( default 300 seconds - 5 minutes)
160+
161+
## Development and contributions
123162

124-
# initial
125-
126-
- [x] run a code cell on a MCU
127-
- [ ] mpremote primitives
128-
- [x] list connected boards and loop through them
129-
- [x] switch the active MCU
130-
- [x] avoid resetting MCU between cells ( use `resume`)
131-
- [x] soft-reset a MCU
132-
- [/] hard-reset a MCU
133-
- only works on non-rp2040 devices
134-
- report / fix hardware reset issue on rp2040 `machine.reset()` ?
135-
- all mpremote commands are possible using `!mpremote`
136-
- [ ] mip install
137-
- [ ] direct - copy file / files to / from
138-
- [ ] mount folder
139-
- [ ] ls and other file operations
140-
- [ ] recursive delete wipe files from MCU - as a built-in magic ? / wait for / create PR for mpremote update ?
141-
- [ ] cellmagic to copy cell content to specific files on the MCS
142-
- [ ] %%micropython --writefile main.py
143-
- [ ] %%micropython --readfile boot.py
144-
- [ ] Notebook essentials
145-
- [x] load magics from `%pip install micropython-magic`
146-
- [x] get the output from the MCU into a python variable `local = %eval remote`
147-
- eval is not quite the same as mpremote
148-
- retain type through json ?
149-
- [?] can this be done with repr(insted) of json ?
150-
- [x] plot data from a MCU
151-
- [x] using bqplot ( > pyplot > vscode-Jupyter)
152-
- [/] add documentation / sample
153-
-
154-
- [ ] copy/echo MCU global vars to local vars ( sync_from / sync_to)?
155-
- [ ] get a data series onto the notebook and plot the outcome
156-
- [x] loop one by one and update plot
157-
- [ ] get larger series
158-
- [ ] loop and update plot
159-
https://ipywidgets.readthedocs.io/en/7.x/examples/Widget%20Asynchronous.html#Updating-a-widget-in-the-background
160-
- [ ] long running via mqtt / async / folder mount ?
161-
- [ ] is there a way to avoid needing to set %%micropython on all cells ?
162-
this could be done via an input_transformer - but keeping the state between cells may be quuite hard / confusing
163-
- [ ] %timeit / %%timeit for micropython code to avoid measuring the mpremote startup overhead
164-
165-
Samples
166-
- [x] Install
167-
- [x] basic board control
168-
- [x] blink
169-
- [x] list connected boards and loop through them
170-
- [~] read sensor and build series ( file / list / plot)
171-
- [ ] flash a mcu with new firmware ( sample per port )
172-
- [ ] mip install
173-
- [ ] upload a repo / folder to a MCU
174-
175-
## development
176-
## Testing
177-
178-
- using Pytest
179-
- using testbook for testing notebooks
180-
- located in the `./tests/` folder
181-
- tests are paired with notebooks that contain the cells and magic commands to be tested
182-
- tests have not been mocked - and therefore require a connected MCU to run ( rp2040 )
183-
184-
- TODO: add tests for (remote) kernels
185-
- [x] Local (on windows)
186-
- [ ] on windows
187-
- [ ] on linux
188-
- [ ] jupyter notebook
189-
- [ ] jupyter labs
163+
The most welcome contributions are :
164+
- Testing on different platforms (OS) but also different Jupyter environments ( Jupyter Notebook, JupyterLab, VSCode)
165+
- Provide additional sample notebooks
166+
- Help add documentation (preferably in a notebook or .md file)
167+
- Share this with other people that may be interested in this.
190168

169+
[See current status](development_status.md) and on Github

samples/device_info.ipynb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
22
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"**Get simple access to port, board and firmware information and many other details**"
8+
]
9+
},
310
{
411
"cell_type": "code",
512
"execution_count": 1,
@@ -137,7 +144,7 @@
137144
"name": "python",
138145
"nbconvert_exporter": "python",
139146
"pygments_lexer": "ipython3",
140-
"version": "3.11.4"
147+
"version": "3.11.7"
141148
},
142149
"orig_nbformat": 4
143150
},

samples/install.ipynb

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -215,28 +215,30 @@
215215
},
216216
{
217217
"cell_type": "code",
218-
"execution_count": 12,
218+
"execution_count": 1,
219219
"metadata": {},
220220
"outputs": [
221221
{
222-
"ename": "ConnectionError",
223-
"evalue": "no device found",
224-
"output_type": "error",
225-
"traceback": [
226-
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
227-
"\u001b[1;31mConnectionError\u001b[0m Traceback (most recent call last)",
228-
"Cell \u001b[1;32mIn[12], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m get_ipython()\u001b[39m.\u001b[39;49mrun_line_magic(\u001b[39m'\u001b[39;49m\u001b[39mmpy\u001b[39;49m\u001b[39m'\u001b[39;49m, \u001b[39m'\u001b[39;49m\u001b[39m--eval 2*3*7\u001b[39;49m\u001b[39m'\u001b[39;49m)\n",
229-
"File \u001b[1;32mc:\\develop\\MyPython\\micropython-magic\\.venv\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:2414\u001b[0m, in \u001b[0;36mInteractiveShell.run_line_magic\u001b[1;34m(self, magic_name, line, _stack_depth)\u001b[0m\n\u001b[0;32m 2412\u001b[0m kwargs[\u001b[39m'\u001b[39m\u001b[39mlocal_ns\u001b[39m\u001b[39m'\u001b[39m] \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mget_local_scope(stack_depth)\n\u001b[0;32m 2413\u001b[0m \u001b[39mwith\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mbuiltin_trap:\n\u001b[1;32m-> 2414\u001b[0m result \u001b[39m=\u001b[39m fn(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[0;32m 2416\u001b[0m \u001b[39m# The code below prevents the output from being displayed\u001b[39;00m\n\u001b[0;32m 2417\u001b[0m \u001b[39m# when using magics with decodator @output_can_be_silenced\u001b[39;00m\n\u001b[0;32m 2418\u001b[0m \u001b[39m# when the last Python token in the expression is a ';'.\u001b[39;00m\n\u001b[0;32m 2419\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mgetattr\u001b[39m(fn, magic\u001b[39m.\u001b[39mMAGIC_OUTPUT_CAN_BE_SILENCED, \u001b[39mFalse\u001b[39;00m):\n",
230-
"File \u001b[1;32mC:\\develop\\MyPython\\micropython-magic\\src\\micropython_magic\\octarine.py:247\u001b[0m, in \u001b[0;36mMpyMagics.mpy_line\u001b[1;34m(self, line)\u001b[0m\n\u001b[0;32m 245\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlist_devices()\n\u001b[0;32m 246\u001b[0m \u001b[39melif\u001b[39;00m args\u001b[39m.\u001b[39meval:\n\u001b[1;32m--> 247\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49meval(args\u001b[39m.\u001b[39;49meval)\n\u001b[0;32m 249\u001b[0m \u001b[39melif\u001b[39;00m args\u001b[39m.\u001b[39mstatement:\n\u001b[0;32m 250\u001b[0m \u001b[39m# Assemble the command to run\u001b[39;00m\n\u001b[0;32m 251\u001b[0m statement \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mjoin(args\u001b[39m.\u001b[39mstatement)\n",
231-
"File \u001b[1;32mC:\\develop\\MyPython\\micropython-magic\\src\\micropython_magic\\octarine.py:272\u001b[0m, in \u001b[0;36mMpyMagics.eval\u001b[1;34m(self, line)\u001b[0m\n\u001b[0;32m 270\u001b[0m cmd \u001b[39m=\u001b[39m \u001b[39mf\u001b[39m\u001b[39m'''\u001b[39m\u001b[39mexec \u001b[39m\u001b[39m\"\u001b[39m\u001b[39mimport json; print(\u001b[39m\u001b[39m'\u001b[39m\u001b[39m{\u001b[39;00mJSON_START\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m,json.dumps(\u001b[39m\u001b[39m{\u001b[39;00mstatement\u001b[39m}\u001b[39;00m\u001b[39m),\u001b[39m\u001b[39m'\u001b[39m\u001b[39m{\u001b[39;00mJSON_END\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m)\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m'''\u001b[39m\n\u001b[0;32m 271\u001b[0m \u001b[39m# print(cmd)\u001b[39;00m\n\u001b[1;32m--> 272\u001b[0m output \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mMCU\u001b[39m.\u001b[39;49mrun_cmd(cmd)\n\u001b[0;32m 273\u001b[0m matchers \u001b[39m=\u001b[39m [\u001b[39mr\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m^.*Error:\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39mr\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m^.*Exception:\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m 275\u001b[0m \u001b[39mfor\u001b[39;00m ln \u001b[39min\u001b[39;00m output\u001b[39m.\u001b[39ml:\n\u001b[0;32m 276\u001b[0m \u001b[39m# check for errors and raise them\u001b[39;00m\n",
232-
"File \u001b[1;32mC:\\develop\\MyPython\\micropython-magic\\src\\micropython_magic\\mpr.py:45\u001b[0m, in \u001b[0;36mMPRemote2.run_cmd\u001b[1;34m(self, cmd, auto_connect)\u001b[0m\n\u001b[0;32m 43\u001b[0m \u001b[39massert\u001b[39;00m \u001b[39misinstance\u001b[39m(output, SList)\n\u001b[0;32m 44\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(output) \u001b[39m>\u001b[39m \u001b[39m0\u001b[39m \u001b[39mand\u001b[39;00m output[\u001b[39m0\u001b[39m]\u001b[39m.\u001b[39mstrip() \u001b[39m==\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mno device found\u001b[39m\u001b[39m\"\u001b[39m:\n\u001b[1;32m---> 45\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mConnectionError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39mno device found\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 46\u001b[0m \u001b[39mreturn\u001b[39;00m output\n",
233-
"\u001b[1;31mConnectionError\u001b[0m: no device found"
234-
]
222+
"data": {
223+
"text/plain": [
224+
"42"
225+
]
226+
},
227+
"execution_count": 1,
228+
"metadata": {},
229+
"output_type": "execute_result"
235230
}
236231
],
237232
"source": [
238233
"%mpy --eval 2*3*7 "
239234
]
235+
},
236+
{
237+
"cell_type": "code",
238+
"execution_count": null,
239+
"metadata": {},
240+
"outputs": [],
241+
"source": []
240242
}
241243
],
242244
"metadata": {

0 commit comments

Comments
 (0)