Code Snippets

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.

Running code (Viper IDE)

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

Print, variables, strings

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 / loops / functions

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

Lists and dicts

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)

Timing

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")

Pins: LED, output, input

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

Analog in (ADC)

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

Servo (PWM)

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)

I2C: who's on the bus?

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.

DS18B20 probes (OneWire)

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))

Don't crash: try / except

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.

Do two things at once (asyncio)

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())

House rules

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.

When it breaks

You seeIt 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.