Digital Oscilloscope on Raspberry Pi Pico

Introduction

This project implements a single-channel digital oscilloscope using a Raspberry Pi Pico board based on the RP2040 microcontroller. The oscilloscope samples an external analog signal with the Pico's internal 12-bit ADC, detects a configurable trigger event, and displays the captured waveform on a 2.4 inch ILI9341 TFT display connected through SPI.

The user can adjust the timebase, trigger threshold, trigger edge and display mode using four push buttons and one potentiometer. The second RP2040 core is used as an independent PWM function generator for generating local test signals. The sampled waveform can also be streamed over USB CDC as comma-separated sample values for optional logging on a PC.

The goal of the project is to build a compact embedded measurement tool and to exercise several microcontroller peripherals at the same time: ADC, SPI, DMA-driven display transfers, PWM, GPIO input handling, multicore execution and USB serial communication.

General Description

The oscilloscope is centered around the Raspberry Pi Pico. The analog input signal first passes through a protection and scaling circuit before reaching ADC0 on GP26. The trigger threshold is read from a potentiometer connected to ADC1 on GP27.

Core 0 handles the oscilloscope user interface and acquisition pipeline:

  • ADC sampling
  • trigger level reading from a potentiometer
  • trigger edge detection
  • waveform rendering on the ILI9341 TFT display
  • button handling
  • USB CDC sample streaming

Core 1 runs independently as a simple PWM-based signal generator on GP14. During testing, this output can be routed through an RC low-pass filter and connected back to the oscilloscope input.

Signal flow:

[Probe input]
      |
[Voltage divider and ADC protection]
      |
[GP26 / ADC0]
      |
[DMA sample buffer]
      |
[Trigger detection and waveform processing]
      |
[SPI display rendering on ILI9341]

[GP27 / ADC1] <- potentiometer for trigger level
[GP2-GP5]    <- buttons for user control
[GP22 GPIO]  -> display backlight enable
[USB CDC]    -> sample export to PC
[GP14 PWM]   -> optional function generator output

Hardware Design

The hardware is built around the Raspberry Pi Pico, an SPI TFT display, a protected ADC input stage, a potentiometer, four push buttons and a PWM test output.

Main Components

Component Role
Raspberry Pi Pico Main controller, ADC acquisition, display rendering, USB communication and PWM generation
ILI9341 2.4 inch TFT display Waveform and UI display, connected through SPI0
10k potentiometer Trigger threshold adjustment, read by ADC1
2 x 100k resistors Input voltage divider, divides the probe input by 2
2 x 100 ohm resistors ADC input series protection and PWM output series resistor
Small capacitor, about 100pF to 1nF Optional ADC input noise filtering
100nF capacitors Supply, display and ADC reference decoupling
4 x tactile push buttons Timebase, trigger edge and display mode controls
Probe/header input External signal input and ground reference

Pin Connections

ILI9341 Display

Display Pin Pico Pin Notes
GND GND Common ground
VCC 3.3V Display supply
CLK GP18, pin 24 SPI0 clock
MOSI / SDA GP19, pin 25 SPI0 TX
RESET / RES GP20, pin 26 Active low reset
DC GP21, pin 27 Data/command select
LED / BLK GP22, pin 29 Backlight enable
MISO / SDO Not connected Not used by the firmware

The display module used for the final implementation does not expose a chip-select pin. The firmware therefore uses the display as the only SPI device and does not drive a display CS line. Touch controller pins, if present on other display modules, are not used.

ADC Input

The oscilloscope input uses a 2:1 voltage divider before the Pico ADC. This allows input voltages up to about 6.6V to be mapped into the Pico ADC's 0V to 3.3V range.

INPUT SIGNAL
     |
    R1 100k
     |
     +---- node A ---- R3 100R ---- GP26 / ADC0
     |
    R2 100k
     |
    GND

The optional ADC filter capacitor should be small. In the final circuit, a 100pF capacitor was used because a larger capacitor visibly rounded fast square waves.

Potentiometer

Potentiometer Pin Connection
Left terminal 3.3V
Right terminal GND
Wiper GP27 / ADC1, pin 32

Buttons

Each button is connected between the GPIO pin and GND. Internal pull-up resistors are enabled in software.

Button Pico GPIO Pico Pin Function
Button 1 GP2 pin 4 Timebase increase
Button 2 GP3 pin 5 Timebase decrease
Button 3 GP4 pin 6 Toggle trigger edge
Button 4 GP5 pin 7 Cycle display mode

Function Generator Output

Signal Connection
PWM source Pico GP14, pin 19
Series resistor 100 ohm
Output terminal GEN_OUT
Optional filter capacitor From GEN_OUT to GND

For testing, GEN_OUT can be connected to the oscilloscope input header. This jumper is only used during tests and is not a permanent connection in the main input circuit.

Decoupling

100nF capacitors are placed between 3.3V and GND near the Pico and near the display module. These capacitors reduce local supply noise caused by fast digital switching, especially during SPI display updates. A separate 100nF capacitor is placed between ADC_VREF and AGND to decouple the ADC voltage reference.

Electrical Schematic

Electrical schematic

Software Design

The firmware is organized around the two RP2040 cores.

Core 0 performs the oscilloscope acquisition and display tasks. The ADC is sampled into a RAM buffer. The software searches for a trigger crossing based on the threshold read from the potentiometer and the selected edge direction. The selected waveform window is then converted from ADC values to display pixel coordinates and rendered on the ILI9341 display.

The display is updated over SPI0. The frame buffer is transferred to the display using DMA, which reduces the time spent waiting for SPI transfers and keeps the interface more responsive. The display backlight is enabled from GP22.

The four buttons are read as digital inputs with internal pull-ups. Software debouncing is used to avoid repeated false events. The buttons modify the timebase, trigger edge and display mode.

Core 1 runs the signal generator. It configures PWM on GP14 and updates the PWM output independently from the acquisition code. This makes it possible to test the oscilloscope without requiring an external signal generator.

USB CDC is used to stream sample data to a connected PC. The data can be sent as comma-separated values, allowing it to be saved or plotted with common serial tools.

Main software modules:

  • ADC acquisition
  • trigger detection
  • waveform scaling and rendering
  • SPI display driver
  • DMA display transfer
  • button and potentiometer input
  • PWM function generator
  • USB CDC sample streaming

Source Code

The firmware is implemented in a single C source file for the Raspberry Pi Pico SDK:

The code contains the ILI9341 display driver, ADC acquisition, trigger detection, waveform rendering, button handling, potentiometer reading, USB CDC sample streaming and the second-core PWM function generator.

Bibliography / Resources

pm/prj2026/florin.stancu/cconstantinescu2705.txt · Last modified: 2026/05/25 05:25 by cconstantinescu2705
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0