Standalone main.py
This is the program that turns your kit into a device. Rename it to main.py, copy it to the
root of the board's filesystem, and MicroPython runs it a few seconds after power arrives — no
computer, no Thonny, just USB power or a battery.
Cut the cord
Up to now every program has needed a laptop attached. After this one, your robot face wakes up on its own and starts feeling things. Great expression!
What It Does
It combines everything from the labs so far into one program that works whether or not anybody is touching it:
| Behavior | How it works |
|---|---|
| Cycles through ten modes on its own | The seven emotions, plus Blink, Wink, and Sleepy |
| Advances every 5 seconds with no input | AUTO_ADVANCE_MS |
| Holds the animated modes longer | REPEATING_HOLD_MS — 10 seconds for Blink and Wink |
| Replays animations while they are up | REPEAT_MS — every 3 seconds |
| Lets you drive it by hand | Button A forward, button B back |
| Gets out of your way when you do | Any press pushes the next auto-advance out to 30 seconds |
That last row is a small piece of interface design worth noticing. A demo that keeps advancing while somebody is trying to look at it is annoying; one that never advances again is a demo nobody sees. Thirty seconds is the compromise.
Two Rules It Follows Religiously
Both rules come from earlier labs, and both matter more here than anywhere else, because this program runs forever.
A full display.fill(BLACK) happens only when the mode changes — a few times a minute, which
is cheap enough to be invisible.
The animations that repeat inside a mode redraw only their own box. Wipe the whole screen three times a second on this display and the demo becomes a strobe light.
1 2 3 4 5 6 7 8 | |
Those two docstrings are the architecture of the whole program.
The Mode Table Carries Timing Too
The animated modes get a five-column row, because they need to describe motion as well as appearance:
1 2 3 4 5 6 7 8 | |
Blink and Wink share an enter function and differ only in how they play, which is exactly the
kind of reuse a table makes visible.
Here's one frame from the reel:

One Line You Should Not Delete
1 2 3 | |
Once this file is main.py, it starts running the moment the board powers up — including the moment
it powers up because you just plugged it into your computer. Without that one-second pause, a
fast-booting board can grab the serial port before Thonny gets a chance to break in, and getting
your board back becomes an adventure.
Rename the Copy, Not the Original
Upload 21-sample-main-demo.py and rename the copy on the board to main.py. Keep the numbered original in your project folder so you can always go back to a version you know works.
Things to Try
- Make it yours. Change the mode order, drop the emotions you do not like, and adjust
AUTO_ADVANCE_MSuntil the pacing feels right for the room it will sit in. - Add your own expression to the table once you have finished the Design Your Own Emotion lab. One row.
- Power it from a battery and put it somewhere people walk past. Watch which expressions make strangers stop, and which they ignore.
- Break it on purpose and recover. Put an error in your
main.py, upload it, and practice getting back in with Thonny's Stop/Restart. Do this once now rather than during a demo.
References
- Demo Reel — the simpler, button-free version of the same idea
- Don't Block the Loop — the
ticks_ms()pattern that lets timers and buttons share one loop - Sleeping Face — the Sleepy mode's drifting Zzz, in its own lab