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

mpremote

Linux, macOS, Windows

Micro REPL

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:

  1. Save the example as a local file, let’s say AutoBlinky as example.py.

  2. 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)
  1. Boot flow3r and let it fully start up into the menu screen.

  2. 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

  1. To use this, add the following to /etc/udev/rules.d/60-extra-acl.rules: KERNEL=="ttyACM[0-9]*", TAG+="udev-acl", TAG+="uaccess"

  2. 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