Environment
The main programming interface and language for flow3r is Python, or rather Micropython, which is a fairly sizeable subset of Python that can run on microcontrollers.
Good news: if you’ve ever used Micropython on an ESP32, then you probably already have all the tools required to get started. However, while the tools to program the badge might be the same as for stock Micropython on ESP32, our APIs are quite different.
If you haven’t used Micropython, there are plenty of code examples and tutorials on the internet. Since most rules of Python apply, the vast resources available for it often apply just as well for many basic operations.
The best way to learn is of course trial and error, so let’s learn first how to try out code on flow3r!
Running applications
You don’t need to install much for developing applications on flow3r, in fact it can be done only with a text editor and file manager by copying your prototypes into the filesystem, but we highly recommend a convenience tool that allows to run application code directly from your computer. These are the tools we tested and are known to work:
Tool |
Platforms |
---|---|
Linux, macOS, Windows |
|
Android |
In the rest of these docs we’ll use mpremote.
When the badge runs (for example, when you see the main menu), you can connect
it to a PC and it should appear as a serial device. On Linux systems, this
device will be usually called /dev/ttyACM0
(sometimes /dev/ttyACM1
).
If it is not that default port, you may need to specify it manually;
For example, if you are on Linux and your flow3r came up as /dev/ttyACM1
,
add an a1
after mpremote
for any command.
After connecting your badge and making sure it runs. You should see this output:
$ mpremote
Connected to MicroPython at /dev/ttyACM0
Use Ctrl-] or Ctrl-x to exit this shell
[... logs here... ]
Congratulations, your toolchain setup is now complete! To run the examples from the Blinky section, you simply need to do the following:
Save the example as a local file, let’s say
AutoBlinky
as example.py.Add some lines to the end of the file that tells mpremote how to run which class. We always use
st3m.run.run_app()
with the class of the application (AutoBlinky
in this case). There’s other optional arguments that we’ll go into later, but for many basic cases this is sufficient.
if __name__ == "__main__":
import st3m.run
st3m.run.run_app(AutoBlinky)
Boot flow3r and let it fully start up into the menu screen.
Run
mpremote run example.py
. The application should now run.
You can now edit example.py however you like, exit mpremote with Ctrl-C and run
mpremote run example.py
again to immediately try out your changes. This is the
primary development loop on flow3r. There’s still a few tools and techniques that
might make your life easier, but this is the central one, and you can feel free to
take a break from reading here to play around with it :D.
Note: Like all great hardware, flow3r sometimes needs a hard reboot. If mpremote run stops working, just power cycle it, let it fully boot and try again.
Warning
Your flow3r is not showing up using Linux?
To let mpremote
to work properly your user needs to have access rights to ttyACM.
Quick fix: sudo chmod a+rw /dev/ttyACM[Your Device Id here]`
More sustainable fix: Setup an udev rule to automatically allow the logged in user to access ttyUSB
To use this, add the following to /etc/udev/rules.d/60-extra-acl.rules:
KERNEL=="ttyACM[0-9]*", TAG+="udev-acl", TAG+="uaccess"
Reload
udevadm control --reload-rules && udevadm trigger
Using the REPL
Micropython features a REPL that we can connect to from a computer. This allows us to type in commands and check their output (and interaction with the hardware) in realtime. Especially if you are a beginner this is a very easy way to test snippets in a quick and interactive way.
You can then use any terminal emulator program (like picocom, GNU screen, etc) or just mpremote to access the badge’s runtime logs. Now, if you press Ctrl-C, you will interrupt the firmware and break into a Python REPL (read-eval-print-loop) prompt:
Traceback (most recent call last):
File "/flash/sys/main.py", line 254, in <module>
[... snip ...]
KeyboardInterrupt:
MicroPython c48f94151-dirty on 1980-01-01; badge23 with ESP32S3
Type "help()" for more information.
>>>
The badge’s display will now switch to ‘In REPL’ to indicate that software execution has been interrupted and that the badge is waiting for a command over REPL.
Congratulations! You can now use your badge as a calculator:
>>> 5 + 5
10
But that’s not super interesting. Let’s try to turn on some LEDs:
>>> import leds
>>> leds.set_all_rgb(0.5, 0, 0.5)
>>> leds.update()
The LEDs should now light up purple - maybe! Depending on which state flow3r was in before this change might be very slow. It is very slow for example if you call it directly after booting in the main menu - look again, mayhaps they have changed by now ;)?
This is because the low level state of flow3r is not reset automatically when you enter the REPL. During boot the operating system sets the LED driver update speed to “very very slow” for a gradual fade-in and just leaves it at that until the user enters an application.
This might seem annoying at first, but it allows for an important debug channel. If you’re not sure if your drivers are set up properly, you can always interrupt your application to check them. Imagine one petal input isn’t working properly, we could check if it’s maybe misconfigured by interrupting the application while the bug is present and checking:
>>> import captouch
>>> conf = captouch.Config.current()
>>> conf.petals[5].logging
False
If we do want to set up the default app configuration in the REPL, we can do it manually like this:
>>> from st3m import application
>>> application.setup_for_app()
Note that some APIs might not be working properly when used raw in the REPL as mentioned in their respective documentations.
Transferring files over REPL
You can access the filesystem both from mpremote and of course micropython itself. There are further commands to copy, delete, etc files.
$ mpremote
MicroPython c48f94151-dirty on 1980-01-01; flow3r with ESP32S3
Type "help()" for more information.
>>> import os
>>> os.listdir('/')
['flash']
>>> os.listdir('/flash/sys')
['main.py', 'st3m', '.sys-installed']
>>>
$ mpremote ls :/flash/sys
ls :/flash/sys
0 main.py
0 st3m
0 .sys-installed
Disk Mode
For larger file transfers (eg. images, sound samples, etc.) you can put the
badge into Disk Mode by selecting Settings -> Disk Mode
in the badge’s menu.
You can then select whether to mount the 10MiB internal flash or SD card (if present) as a pendrive. The selected device will then appear as a pendrive on your system, and will stay until it is ejected. The serial connection will disconnect for the duration of the badge being in disk mode.
Disk Mode can also be enabled when the badge is in Recovery Mode.
Using the simulator
The flow3r badge firmware repository comes with a Python-based simulator which allows you to run the Python part of st3m on your local computer, using Python, Pygame and wasmer.
Currently the simulator supports the display, LEDs, the buttons, accelerometer (in 2D) and some static input values from the gyroscope, temperature sensor and pressure sensor.
It does not support most of the audio APIs. It also does not support positional captouch APIs.
To set the simulator up, clone the repository and prepare a Python virtual environment with the required packages:
$ git clone https://git.flow3r.garden/flow3r/flow3r-firmware
$ cd flow3r-firmware
$ python3 -m venv venv
$ venv/bin/pip install pygame requests pymad
$ venv/bin/pip install wasmer wasmer-compiler-cranelift
Warning
The wasmer python module from PyPI doesn’t work with Python versions 3.10 or 3.11. You will get
ImportError: Wasmer is not available on this system
when trying to run
the simulator.
Instead, install our rebuilt wasmer wheels using
venv/bin/pip install https://flow3r.garden/tmp/wasmer-py311/wasmer_compiler_cranelift-1.2.0-cp311-cp311-manylinux_2_34_x86_64.whl
venv/bin/pip install https://flow3r.garden/tmp/wasmer-py311/wasmer-1.2.0-cp311-cp311-manylinux_2_34_x86_64.whl
You can then run the simulator:
$ venv/bin/python sim/run.py
Grey areas near the petals and buttons can be pressed.
The 3-way switches can be controlled with keyboard keys and have a default
mapping of 1
, 2
, 3
for the left and 8
, 9
, 0
for the
right switch. This mapping can be changed by copying sim/config.py.default
to sim/config.py
and adjusting it to personal preference.
The simulators apps live in python_payload/apps
copy you app folder in there
and it will appear in the simulators menu system.
If you want to start an app directly, simply give its name (the [app] -> name
in
flow3r.toml
) as an argument:
$ venv/bin/python sim/run.py Worms