Chapter 2: Passive Buzzer (LEDC PWM Tone Control)
2.1 Key Points
- LEDC timer and channel configuration
- Dynamic PWM frequency changes for tone generation
- Duty cycle and sound output relationship
- Note frequency table and melody playback logic
2.2 Course Content
A passive buzzer does not contain an internal oscillator. It must be driven by an external square wave, and the frequency determines the pitch. ESP32-S3's LEDC peripheral can generate PWM at flexible frequencies, making it suitable for melody playback.
This chapter implements an ascending and descending C major scale.
2.3 Basic Learning
LEDC Structure
LEDC contains timers and channels:
- The timer defines clock source, resolution, and frequency.
- The channel binds a GPIO to a timer and sets duty cycle.
For the buzzer, OSRCORE uses LEDC_TIMER_1 with 10-bit resolution. A duty value of 512 produces a 50% duty square wave. Muting the buzzer is done by setting the duty to zero.
Note Frequencies
text
C4=262 D4=294 E4=330 F4=349
G4=392 A4=440 B4=494 C5=5232.4 Program Study
Initialize the timer and channel:
c
ledc_timer_config_t timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_10_BIT,
.timer_num = LEDC_TIMER_1,
.freq_hz = 1000,
.clk_cfg = LEDC_AUTO_CLK,
};
ledc_timer_config(&timer);
ledc_channel_config_t ch = {
.gpio_num = 42,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LEDC_CHANNEL_2,
.timer_sel = LEDC_TIMER_1,
.duty = 0,
};
ledc_channel_config(&ch);Play a single note:
c
static void buzzer_tone(uint32_t freq_hz, uint32_t duration_ms)
{
ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_1, freq_hz);
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2, 512);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2);
vTaskDelay(pdMS_TO_TICKS(duration_ms));
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2, 0);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2);
}2.5 Summary
This chapter showed how to drive a passive buzzer with LEDC and how to change tone by changing PWM frequency. LEDC is also used later for ESC and servo PWM output.