Skip to content

AbanoubSalah/esp32-dma-pwm-controller

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Build Status

ESP32-S3 High-Performance Potentiometer-Controlled PWM

A professional-grade implementation of a real-time control loop on the ESP32-S3. This project uses high-speed DMA-driven ADC sampling and a dedicated control task to manage high-resolution PWM output with minimal CPU overhead.

πŸ›  Technical Specifications

Circuit Design

The hardware interface is designed in KiCad.


System Schematic

Hardware 3D View

Bill of Materials (BOM)

Reference Value Package/Footprint Description
U2 ESP32-S3-WROOM-1 Module_ESP32-S3 Dual-core Wi-Fi/BT MCU
C1 10 nF 0805 or 1206 (SMD) Ceramic Decoupling Capacitor
C2 100 ΞΌF Radial Electrolytic Polarized Bulk Capacitor (Check Polarity!)
Cf1 0.10 nF 0805 or 1206 (SMD) Ceramic Filtering Capacitor
R1 10 kΞ© 0805 or 1206 (SMD) Pull-up Resistor for EN pin
Rf1 10 kΞ© 0805 or 1206 (SMD) Filtering Resistor for ADC input pin
RV1 10 kΞ© Potentiometer Through-hole Breadboard Friendly Pot
PWR1 2-pin Header 2.54mm Pitch Power Input (3.3V / GND)
IO1 4-pin Header 2.54mm Pitch Signal Output (Multimeter/Logic Analyzer)

πŸ”¬ Real-Time Performance

Using a Latency Trigger (GPIO toggle inside the ISR and after the PWM update), the control loop timing was verified:

  • PWM Frequency: 5 KHz (Configured via LEDC)
  • PWM Resolution: 13-bit (0...8191 steps)
  • System Latency: ~60 ΞΌs from ADC interrupt to PWM update.

Signal Conditioning

  • Filter Type: Single-pole Digital IIR (Exponential Moving Average).
  • Update Cadence: 19.53 Hz (Synchronized with DMA ISR).
  • Coefficient (Ξ±): 0.1.
  • Cutoff Frequency (fc): ~0.35 Hz.
  • Effect: Provides -40dB attenuation at 10Hz, effectively eliminating mechanical potentiometer chatter and 50Hz environmental EMI.

πŸ— System Architecture

The firmware is designed with a "Producer-Consumer" model to ensure that high-frequency sampling does not block the application logic:

  • Producer (Core 0/ISR): High-speed ADC sampling using DMA. Data is transferred in batches to a FreeRTOS Queue without CPU intervention.
  • Consumer (Core 1): A dedicated task that unblocks upon queue reception, performs IIR filtering, maps the 12-bit ADC range to 13-bit PWM space, and updates the LEDC peripheral.
  • Actuation: The LEDC Hardware Fade Engine handles the PWM output, ensuring smooth duty cycle transitions.

πŸ”¬ Hardware Verification (Logic Analyzer)

To maintain observability, the project includes a debug_pins component that toggles GPIOs at critical execution points. These captures verify the real-time budget.

End-to-End Latency

  • Channel 1 (D1): Resulting 5kHz PWM Output.
  • Channel 2 (D2): ADC Interrupt Lifecycle.
  • Channel 3 (D3): Processing Task execution time.

πŸ§ͺ Quality Assurance: TDD

The core processing logic is validated using the Unity Test Framework. Tests ensure that the mapping remains accurate and that edge cases (like calibration limits) are handled gracefully.

Test Case Example:

  • ADC to PWM Mapping is linear: Validates that a mid-point ADC value of 2048 results in a PWM duty cycle of 4096.

πŸ“‚ Project Structure

  • components/adc_dma: Low-level GDMA configuration for continuous ADC.
  • components/pwm_engine: LEDC configuration for 13-bit precision.
  • components/processing_logic: Math library for fixed-point filtering and mapping.
  • components/debug_pins: GPIO abstraction for logic analyzer instrumentation.
  • test_app: Unit tests for verifying the linear mapping and filter response.

πŸš€ Getting Started

Prerequisites

  • ESP-IDF v5.5.3
  • Unity Test Component (for test_app)
  • ESP32-S3 Development Board
  • Potentiometer connected to GPIO1 (ADC1_CH0) through a Low Pass Filter (LPF) RC

Configuration

Toggle debug hardware pins via menuconfig:

idf.py menuconfig
# Navigate to "Debug Configuration" -> "Enable Hardware Debug Toggles"

Building and Flashing

idf.py set-target esp32s3
idf.py build
idf.py flash monitor

Running Tests

This project uses the Unity test framework. To run the math verification:

cd test_app
idf.py build flash monitor

Generate Doxygen Document

doxygen Doxyfile

πŸ“ˆ Performance & Verification

The system performance was verified using an 8-channel logic analyzer to measure task execution timing and jitter.

PWM Task Execution Timing

The following capture shows the DEBUG_PIN_PWM_TASK behavior. The high duration represents the time taken to process 256 samples and update the duty cycle. The 15 ΞΌs execution time represents only 0.29% of the available 51.2ms processing window, allowing for future expansion into more complex DSP (Digital Signal Processing) or Wi-Fi telemetry without dropping frames.

PWM Task Duration

PWM Task Duration (~15 ΞΌs)

ISR Cadence & Stability

Measurement of the on_conv_done callback frequency confirms the DMA is filling at 19.53 Hz β‰ˆ (5000 Hz / 256 samples), triggering the processing loop.

ISR Frequency

ISR Task Frequency

System Latency

This confirms the system remains deterministic within a single 5 kHz PWM period 200 ΞΌs

System Latency

End-to-end system latency measured at 100 ΞΌs

Duty Cycle Linearity

The 13-bit resolution allows for 8192 discrete steps, providing smooth, high-resolution control of the output power rail. a Β±1% variance is expected due to component tolerances and the IIR filter.

PWM Duty-Cycle Scaling

PWM at Different Inputs

Jitter & Stability

DMA-backed acquisition ensures zero-drift sampling, critical for stable IIR filtering and control loop stability

Interrupt Jitter

Interrupt Jitter Analysis

πŸš€ Future Work & Roadmap

To evolve this project from a standalone control loop into a full-scale industrial monitoring solution, the following features are planned:

1. Wi-Fi Telemetry & Dashboard (ESP-RAINMAKER)

  • Objective: Real-time remote monitoring of the ADC input and PWM duty cycle.
  • Implementation: Integrate the ESP-RainMaker framework to provide a mobile app interface for viewing live "Forensic" data without needing a physical Logic Analyzer.

2. Adaptive Calibration System

  • Objective: Automatically detect the noise floor and physical limits of the potentiometer.
  • Implementation: Develop a startup calibration routine that records the minimum and maximum raw values over a 5-second window, dynamically updating calib_min and calib_max in NVS (Non-Volatile Storage).

3. Advanced DSP (FFT Integration)

  • Objective: Detect mechanical wear in the potentiometer.
  • Implementation: Utilize the ESP32-S3's SIMD (Single Instruction, Multiple Data) instructions to perform an FFT on the 256-sample buffer. High-frequency noise spikes during rotation can be used as a "Health Indicator" for the physical component.

4. Hardware Safety Interlocks

  • Objective: Prevent "Thermal Runaway" in the power rail.
  • Implementation: Add a secondary ADC channel to monitor the temperature of the power MOSFETs, automatically throttling the PWM duty cycle if a thermal threshold is exceeded.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE.txt file for details. Copyright (c) 2026 Abanoub Salah.

About

Pot Controlled PWM using ESP32-S3 ADC & DMA

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors