Little copy-and-paste recipes for the code you write on a Pico, how to print, wait, read a sensor, blink the light, and so on. Grab a snippet, drop it into your program, change the parts you need. This is a reference for the MicroPython code itself, not for the website. New to a word here? The Glossary explains it.
Run the open file · Stop = Ctrl+C in the terminal ·
save as main.py and it runs at every power-up (that's "shipping").
>>> 2 + 2 # the REPL runs lines instantly >>> import machine >>> machine.reset() # full reboot from the keyboard
name = "Ada"
temp = 23.51
print("hi", name, temp)
print("T: %.1f C" % temp) # 1 decimal
print(f"{name}: {temp:.1f} C") # f-string, same idea
if temp > 30:
print("too hot!")
elif temp < 15:
print("too cold")
else:
print("just right")
for i in range(5): # 0,1,2,3,4
print(i)
while True: # forever (Ctrl+C stops)
pass
def c_to_f(c):
return c * 9 / 5 + 32
temps = [24.1, 25.0, 23.8]
temps.append(22.9)
print(len(temps), temps[0], temps[-1])
reading = {"temp_c": 24.1, "ok": True}
print(reading["temp_c"])
for t in temps:
print(t)
import time
time.sleep(1) # seconds (freezes everything!)
time.sleep_ms(250)
# non-blocking pattern (how our demos wait):
due = time.ticks_add(time.ticks_ms(), 750)
if time.ticks_diff(time.ticks_ms(), due) >= 0:
print("750 ms passed, do the thing")
from machine import Pin
led = Pin("LED", Pin.OUT) # the truth light
led.on(); led.off()
led.value(1) # same as on()
button = Pin(14, Pin.IN, Pin.PULL_UP)
print(button.value()) # 1 = not pressed
from machine import ADC soil = ADC(26) # GP26/27/28 only raw = soil.read_u16() # 0..65535 volts = raw * 3.3 / 65535 pct = raw / 65535 * 100
More channels or better precision: the ADS1115 over I2C
(from ads1115 import ADS1115).
from machine import PWM, Pin
pwm = PWM(Pin(16)); pwm.freq(50)
def angle(a): # 0..180 degrees
us = 600 + a / 180 * 1800
pwm.duty_u16(int(us * 65535 / 20000))
angle(90)
from machine import I2C, Pin i2c = I2C(0, sda=Pin(0), scl=Pin(1)) print(i2c.scan()) # [60] = 0x3C = the OLED
Empty list = wiring problem, not code. Our addresses: OLED 0x3C,
BME280 0x76/0x77, BH1750 0x23, ADS1115 0x48,
VL53L0X 0x29.
import onewire, ds18x20, time
from machine import Pin
ds = ds18x20.DS18X20(onewire.OneWire(Pin(22)))
roms = ds.scan() # one entry per probe
ds.convert_temp()
time.sleep_ms(750) # conversion takes 750 ms
for rom in roms:
print(ds.read_temp(rom))
try:
t = ds.read_temp(rom)
except Exception as e:
t = None # survive, report, retry
print("probe unhappy:", e)
House rule: a missing part never crashes a station. It shows up in the POST blinks and the program keeps going.
import asyncio
async def heartbeat():
while True:
led.on(); await asyncio.sleep_ms(100)
led.off(); await asyncio.sleep_ms(900)
async def work():
while True:
print("reading sensors...")
await asyncio.sleep(2)
async def main():
await asyncio.gather(heartbeat(), work())
asyncio.run(main())
1. Config at the top. Tunable numbers live at the top of the file in CAPS with a comment. Nobody digs in loop code to change a timing.
2. Use the truth light. Simplest programs: LED on = working. Bigger ones: POST blinks, one per part, short = OK, long = trouble, dark = not running.
3. Never crash on a missing part. try/except, report, retry.
4. Metric units. This is science.
| You see | It usually means |
|---|---|
ImportError: no module named X |
Driver missing from lib/ on the board (or a folder is shadowing it) |
OSError: [Errno 110] ETIMEDOUT / ENODEV |
Wiring: the device didn't answer. Check with i2c.scan() |
IndentationError |
Python cares about the spaces at line starts. Make them match. |
EADDRINUSE / address in use |
The old run still owns the port; our demos recover on their own |
| weird error right after an update | Stale .mpy in lib/: delete it, reinstall |
| board won't show in Viper | Charge-only USB cable. Swap it. They look identical; they are not. |