Learn

Watching Signals Over Time with the Digital Oscilloscope

Use the simulator's built-in Digital Oscilloscope to see voltage over time at any point in your circuit — watch a GPIO pin toggle, measure a PWM signal's frequency and duty cycle, and inspect timing that a multimeter can't show.

Note: the Digital Oscilloscope is a VIP-tier component in the simulator — you’ll need a VIP plan to use it there.

Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.

What you’ll need

  • Raspberry Pi 4B
  • LED
  • Resistor (220Ω)
  • The Scope tool (top bar) — not a component you place

Step by step

  1. Build a simple circuit: drag a Raspberry Pi 4B, a Resistor (220Ω) and an LED onto the Canvas. Wire Pi pin 37 → the resistor, the resistor → the LED's anode (long leg), and the LED's cathode → a Pi GND pin (for example pin 39).

The Digital Oscilloscope is a tool, not a part: you don't drag it onto the canvas. It works on a circuit you've already built and never changes it. It is available on VIP accounts.

  1. Go to the Code tab and add a script that toggles pin 37, then click Start:
import asyncio
import RPi.GPIO as GPIO
 
GPIO.setmode(GPIO.BOARD)
GPIO.setup(37, GPIO.OUT)
 
while not should_stop():
GPIO.output(37, GPIO.HIGH)
await asyncio.sleep(0.25)
GPIO.output(37, GPIO.LOW)
await asyncio.sleep(0.25)
  1. Click the Scope button in the top bar. A panel appears at the bottom right of the canvas with a plot, two channels (CH1 yellow, CH2 cyan), a time window, Hold and Trig ↑ buttons. Press Esc or the ✕ to close it.
  2. Make sure CH1 is selected, then click the resistor's terminal that is wired to pin 37. A yellow ring marks the probed pin.

The trace steps between 0 V and 3.3 V, and the readout under the plot shows about 2 Hz and a 50% duty cycle. Change the time window (for example 1 s total) to see more or fewer cycles.

  1. Press Hold to freeze the picture and look closely, then press Run to continue. Turn on Trig ↑ to make the trace start from a rising edge so a repeating signal stays steady on the screen.
  2. Try PWM. Stop the simulation, replace the script with the one below, and click Start:
import asyncio
import RPi.GPIO as GPIO
 
GPIO.setmode(GPIO.BOARD)
GPIO.setup(37, GPIO.OUT)
 
pwm = GPIO.PWM(37, 1000) # 1 kHz
pwm.start(25) # 25% duty
await asyncio.sleep(2)
pwm.ChangeDutyCycle(75) # now 75% duty
await asyncio.sleep(2)

Set the time window to 10 ms total. You'll see a 1 kHz square wave that's high for a quarter of each cycle, then — after two seconds — high for three quarters. The readout reports about 1 kHz and the duty cycle. PWM is drawn from its frequency and duty setting, so it stays clean even at high frequencies.

  1. Optional: select CH2, click a second pin (for example the LED's anode) and compare two points at once. Each channel's readout shows its own Vpp, frequency and duty.

What “working correctly” looks like

  • The toggle script draws a 0 V / 3.3 V square wave and reads about 2 Hz at 50% duty.
  • The PWM script reads about 1 kHz, first at 25% and then at 75% duty, and the trace visibly changes when the duty changes.
  • Nothing about your circuit changes while you use the scope — probes never move or edit parts.

If something’s wrong

  • A flat line at 0 V → click Start first, and make sure you clicked a pin that's wired to the signal (a pin on the same net as Pi pin 37).
  • No trace at all → select CH1 or CH2 first, then click a pin; a channel with no probe stays blank.
  • The Scope button asks you to upgrade → the oscilloscope is a VIP tool; sign in with a VIP account.
  • Clicking a pin draws a wire → the Scope isn't active; click Scope in the top bar first. The multimeter and the scope can't be open at the same time.
  • Edges look slightly late or spaced wider than your script's timing → the simulator's timing is limited to about 1–20 ms (the bridge between your Python code and the canvas), so very short pulses look stretched.
  • A NeoPixel data line shows a labeled illustrative waveform → the simulator doesn't run the real 800 kHz signal; the scope draws it from the last frame and says so on screen.