Page 1 of 1

Audio Signal via PWM with ESP32-C3

Posted: Sat Nov 02, 2024 2:04 pm
by berferd
Hi guys,

I'm trying to control a passive buzzer with a GPIO output pin. This is on an ESP32-C3-Super-Mini-Board, and I'm using the IDF Framework for bare metal programming (i.e. no Arduino).

I was successful with generating audio in general, but only for the first call to tone_play(). When stopping audio and trying to re-start (with same or different frequency), it fails: I tried lots of variants, but I either get an error message
E (1199) ledc: ledc_timer_del(767): timer hasn't been configured, or it is still running, please stop it with ledc_timer_pause first
, or audio continues playing with the first chosen frequency (not with the new one). It seems the timer continues to run somehow, but I have not found any way to stop it properly so IDF would not complain anymore (and ledc_timer_del() does not seem to be available (anymore?)).

The code I have based on https://github.com/pcbreflux/espressif/ ... pio_task.c, and it looks as follows;

Code: Select all

#define GPIO_SPEAKER		GPIO_NUM_0
#define GPIO_OUTPUT_SPEED LEDC_LOW_SPEED_MODE	// no LEDC_HIGH_SPEED_MODE for ESP32-C3

void tone_play(uint32_t freq) {
	ledc_timer_config_t timer_conf;
	timer_conf.speed_mode = GPIO_OUTPUT_SPEED;
	timer_conf.duty_resolution =  LEDC_TIMER_8_BIT;
	timer_conf.timer_num  = LEDC_TIMER_0;
	timer_conf.freq_hz    = freq;
	timer_conf.clk_cfg = LEDC_AUTO_CLK;              // Auto select the source clock
	ledc_timer_config(&timer_conf);

	ledc_channel_config_t ledc_conf;
	ledc_conf.gpio_num   = GPIO_SPEAKER;
	ledc_conf.speed_mode = GPIO_OUTPUT_SPEED;
	ledc_conf.channel    = LEDC_CHANNEL_0;
	ledc_conf.intr_type  = LEDC_INTR_DISABLE;
	ledc_conf.timer_sel  = LEDC_TIMER_0;
	ledc_conf.duty       = 0x0; // 8 bit: 50%=0x7F, 100%=0xFF
	ledc_conf.hpoint     = 0;
	ledc_channel_config(&ledc_conf);

	ledc_set_duty(GPIO_OUTPUT_SPEED, LEDC_CHANNEL_0, 0x7F); // 50% duty cycle
	ledc_update_duty(GPIO_OUTPUT_SPEED, LEDC_CHANNEL_0);
}


void tone_stop(void) {
	ledc_set_duty(GPIO_OUTPUT_SPEED, LEDC_CHANNEL_0, 0);
	ledc_update_duty(GPIO_OUTPUT_SPEED, LEDC_CHANNEL_0);
}

void _delay_ms(uint32_t ms) {
	vTaskDelay(ms / portTICK_PERIOD_MS);
}

/* ... and this code in main() */
	gpio_set_direction(GPIO_SPEAKER, GPIO_MODE_OUTPUT);
	gpio_set_level(GPIO_SPEAKER, 0);
	tone_play(n_o6_Dis); _delay_ms(500);
	tone_stop();
        _delay_ms(500);
	tone_play(n_o4_C); _delay_ms(500);
	tone_stop();
I have also experimented with adding

Code: Select all

	ledc_timer_pause(GPIO_OUTPUT_SPEED, LEDC_TIMER_0);
	ledc_stop(GPIO_OUTPUT_SPEED, LEDC_CHANNEL_0, 0);
in the tone_stop() functuion, but it did not change much.

Also, in the log I'm getting a warning message
W (1199) ledc: GPIO 0 is not usable, maybe conflict with others
which is not sure if it's related or meaning anything. I do not use GPIO0 for anything else.


Any ideas?

Re: Audio Signal via PWM with ESP32-C3

Posted: Sun Nov 03, 2024 8:34 am
by aliarifat794
The warning GPIO 0 is not usable, maybe conflict with others suggests that GPIO 0 may be reserved. You can try to connect the speaker to another GPIO pin and see if the issue still persists.