Built-in project · Raspberry Pi Pico W

Pico W PIR motion sensor on GP14

MicroPython on a Pico W: a PIR motion sensor on GP14 raises an interrupt when someone moves, and the program times how long each spell lasts. The whole build, a Raspberry Pi Pico W and 1 more part, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Beginner About 10 minutes to build and run. Runs in your browser. Free, and no account needed.

The parts retail for about $8. On Mokxi they're free.

The circuit runs here once the page has loaded.

What you'll learn

  • Reading a PIR motion sensor
  • Interrupts on rising and falling edges
  • Timing with ticks_ms and ticks_diff
  • Passing events to the main loop in a list
  • Difficulty: Beginner
  • Time: About 10 minutes
  • Board: Raspberry Pi Pico W
  • Parts: 3

How it works

The motion sensor's OUT pin goes to GP14. It goes high while it sees someone move and low when things go still. The program asks the board to call a function on both edges, rising and falling.

Each call saves the pin level and the time. The main loop takes those events and prints a message. When the pin goes high, it prints Somebody here and how long it was quiet. When the pin goes low, it prints gone and how long the movement lasted.

Parts list

3 parts, plus the jumper wires. They retail for about $8; on Mokxi they're free.

Kits that can build it

These 2 starter kits have every part in the circuit. Each kit's page lists what else it can build.

Wiring table

Every connection, pin by pin, read from the circuit itself. Each row joins the pin on the left to the pin on the right, by a jumper wire or a breadboard strip.

Part and pinConnects to
Motion sensor pin OUTRaspberry Pi Pico W pin GP14
Motion sensor pin VCC3.3 V
Motion sensor pin GNDGround

The code

The MicroPython code exactly as the editor opens it. Change a line there and press Run: the board runs it on the official MicroPython firmware, with nothing to compile.

main.py · Raspberry Pi Pico W
# Detect movement: the PIR module's output on GP14 goes high while it
# sees someone move. Interrupts on both edges time each spell.
from machine import Pin
import time

pir = Pin(14, Pin.IN)
events = []
since = time.ticks_ms()

def changed(pin):
    events.append((pin.value(), time.ticks_ms()))

pir.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=changed)
print("watching")

while True:
    while events:
        level, at = events.pop(0)
        took = time.ticks_diff(at, since)
        since = at
        if level:
            print("Somebody here! (quiet for %d ms)" % took)
        else:
            print("gone (moving for %d ms)" % took)
    time.sleep_ms(20)

Code walkthrough

The key functions of the sketch, and what each one does.

changed main.py

Runs by itself every time GP14 changes. It does very little on purpose: it adds the pin's new value and the current time to the events list. The main loop later prints the messages, which keeps the interrupt handler quick.

def changed(pin):
    events.append((pin.value(), time.ticks_ms()))

Troubleshooting

The usual mistakes with this circuit, and the fix for each.

  • Nothing prints after watching. This project
    Check OUT goes to GP14, and trigger the sensor by moving something in front of it in the simulator.
  • Messages arrive in bursts. This project
    That is expected. Events wait in the list, and the loop checks it every 20 ms.
  • The sensor reads high for ages after power up. Motion sensor
    A real PIR needs 30 to 60 seconds to settle. Ignore its output during that time, and keep still in front of it until the delay passes.
  • Wrong output or it never triggers. Motion sensor
    Power it from 5 V, join GND, and read OUT as a digital input (3.3 V logic high). Check the trimmers for delay and sensitivity.
  • Pins are powered from 5 V, or a 5 V signal goes into a GPIO. The RP2040 pins are 3.3 V only and are not 5 V tolerant. Raspberry Pi Pico W
    Power the board from VBUS or VSYS at 5 V, but keep GPIO signals at 3.3 V. Use a level shifter or a divider for 5 V parts.
  • WiFi code fails to connect, or the on-board LED code does nothing. The LED on the Pico W is not on GP25 like on the plain Pico. Raspberry Pi Pico W
    Use the board's LED_BUILTIN name so the library drives it through the WiFi chip. Join a 2.4 GHz network only, with the right SSID and password, and wait for the link before sending.

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.