post / 2024.02.15

MicroPython Function Reference

MicroPython Function Reference

This article collects the parts of MicroPython’s machine module that are most useful on a Raspberry Pi Pico (RP2040). Everything has been checked against the official MicroPython documentation.

There are two numbering schemes for pins:

  • GPIO number (GP0–GP29): the one used in code; Pin(25) means GP25.
  • Physical pin number: the 40 header positions on the board. These are not the same as GPIO numbers, so be careful when wiring.

class Pin

Constructor machine.Pin(id, mode=-1, pull=-1, value=None)

ParameterMeaning
idPin identifier. On the Pico, 0–29 (GP0–GP29)
modeNone / Pin.IN(0) / Pin.OUT(1) / Pin.OPEN_DRAIN(2)
pullInternal pull resistor, valid only in input mode: None / Pin.PULL_UP(1) / Pin.PULL_DOWN(2)
valueValid only for output/open-drain mode; initial level: 0 low, 1 high

Note that it is Pin.PULL_DOWN, not Pin.DOWN.

Pin.init(mode=-1, pull=-1, value=None)

Re-initialise the pin. Only the arguments you pass are changed; everything else keeps its current state.

Pin.value([x])

  • With no argument: returns the current pin level (0 or 1).
  • With an argument: writes the level. The argument is converted to a boolean (True sets 1, False sets 0).

Pin.on() / Pin.off() and Pin.high() / Pin.low()

  • on(), high(): drive the pin high (1).
  • off(), low(): drive the pin low (0).

These four are meaningful only in output/open-drain mode. low() and high() are not part of the core API, but they are available on the Pico (rp2 port).

Pin.toggle()

Flips the output level from 0 to 1 or 1 to 0. toggle() is available on the rp2, esp32, and several other ports; where it is missing, use Pin.value(not Pin.value()) instead.

from machine import Pin
import time

led = Pin(25, Pin.OUT)   # the on-board LED of a Pico is GP25
while True:
    led.toggle()
    time.sleep(1)        # flip once per second

Pin.irq(handler=None, trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING)

Configures an external interrupt. The callback runs whenever the trigger condition occurs.

  • handler: the callback, which must accept one Pin argument.
  • trigger: the condition, and multiple values can be OR-ed with |:
ConstantTrigger
Pin.IRQ_FALLINGfalling edge
Pin.IRQ_RISINGrising edge
Pin.IRQ_LOW_LEVELlow level
Pin.IRQ_HIGH_LEVELhigh level
def on_press(pin):
    print("Button pressed")

button = Pin(15, Pin.IN, Pin.PULL_UP)
button.irq(handler=on_press, trigger=Pin.IRQ_FALLING)

class PWM

PWM (pulse-width modulation) switches a pin on and off rapidly to emulate intermediate voltages. It is used for dimming LEDs, controlling motor speed, and driving servos.

machine.PWM(pin, freq=..., duty_u16=...)

Creates a PWM output on the given pin; pin is a Pin object.

Common methods

MethodPurpose
PWM.freq([value])get/set the frequency in Hz, roughly 8 Hz – 62.5 MHz (at a 125 MHz CPU clock)
PWM.duty_u16([value])get/set the duty cycle as 0–65535, the ratio value / 65535
PWM.duty_ns([value])get/set the high time within one period, in nanoseconds
PWM.deinit()stop the PWM output

The upper bound of duty_u16 is 65535, not 65536. Passing 65536 overflows.

RP2040 has 8 independent PWM slices with 2 channels each, 16 channels in total. The two channels of a slice must share a frequency but may have different duty cycles.

Example: breathing LED

from machine import Pin, PWM
import time

led = PWM(Pin(25))
led.freq(1000)      # 1 kHz

duty = 0            # duty cycle in percent
step = 1

while True:
    duty += step
    if duty >= 100:
        duty = 100
        step = -1
    elif duty <= 0:
        duty = 0
        step = 1

    # convert percent to the 0-65535 range, without overflowing
    led.duty_u16(int(duty / 100 * 65535))

    if duty % 5 == 0:
        print(duty)  # convenient for plotting

    time.sleep(0.01)  # roughly a 2-second round trip

Example: button-controlled LED (with software debouncing)

from machine import Pin
import time

button = Pin(15, Pin.IN, Pin.PULL_UP)   # reads 0 while pressed
led_board = Pin(25, Pin.OUT)            # on-board LED
led_ext = Pin(16, Pin.OUT)              # external LED

while True:
    led_ext.off()
    if button.value() == 0:             # possibly pressed
        time.sleep(0.01)                # wait 10 ms and check again to filter bounce
        if button.value() == 0:         # confirmed
            led_board.toggle()
            led_ext.on()
            print("The button is pressed.")
            while button.value() == 0:  # wait for release
                time.sleep(0.01)

A mechanical button bounces for a few milliseconds when pressed or released, and the CPU can read that as several presses. Software debouncing means: after detecting a change, wait about 10 ms and read the pin again to confirm.

class ADC

The ADC (analog-to-digital converter) turns an analog voltage into a digital reading.

machine.ADC(id)

id may be a Pin object or a channel number:

  • On the Pico, channels 0–3 map to GP26–GP29 (GP29 is wired to VSYS on the board);
  • Channel 4 is the on-chip temperature sensor, also reachable as ADC.CORE_TEMP.

ADC.read_u16()

Returns the reading as an integer in 0–65535, spanning the input range 0–3.3 V.

from machine import ADC, Pin

adc = ADC(Pin(26))          # equivalent to ADC(0)
value = adc.read_u16()      # 0 - 65535
voltage = value / 65535 * 3.3   # convert to volts
print(voltage, "V")

The range is 0–65535. The RP2040’s ADC hardware is only 12-bit (0–4095); MicroPython scales it linearly to 16 bits, so the lowest few bits carry no real precision.

Summary

TaskKey point
Digital I/OPin(id, mode, pull); read with value(), write with value() / on() / off() / toggle()
InterruptsPin.irq(handler, trigger); the callback must take one Pin argument
Dimming / speed controlPWM(pin) + freq() + duty_u16(); duty is capped at 65535
Reading analog inputADC(Pin(26)) + read_u16(), returning 0–65535
Button bounceafter detecting a change, wait 10 ms and confirm

Author: 孤筝

Title: MicroPython Function Reference

Published: 2024-02-15

Updated: 2026-10-05

License: CC BY-NC-SA 4.0

When will I have a drink and discuss the details again?

Search