Back to Projects

STM32 Pong Controller

An ECE 4240 embedded systems lab project integrating an ST7735 SPI display, DMA transfers, timer interrupts, and filtered analog input into a playable Pong game.

STM32 Pong Controller setup

Tools and Languages

STM32CSPIDMATIM4 InterruptsADCOversamplingEWMA FilteringST7735 LCD

8 samples

ADC averaging per update

Overview

Developed as an ECE 4240 lab project, this work brought together display communication, hardware-assisted transfers, and analog input processing on an STM32. Starting with an unbuffered SPI display test, the lab progressed to DMA-backed graphics and a Pong game controlled by a linear potentiometer.

Engineering Problem

The system needed to update the display efficiently while turning noisy analog readings into stable paddle movement. CPU-driven SPI transfers added drawing overhead, while raw potentiometer readings could cause visible jitter. The goal was to improve graphics throughput and input quality without making the controls feel sluggish.

Display Integration and DMA

  • Configured SPI2 and GPIO control pins, wired the ST7735 LCD, and validated the connection with display test routines.
  • Enabled SPI2 transmit DMA, memory-to-memory DMA, and TIM4 interrupts to support framebuffer copying and display transfers.
  • Compared display-operation timings before and after enabling DMA; the recorded tests showed lower operation times with the DMA-backed driver.
  • Used the existing driver’s framebuffer and windowed-addressing approach to reduce repeated SPI commands and transfer image data in larger blocks.

Analog Input and Filtering

  • Configured an ADC input and connected the linear potentiometer to 3V, ground, and the ADC pin.
  • Collected eight ADC samples per update and averaged them before filtering.
  • Applied an exponentially weighted moving average (EWMA) to reduce noise while retaining responsive control.
  • Passed the filtered reading into runPongGame() and verified that paddle position followed the potentiometer smoothly.

Timing and Game Integration

Integrated the provided Pong game files with the display and input pipeline. The game uses getFrameCount(), updated by the display driver’s TIM4 interrupt, to wait for the previous frame before advancing. This connects game updates to the display-transfer cadence rather than running the game loop independently of rendering.

Testing and Results

Built and loaded the firmware on the physical STM32 setup, ran the display test suite, compared transfer timings, and tested the game with the potentiometer. The completed prototype demonstrated playable Pong with stable, responsive paddle movement. Oversampling and EWMA filtering reduced the jitter observed with noisy analog input.

Things Learned

The lab reinforced how DMA, interrupts, and buffering work together to improve an embedded graphics pipeline. It also highlighted the tradeoff in input filtering: stronger smoothing reduces noise but adds lag, while weaker smoothing responds faster and exposes more jitter. Integrating the display driver, game loop, and ADC processing made those tradeoffs visible on real hardware.