PROJECT NOTE · 01
Guided Engineering Project

Build a Real-Time Audio Visualizer

Abstract

This project captures an analog microphone signal, samples it with the ADC inside an RP2040 microcontroller, and converts the resulting data into a continuously updating waveform on a 240 × 240 TFT display. Four WS2812 RGB LEDs provide a second visual representation of the approximate signal magnitude.

Difficulty Foundation → Intermediate
Estimated Time 2–3 Hours
Controller STEPICO / RP2040
Language MicroPython
Real-Time Audio Visualizer using STEPICO RP2040, microphone frontend and ST7789 TFT display FIG. 01
Figure 1 Complete real-time audio visualizer system. The microphone frontend captures the incoming analog signal, the RP2040 performs ADC sampling and processing, and the ST7789 display renders the resulting waveform.
Primary Signal Path
Sound → Microphone Front-End → ADC → RP2040 Processing → TFT / RGB Output
01 Signal Input Analog Microphone Front-End
02 Acquisition RP2040 ADC · GP28 / ADC2
03 Visualization ST7789 · 240 × 240 TFT
04 Platform Fundamental EE Starter
01 Project Overview
System Definition

From an Analog Sound Signal to a Real-Time Visual Output

The project connects analog signal acquisition, digital sampling, embedded processing, and visual output in one complete signal path. The objective is not only to produce a responsive display, but to understand how information moves through each layer of the system.

A complete real-time audio signal path.

The microphone frontend converts sound pressure into a changing analog voltage. The RP2040 reads this voltage through its ADC, converts the samples into vertical positions, and continuously draws the resulting waveform across the TFT display.

At the same time, the program estimates the magnitude of the incoming signal and uses that information to control four WS2812 RGB LEDs. Speech, a hand clap, or nearby music therefore produces two simultaneous visual responses: a waveform on the display and changing light from the LEDs.

Input
Real-world sound captured by an analog microphone frontend
Process
ADC sampling and real-time processing on the RP2040
Output
Live TFT waveform and responsive WS2812 RGB LEDs
02 · Architecture

How the System Works

Sound begins as a physical variation in air pressure. The microphone and analog frontend convert that variation into an electrical signal suitable for the microcontroller. The RP2040 then samples the signal, processes the resulting numerical data, and produces visual output through the display and RGB LEDs.

Block diagram showing the signal path from sound through the analog frontend, ADC, RP2040 processing and display FIG. 02
Figure 2 Functional architecture of the audio visualizer. The signal begins in the analog domain, crosses into the digital system through the ADC, and is processed by the RP2040 before being presented as a visible waveform and responsive light output.
01 Physical Input

Sound

Changes in air pressure provide the real-world signal entering the system.

02 Analog

Microphone Front-End

Converts sound into an electrical waveform and prepares it for the ADC through analog signal conditioning.

03 Acquisition

RP2040 ADC

Repeatedly measures the analog voltage and represents each measurement as numerical data.

04 Digital

Signal Processing

Centres, averages, scales, and maps the sampled data into values suitable for real-time visualization.

05 Output

Display + RGB LEDs

Presents the measured behaviour as a moving waveform and a second light-based response.

Engineering Note

This display is oscilloscope-style, not a calibrated oscilloscope. The vertical axis represents relative signal amplitude, while the horizontal behaviour depends on program execution and display-refresh timing rather than a calibrated timebase.

03 Signal Acquisition
Analog → Digital

From Sound to Voltage — and Voltage to Data

Before the RP2040 can process sound in software, the physical audio signal must first be converted into an electrical waveform, conditioned for the ADC input range, and then sampled as a sequence of numerical values.

Analog Front-End

From Sound to Voltage

A microphone does not produce a digital value. It produces a small analog signal whose voltage changes with the sound around it.

The analog frontend prepares this signal for the RP2040 ADC by providing the required amplification and biasing. Because the RP2040 accepts only a positive input range, the audio waveform cannot simply swing above and below 0 V.

Instead, the waveform is shifted upward around a DC midpoint. The signal still carries the changing audio information, but now remains inside the voltage range that the ADC can measure.

Key Principle

Signal conditioning does not remove the audio waveform — it prepares that waveform so the digital system can measure it safely.

Comparison of an AC audio signal centred around zero volts and the same signal shifted upward into the RP2040 ADC input range FIG. 03
Figure 3 Conceptual view of DC biasing. The original AC waveform contains negative voltage, while the conditioned signal is shifted into the RP2040 ADC-compatible positive input range.
Diagram showing a continuous waveform converted into evenly spaced ADC samples and corresponding digital values FIG. 04
Figure 4 ADC sampling converts the continuously changing input voltage into a sequence of numerical measurements that the RP2040 can process in software.
Data Acquisition

From Voltage to Numbers

The ADC measures the microphone voltage repeatedly and returns a numerical value for each measurement. In MicroPython, read_u16() represents the ADC result on a 0–65,535 scale.

The program subtracts 32,768 so that the expected midpoint can be treated as zero. It then averages four readings to reduce small sample-to-sample variations before mapping the result onto the TFT display.

The resulting sequence of numbers is not the same thing as the original continuous waveform. Sampling speed, microphone bandwidth, display-refresh timing, electrical noise, and the program itself all influence what finally appears on the screen.

Key Principle

The ADC does not “see” a waveform. It repeatedly measures voltage and provides the microcontroller with numerical data.

01 Physical

Sound Pressure

Air-pressure variation provides the original real-world input.

02 Analog

Conditioned Voltage

The microphone frontend amplifies and biases the electrical waveform.

03 Acquisition

ADC Samples

Repeated voltage measurements become a stream of numerical values.

04 Software

Processable Data

The RP2040 can now centre, average, scale, and visualize the samples.

Engineering Note

The objective of this project is intuitive real-time visualization rather than precision audio measurement. The displayed waveform is affected by sampling behaviour, microphone bandwidth, noise, program execution, and TFT refresh timing. It should therefore be interpreted as a responsive view of the incoming signal, not as a calibrated measurement instrument.

04 Embedded Software
Real-Time Program Flow

Turning ADC Samples into a Live Visual Response

Once the microphone signal has been converted into numerical samples, the RP2040 must repeatedly read, process, scale, and visualize those values. The software therefore operates as a continuous loop rather than as a one-time calculation.

Real-time program flow showing ADC reading, averaging, offset calculation, waveform drawing, LED updating, and repetition FIG. 05
Figure 5 Main execution loop of the audio visualizer. Each iteration acquires a new ADC measurement, processes the result, updates the waveform and LEDs, and immediately begins the next cycle.
Continuous Execution

One Loop Connects Measurement to Output

The visualizer does not capture an entire audio signal and process it afterward. Instead, the RP2040 repeatedly performs a short sequence of operations while the system is running.

01
Acquire

Read new voltage samples from the ADC.

02
Process

Average, centre, and scale the measured values.

03
Render

Convert the processed value into waveform position and LED response.

04
Repeat

Immediately return to the ADC and begin the next update cycle.

Real-time behaviour comes from repetition. Each individual calculation is small; the continuously repeating loop creates the responsive waveform seen on the display.
04.1 · Core Logic

Three Operations Drive the Visualization

The program does more than transfer raw ADC values directly to the display. It establishes a centre reference, reduces small sample-to-sample variation, maps the signal into screen coordinates, and uses the same processed magnitude to control the LED response.

01 Acquire

Read and Centre the ADC

The ADC reading is shifted around the expected midpoint so that positive and negative waveform movement can be represented as offsets around the display centre line.

02 Process

Average and Scale

Four readings are averaged to reduce small random variations, then scaled to the available display height and constrained so the trace remains on-screen.

03 Visualize

Draw the Waveform and Drive LEDs

The processed offset determines the next waveform position. Its absolute magnitude is also used as an approximate measure for the RGB LED response.

Software Implementation

The Important Parts of the Program

The complete MicroPython project contains the ST7789 display driver, grid drawing, waveform update logic, ADC processing, and RGB LED behaviour.

For the article, only the signal-processing steps need to be shown directly. The full tested project should be distributed as a downloadable ZIP containing main.py and st7789py.py.

Download Complete MicroPython Project ↓
Hardware Interfaces 01
spi = machine.SPI(
    1,
    baudrate=40_000_000,
    polarity=0,
    phase=0,
    sck=machine.Pin(10),
    mosi=machine.Pin(11),
    miso=machine.Pin(12),
)

adc = machine.ADC(28)
np = neopixel.NeoPixel(machine.Pin(23), 4)
Centre and Average 02
def read_centered():
    return adc.read_u16() - 32768

def sample_pixel_offset():
    raw = (
        read_centered()
        + read_centered()
        + read_centered()
        + read_centered()
    ) >> 2

    offset = (raw * (HALF_H - 4)) // 32768

    return max(
        -(HALF_H - 4),
        min(HALF_H - 4, offset)
    )
Visual Output 03
offset = sample_pixel_offset()

curr_y = HALF_H - offset

update_leds(abs(offset))

display.vline(
    x,
    prev_y,
    curr_y,
    color
)
Processing Logic

The raw ADC value is not sent directly to the screen. The program first establishes a centre reference, reduces small variations through averaging, scales the result to the display geometry, and limits the value so that the trace cannot be drawn outside the screen.

Engineering Note

The LED output represents approximate instantaneous signal magnitude, not calibrated sound pressure level. Larger waveform offsets produce a stronger visual response, but the result depends on the microphone frontend, ADC behaviour, software scaling, and the chosen LED mapping.

05 Build the Project
Hardware + Software Procedure

Assemble, Program, and Run the Complete System

The system can be built using the integrated project PCB supplied with the Fundamental EE Starter system or by connecting the individual modules directly. In both cases, the electrical signal path and RP2040 pin assignments remain the same.

Hardware

What You Need

The project combines one analog input stage, one RP2040-based controller, a TFT display, and four addressable RGB LEDs.

A USB connection provides power and is also used to program the RP2040 from a computer.

STEPICO / RP2040 board
Samples the microphone signal and runs the MicroPython program
Analog microphone frontend
Converts sound into an ADC-compatible analog voltage
ST7789 240 × 240 IPS display
Shows the real-time waveform
Four WS2812 RGB LEDs
Respond to approximate audio intensity
USB cable and computer
Powers, programs, and communicates with the RP2040
Jumper wires or integrated PCB
Completes the hardware connections
Before Powering

Disconnect USB power while changing wiring. Confirm the supply voltage, ground connections, and module orientation before reconnecting the board.

Stage 01

Connect the Hardware

Begin with the TFT display, then connect the microphone frontend and WS2812 LEDs. All modules must share the appropriate ground reference.

RP2040 wiring diagram for the ST7789 display, microphone input and WS2812 LEDs FIG. 06
Figure 6 Pin-accurate wiring reference for the display, microphone frontend, and RGB LEDs.

The ST7789 display communicates with the RP2040 through SPI. The current program configures SPI at 40 MHz.

SCK
GP10
MOSI
GP11
MISO
GP12
CS
GP13
DC
GP16
RESET
GP17
Microphone Output
GP28 / ADC2
WS2812 Data
GP23
Checkpoint 01

Connect USB power. The board should power normally, the display backlight should turn on, and no component should become unusually warm. Disconnect power immediately if the board resets repeatedly or any component heats up.

Stage 02

Prepare the MicroPython Program

Install the current MicroPython firmware on the RP2040, connect the board in Thonny, and upload the two tested project files to the device filesystem.

Select the correct MicroPython interpreter in Thonny and confirm that the RP2040 appears as the connected device.

Upload both project files to the microcontroller:

Project Files
AudioVisualizer/
├── main.py
└── st7789py.py
Download Complete MicroPython Project ↓
Thonny showing the connected RP2040 and uploaded MicroPython project files FIG. 07
Figure 7 Example software setup in Thonny with the RP2040 connected and both project files stored on the device.
Checkpoint 02

If necessary, run a simple ADC test before starting the full visualizer. In a quiet environment the reading should remain near its bias level and change when you speak or clap near the microphone. A value fixed near the minimum or maximum usually indicates an input, power, or biasing problem.

Stage 03

Run the Complete System

With both files stored on the RP2040, run main.py and verify that the waveform and RGB response track changes in the incoming sound signal.

Comparison of the audio visualizer display in quiet, speech and clap conditions FIG. 08
Figure 8 Example response under three input conditions: quiet room, normal speech, and a short clap.

Start with normal speech approximately 20–40 cm from the microphone. The waveform should move away from the centre line while the LEDs respond to the approximate magnitude.

Next, try a short hand clap and then play music at a moderate volume.

01 Quiet

Expect a relatively narrow trace and minimal LED response.

02 Speech

Expect an irregular moving waveform and stronger LED activity.

03 Clap

Expect a larger short-duration waveform response.

Checkpoint 03

The display should refresh continuously, the waveform should react without an obvious long delay, and the LEDs should become more active as the signal grows. The exact waveform will vary with the microphone, room noise, sound source, and sensitivity setting.

06 Test & Improve
Measurement · Validation · Iteration

A Working System Is the Beginning of the Experiment

A successful first run confirms that the hardware and software can operate together. The next step is to change one condition at a time, observe the response, compare the result, and identify which part of the system caused the change.

Engineering Principle

Making a system respond is only the first step. Testing whether it responds correctly is what turns a build into an experiment.

06.1 · Input Test

Compare Different Audio Inputs

Keep the microphone position and display sensitivity unchanged while testing several sound conditions. A controlled comparison makes it easier to determine whether the system is responding consistently to changes in the input signal.

01 Baseline

Quiet Room

Expect a relatively narrow trace around the centre line, with only small variations caused by ambient sound and noise.

02 Continuous Input

Normal Speech

The display should show a continuously changing irregular waveform with visibly greater amplitude than the quiet condition.

03 Transient Input

Hand Clap

A short, louder transient should produce a larger short-duration response on the display and stronger LED activity.

Comparison between the analog microphone signal measured on an oscilloscope and the RP2040 TFT audio visualization FIG. 09
Figure 9 Measurement comparison between the analog microphone output observed on an oscilloscope and the real-time visualization generated by the RP2040.
Measurement Evidence

Compare the Visualization with the Analog Signal

For a stronger engineering comparison, probe the analog microphone output with an oscilloscope while the TFT visualizer is running.

The two displays should respond to the same changes in the input signal, but they will not look identical. The oscilloscope and the RP2040 visualization use different sampling behaviour, scaling, refresh timing, and timebase.

Interpretation

The purpose of this comparison is not to make both traces visually identical. It is to verify that the TFT response originates from a measurable electrical signal.

06.2 · Parameter Test

Adjust the Waveform Sensitivity

The apparent waveform height can be changed in software by modifying the scaling divisor. This changes the mapping from ADC data to screen coordinates; it does not increase the electrical microphone signal or improve ADC resolution.

Display Mapping

Change the Digital Scale, Not the Analog Signal

The waveform size is controlled by the divisor used when converting the processed ADC value into a vertical screen offset.

Reducing the divisor makes the same electrical input appear larger on the display. If the sensitivity is increased too far, however, the trace repeatedly reaches the top and bottom limits and useful differences between louder signals are lost.

Sensitivity Mapping
# Default
offset = (raw * (HALF_H - 4)) // 32768

# Higher display sensitivity
offset = (raw * (HALF_H - 4)) // 16384
32768
Lower displayed sensitivity; more headroom before clipping
16384
Approximately twice the displayed waveform height
8192
High apparent sensitivity with greater risk of reaching the display limits
Comparison of audio visualizer waveform sensitivity using divisors 32768, 16384, and 8192 FIG. 10
Figure 10 Comparison of three digital sensitivity settings using the same input signal. Excessive scaling causes the waveform to approach the display limits and reduces useful visual distinction.
06.3 · Output Test

Adjust the LED Response Separately

The LED behaviour is derived from the processed signal magnitude, but its final brightness scaling is independent of the waveform calculation. This allows the visual comfort and power demand of the LEDs to be adjusted without changing the displayed signal.

Independent Output

Separate Signal Processing from Presentation

The number of controlled LEDs is defined by LED_COUNT = 4. Final LED brightness can also be reduced after the waveform magnitude has already been calculated.

LED Brightness Example
LED_COUNT = 4

# Reduce final LED brightness
brightness = brightness // 8
Experimental Method

Change One Variable at a Time

If waveform sensitivity, LED brightness, microphone position, and sound level are all changed simultaneously, it becomes difficult to determine which modification caused the observed result.

Keep the remaining variables fixed while changing one parameter, then compare the result before making the next adjustment.

Test Rule

Change one parameter at a time. Record what changed, what remained constant, and how the system responded. This makes the result interpretable rather than merely observable.

06.4 · Diagnosis

Troubleshooting the System

Use the observed symptom to narrow the fault to the display, project files, ADC input, analog frontend, LED connection, or software configuration.

Likely Cause
Incorrect CS, DC, RESET, SCK, or MOSI connection. Compare every display connection with the wiring table and confirm that the correct SPI bus and pins are configured.
Likely Cause
One project file was not uploaded to the RP2040. Confirm that both main.py and st7789py.py are stored on the device.
Likely Cause
Weak microphone output, low display sensitivity, or an incorrect ADC connection. Speak close to the microphone, verify GP28 / ADC2, and then try a smaller sensitivity divisor.
Likely Cause
The ADC input may be outside the expected range or the microphone frontend may not be biased correctly. Measure the ADC input and verify the analog frontend supply and ground.
Likely Cause
Floating input, loose ground, supply noise, or excessive display sensitivity. Verify the common ground and wiring, then restore the default sensitivity.
Likely Cause
Incorrect GP23 connection, LED orientation, or power issue. Verify data direction, power, ground, and LED_COUNT.
Likely Cause
SPI configuration, poor wiring quality, or excessive program workload. Shorten the wiring, restore the tested code, and confirm the configured SPI pins.
07 Engineering Challenges
Extend · Measure · Analyze

Take the System Beyond the First Working Version

The current visualizer establishes a complete path from analog input to digital output. The next step is to improve how the system calibrates itself, extracts useful information, and represents the signal.

Design Direction

Each challenge changes a different layer of the system. Start with signal calibration, then add a new measurement feature, and finally move from time-domain visualization into frequency-domain analysis.

CHALLENGE 01 Calibration
Signal Reference

Auto-Calibrate the Centre Line

The current program assumes that the quiet ADC midpoint is 32,768. Replace this fixed assumption by measuring the average ADC value during startup and using the measured result as the waveform centre.

Test Question

Does automatic calibration improve waveform stability or reduce offset when the actual microphone bias differs from the assumed midpoint?

CHALLENGE 02 Feature Extraction
Signal Magnitude

Add a Peak Indicator

Track the largest recent signal magnitude and display it as a marker, separate LED state, or other visual reference. Add a decay mechanism so the peak remains visible briefly before returning toward the current signal level.

Design Question

How long should the peak remain visible, and how quickly should it decay so that short transients remain readable without obscuring new measurements?

CHALLENGE 03 Signal Analysis
Frequency Domain

Build an FFT Spectrum Display

The current waveform shows how the signal changes with time, but it does not directly show which frequencies are present. Extend the project with an FFT-based spectrum display and compare speech, a musical tone, and broadband noise.

Analysis Question

What information becomes easier to interpret in the frequency domain that is difficult to identify from the time-domain waveform alone?

Progression
Build → Calibrate → Measure → Extract Features → Analyze
Next Direction

The natural next project is an audio spectrum analyzer. The same microphone and ADC path can be reused, but instead of drawing amplitude versus time, the sampled data can be processed to reveal the frequency content of speech, musical tones, and other signals.

Project Conclusion PROJECT NOTE · 01 / END
Complete Signal Path

From Sound to a Working Embedded System

This project connects several engineering layers that are often studied separately. The analog frontend determines what signal reaches the microcontroller. The ADC creates the bridge into software. The RP2040 processes the samples, and the display and RGB LEDs turn otherwise invisible electrical behaviour into something that can be observed, tested, and improved.

System Sound → Analog Front-End → ADC → Software → Visualization

BECOME A PIONEER

Subscribe our monthly newsletter to gain access to exclusive hardware deep-dives and priority testing for new EIM innovations.

One high-value briefing per month. No spam, just pure engineering. Unsubscribe anytime.