Lab 6: Deploying Code and Libraries
Time: ~40 minutes | Prerequisites: Lab 5 | Hardware: Pico 2, OLED, buttons
Let's cut the cord
So far your Pico has needed a laptop the way a puppet needs a hand. By the end of this
lab it runs on its own from a phone charger. Time to transform!
What You'll Build
A program that inspects the board's own filesystem and import machinery — then a main.py that
makes your Pico run standalone, no computer attached.
Learning Objectives
- Explain how
importfinds a module, usingsys.path - Describe what
/libis for and why drivers live there - List and inspect files on the device filesystem
- Create a
main.pythat runs automatically at power-up - Recover a board whose
main.pymisbehaves
Concepts Introduced
| ID | Concept |
|---|---|
| 249 | File Transfer To Device |
| 250 | mpremote Tool |
| 251 | Library Directory |
| 252 | Import Path |
| 253 | Module Import |
| 254 | Autorun main.py |
| 255 | Standalone Operation |
| 256 | Code Organization |
Background
How import actually works
When you write import config, MicroPython walks a list of places called sys.path, in order,
looking for config.py. On your board that list is:
1 | |
| Entry | Meaning |
|---|---|
'' |
the device's root directory |
.frozen |
modules baked into the firmware itself |
/lib |
the conventional home for libraries |
So import config finds /config.py, and import ssd1306 finds /lib/ssd1306.py. Nothing
mysterious — just a search through three folders.
Two filesystems, easily confused
Thonny's Files panel shows your computer on top and the Pico underneath. A file open from your laptop doesn't exist on the chip at all. This is the single most common way to lose twenty minutes in this course.
How this course puts code on your board
All 35 labs' code is pre-loaded for you, using upload-code.sh in the kit directory.
It uses a tool called mpremote — the command-line way to talk to a Pico. If you ever
need to reset your board to a clean state, that script is how.
main.py: the autorun file
Two filenames are special to MicroPython:
| File | When it runs |
|---|---|
boot.py |
first, at power-up — for low-level setup |
main.py |
immediately after, every power-up |
Put your program in main.py and the board becomes an appliance. Plug it into a USB charger
and it just works.
Procedure
Step 1 — Inspect your board
Open 06-deploying-code.py and run it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | |
It prints sys.path, lists the root directory and /lib, proves import config worked, and
reports your flash usage.
Step 2 — Trace an import yourself
In the REPL:
1 2 3 4 5 6 7 | |
You've just followed the search path by hand.
Step 3 — Go standalone
Look at main.py.example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
Copy it to your Pico and rename it to main.py. Then unplug the board from your computer
and plug it into a phone charger.
It runs. No laptop. That's an embedded product.
Always leave yourself an escape hatch
Notice the three-second delay at the top of main.py before anything else happens. A
main.py that jumps straight into a tight loop can make the board hard to interrupt —
it's busy running your program before you can get a word in. That delay is your window
to press Ctrl-C. Put one in every main.py you write.
Step 4 — Rescue a board
If a main.py ever locks you out:
- Connect in Thonny and press Ctrl-C repeatedly while it boots.
- If that fails, delete the file over the REPL:
1 2
import os os.remove('main.py') - Last resort: hold BOOTSEL while plugging in and re-flash MicroPython. This erases
everything — you'd re-run
upload-code.shafterwards.
Knowing step 3 exists is what lets you experiment fearlessly.
Expected Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
ImportError: no module named 'config' |
File is on your laptop, not the Pico | Check the Raspberry Pi Pico half of the Files panel |
ImportError: no module named 'ssd1306' |
Driver missing from /lib |
Re-run upload-code.sh |
main.py won't stop |
No escape hatch | Ctrl-C during boot, or os.remove('main.py') |
| Board seems bricked | Bad main.py |
BOOTSEL + re-flash, then re-upload |
| Edits keep disappearing | Editing the laptop copy | Reopen from the Pico side |
| Changed a module but behaviour is stale | Module already imported | Soft-reset (Ctrl-D) — imports are cached |
Challenges
- Make your own library. Write
mymath.pywith a function, put it in/lib, and import it from a separate program. You've just built a reusable module. - Boot counter. Have
main.pyread a count from a file, add one, display it, and write it back. Now your board remembers across power cycles. - Button-selected startup. Have
main.pycheck whether button A is held at boot, and run a different program if it is. That's a genuinely useful pattern for a shipped device.
Check Your Understanding
- What does
sys.pathcontain, and in what order is it searched? - Why do drivers go in
/librather than the root? - What's the difference between
boot.pyandmain.py? - Why should every
main.pystart with a delay? - Your edits vanish each time you unplug. What's the most likely cause?
Setup complete — now the fun starts
Screen, buttons, standalone operation, and a chip that knows its own name. That's the
entire foundation. Next lab we plug in a microphone — and everything after that is
about turning sound into insight. Now that's a superpower.
Next: Lab 7: Your First Sound Capture | Previous: Lab 5