This is a variant of codal_port which is compiled with Emscripten. It provides a simulated micro:bit REPL in the browser.
To build, first fetch the submodules (don't use recursive fetch):
$ git submodule update --init lib/micropython-microbit-v2
$ git -C lib/micropython-microbit-v2 submodule update --init lib/micropython
Then run (from this top-level directory):
$ make
Once it is build the webpage in src/ needs to be served, eg via:
$ (cd build && python -m http.server)
Then browse to http://localhost:8000/demo.html
The main branch is deployed to https://stage-python-simulator.microbit.org/ by CircleCI.
Other branches are deployed to https://review-python-simulator.microbit.org/{branchName} by CircleCI.
There is currently no stable deployment. The URLs above are under active development and are subject to change.
There is also a Netlify based build for development purposes only. Netlify's GitHub integration will comment on PRs with deployment details.
The simulator is designed to be embedded into other web applications via an iframe.
The page to embed is http://localhost:8000/simulator.html
The iframe provides the micro:bit board user interface and some limited interactions. It does not provide a terminal for serial output or the REPL or any UI for the sensors. A value for color can be passed to the simulator via a query string and is used to style the play button. E.g., http://localhost:8000/simulator.html?color=blue
demo.html is an example of embedding the simulator. It connects the iframe to a terminal and provides a simple interface for sensors.
The following sections documents the messages supported via postMessage.
| Kind | Example | Description |
|---|---|---|
| ready |
{
"kind": "ready",
"state": {
"lightLevel": {
"id": "lightLevel",
"type": "range",
"min": 0,
"max": 255
},
"soundLevel": {
"id": "soundLevel",
"type": "range",
"min": 0,
"max": 255
// Microphone sensor only:
"lowThreshold": 50,
"highThreshold": 150
}
// Full state continues here.
}
} | Sent when the simulator is ready for input. Includes a description of the available sensors. |
| sensor_change |
{
"kind": "state_change",
"change": {
"soundLevel": {
"id": "soundLevel",
"type": "range",
"min": 0,
"max": 255
// Microphone sensor only:
"lowThreshold": 50,
"highThreshold": 150
}
// Optionally, further keys here.
}
]
} | Sent when the simulator state changes. The keys are a subset of the original state. The values are always sent in full. |
| request_flash |
{
"kind": "request_flash",
} | Sent when the user requests the simulator starts. The embedder should flash the latest code via the flash message.
|
| serial_output |
{
"kind": "serial_output",
"data": "text"
} | Serial output suitable for a terminal or other use. |
| radio_output |
{
"kind": "radio_output",
"data": new Uint8Array([])
} | Radio output (sent from the user's program) as bytes. If you send string data from the program then it will be prepended with the three bytes 0x01, 0x00, 0x01. |
| internal_error |
{
"kind": "internal_error",
"error": new Error()
} | A debug message sent for internal (unexpected) errors thrown by the simulator. Suitable for application-level logging. Please raise issues in this project as these indicate a bug in the simulator. |
| Kind | Example | Description |
|---|---|---|
| flash |
{
"kind": "flash",
"filesystem": {
"main.py":
new TextEncoder()
.encode("# your program here")
}
} | Update the micro:bit filesystem and restart the program. |
| stop |
{
"kind": "stop"
} | Stop the program. |
| reset |
{
"kind": "reset"
} | Reset the program. |
| mute |
{
"kind": "mute"
} | Mute the simulator. |
| unmute |
{
"kind": "unmute"
} | Unmute the simulator. |
| serial_input |
{
"kind": "serial_input",
"data": "text"
} | Serial input. If the REPL is active it will echo this text via serial_write.
|
| sensor_set |
{
"kind": "set_value",
"id": "lightLevel",
"value": 255
} | Set a sensor, button or pin value. The sensor, button or pin is identified by the top-level key in the state. Buttons and pins (touch state) have 0 and 1 values. In future, analog values will be supported for pins. |
| radio_input |
{
"kind": "radio_input",
"data": new Uint8Array([])
} | Radio input (received by the user's program as if sent from another micro:bit) as bytes.
If you want to send string data then prepend the byte array with the three bytes 0x01, 0x00, 0x01.
Otherwise, the user will need to use radio.receive_bytes or radio.receive_full. The input is assumed to be sent to the currently configured radio group.
|
- Update the lib/micropython-microbit-v2 to the relevant hash. Make sure that its lib/micropython submodule is updated (see checkout instructions above).
- Review the full diff for micropython-microbit-v2. In particular, note changes to:
- main.c, src/Makefile and mpconfigport.h all which have simulator versions that may need updates
- the HAL, which may require implementing in the simulator
- the filesystem, which has a JavaScript implementation.
Steps for WASM debugging in Chrome:
- Add the source folder
- Install the C/C++ debug extension: https://helpgoo.gle/wasm-debugging-extension
- Enable "WebAssembly Debugging: Enable DWARF support" in DevTools Experiments.
- DEBUG=1 make