⚡ Spark Academy53 lessons

Build Your Own Oscilloscope

A Pico, a divider probe and two short programs turn into a working scope — then your blinker, your dimmer and your night-light become its first test subjects.

lesson 1 of 1 in this unit

Builds on: 12.1 Program the Night-Light13.1 Sampling & Aliasing2.2 Voltage Dividers15.2 The Debugging Mindset

The mission

Every lab in this course drew an oscilloscope trace for you. This build closes the loop on the entire curriculum: you will make a real sampling oscilloscope from your Pico, use it to measure the RC charging curve, the blinker’s 3-to-6-volt sawtooth and the dimmer’s PWM — and compare physics against everything the simulators promised. An instrument you built, verifying circuits you built, using theory you own. That is what mastery looks like.

Everything needed is already on your desk: the Pico’s ADC (11.2) is the sampler, Nyquist (13.1) sets its honest limits, a voltage divider (2.2!) becomes the probe, and Thonny’s built-in plotter is the screen. New parts required: none — two resistors from your kit build the probe.

The probe: a divider with a job title

Your circuits under test run at 9 V; the Pico’s ADC dies above ~3.6 V. The fix is the very first trick this course taught you — a 3:1 voltage divider: 100 kΩ from the probe tip to GP26, 47 kΩ from GP26 to ground (÷3.13; software multiplies back). Real 10:1 scope probes are exactly this idea with fancier tolerances. Two fine points, both old friends:

  • Loading (2.2's trap): the probe's ~150 kΩ hangs on whatever you touch. On the 555's output pin — a stiff, low-impedance source — it's invisible. Directly on the high-impedance cap node it would gently distort the timing. Probe outputs by preference; probe delicate nodes knowingly.
  • Common ground: voltage is between two points (0.2's oldest lesson). The Pico's GND and the blinker's − rail must be wired together, or your readings are fiction.
probe tip → 100 kΩ → GP26 → 47 kΩ → GND · reading × 3.13 in softwarenever probe mains or anything not battery/USB powered — this scope is for your own low-voltage bench

Two firmwares, one instrument

Live mode streams readings for Thonny’s plotter (View → Plotter) — a few hundred samples per second, perfect for the slow beauties: RC curves, blinker sawtooth, the night-light’s dusk.

from machine import ADC
from time import sleep_ms

probe = ADC(26)

# LIVE MODE - open Thonny's View > Plotter and watch
while True:
    v = probe.read_u16() * 3.3 / 65535
    print(v * 3.128)      # undo the 100k/47k divider (which divides by 3.13)
    sleep_ms(2)           # ~400 samples per second

Burst mode samples flat-out into memory first (tens of thousands of samples per second — MicroPython’s honest limit), then prints the capture: enough to resolve your 1.4 kHz PWM cleanly. It even measures its own sample rate, because an instrument that doesn’t know its own fs can’t warn you about Nyquist.

from machine import ADC
from time import ticks_us, ticks_diff

probe = ADC(26)

def capture(n=2000):
    buf = bytearray(2 * n)
    t0 = ticks_us()
    for i in range(n):                 # tight loop: tens of kS/s
        x = probe.read_u16()
        buf[2*i] = x & 0xFF
        buf[2*i + 1] = x >> 8
    us = ticks_diff(ticks_us(), t0) / n
    print("# sample interval:", us, "us  ->  fs =", 1e6 / us, "Hz")
    for i in range(n):
        x = buf[2*i] | (buf[2*i + 1] << 8)
        print(x * 3.3 / 65535 * 3.128)

capture()

The measurement campaign

TargetProbe pointYou should seeCloses the loop on
RC charge: 10 µF via 100 kΩ to 9 Vcapacitor topthe exponential; 63% at τ ≈ 1 sLesson 2.3
555 blinkerpin 3 (output)square, ~1.5 Hz — measure it against f = 1.44/((R1+2R2)C)Lessons 3.3 & 4.1
555 blinkerpins 2+6 (gently!)the sawtooth between ⅓ and ⅔ of 9 Vthe simulator's signature trace
PWM dimmerpin 3, burst modeduty following the knob at ~1.4 kHzUnit 8 & Nyquist (13.1)
Night-light at duskGP26 divider nodethe slow slide your twin predictedUnit 12

If it misbehaves

SymptomLikely causeFix
Readings pinned at 3.3 Vprobing 9 V without the divider — the input was overdrivenbuild the 100k/47k probe, then check the pin still reads sensibly (above ~3.6 V you may have damaged it)
Readings are noise/garbageno common groundjumper Pico GND to the target's − rail
PWM looks like a slow wavealiasing in live modethat's Lesson 13.1 in the wild! use burst mode
Sawtooth timing looks stretchedprobe loading the cap nodeexpected (2.2!) — measure frequency at pin 3 instead
Plotter shows nothingplotter window closed / prints too fastView → Plotter in Thonny; keep the sleep_ms in live mode

Graduation

Look at the bench: a blinker designed with RC arithmetic, a dimmer steered with diodes, a night-light running your firmware, and now a measuring instrument that audits them all — every one built from parts you understand down to the drifting electron. There is no fifth tier — the ladder ends here, on purpose. What remains are the specializations: parallel branches, in any order, into CPUs, the radio spectrum, and robots. Pick whichever pulls hardest — you are fully equipped to debug the gap between the idea and the working thing. That gap has a name. It’s called engineering. Welcome to it. ⚡

⚡ Lab — Digital Twin — Rehearse the Campaign

Your Pico-scope, simulated one last time: pick a target, a sample rate and a probe, and rehearse every measurement before touching hardware.

  • Probe the PWM at 1 kHz: a phantom 400 Hz wave (1.4 kHz, folded — Lesson 13.1). At 200 Hz the samples flatline, because 1 400 is an exact multiple of 200. Only the fastest rate tells the truth.
  • Switch to a direct wire on a 9 V target and watch the trace clip at 3.3 V.
  • Sawtooth at 1 kHz with the divider probe: the textbook capture. Do this one for real first.
1 kHz
What to expect on the real thing
the sawtooth between ⅓ and ⅔ of 9 V at ~1.5 Hz — the exact trace the simulator promised
Full circle
33 lessons of simulated scopes — this one you will hold in your hand

Build checklist — 0 / 12