Hi!
I've just started programming the ESP32 with IDF, and I am a complete beginner. I've managed to set up the tool chain and flash some examples. The next step I want to take is to control a motor with a PWM signal. It looks like the LED-PWM function of ESP32 is very versatile, but I am a bit overwhelmed with all the talk about clocks and dividers and high speed timers etc.
I'm looking for some example code that explains all the steps I need to take to get a PWM signal to a GPIO pin. I want the frequency of the signal to be around 20-25kHz (to avoid audible oscillations). I want to vary the duty cycle from 0% to 100%, the phase of the PWM signal is not important.
Is there someone who has some working code to share?
Thank you for your help in advance!
Jakob
LED-PWM example for a beginner?
Re: LED-PWM example for a beginner?
I've already seen that example. But as far as I understand, this just works if I use the Arduino IDE, right? Those ledc-funtions are not available in IDF, are they?
I don't want to use the Arduino IDE since it is still missing a few important bits (as far as I understand UDP and analog read are still missing, which is important for my project)
I don't want to use the Arduino IDE since it is still missing a few important bits (as far as I understand UDP and analog read are still missing, which is important for my project)
Re: LED-PWM example for a beginner?
It's not a standalone example, but in esp-idf the "16_pcnt" example uses the LEDC PWM engine to generate pulses for the pulse count (PCNT) unit to count. You can break out the PCNT example code by itself to control an LED.
The LEDC reference documentation is here: http://esp-idf.readthedocs.io/en/latest ... ader-files
The LEDC reference documentation is here: http://esp-idf.readthedocs.io/en/latest ... ader-files
Re: LED-PWM example for a beginner?
Thanks a lot, Angus! That example helped a lot, I was able to get it working. It turned out to be really simple:
- first call ledc_channel_config() to set up a PWM channel
- then call ledc_timer_config() to set up a timer
There's one caveat: don't switch the order of the calls. I tried to set up the timer first, then the channel, but that didn't work. So don't switch the order of those two statements.
Once the PWM channel is set up, you can change the duty cycle by calling ledc_set_duty() followed by ledc_update_duty().
In case anybody else is interested, here's the code I used to set up PWM for two motors (left & right):
- first call ledc_channel_config() to set up a PWM channel
- then call ledc_timer_config() to set up a timer
There's one caveat: don't switch the order of the calls. I tried to set up the timer first, then the channel, but that didn't work. So don't switch the order of those two statements.
Once the PWM channel is set up, you can change the duty cycle by calling ledc_set_duty() followed by ledc_update_duty().
In case anybody else is interested, here's the code I used to set up PWM for two motors (left & right):
Code: Select all
#include <math.h>
#include "driver/ledc.h"
#include "esp_err.h"
#define MOTOR_PWM_CHANNEL_LEFT LEDC_CHANNEL_1
#define MOTOR_PWM_CHANNEL_RIGHT LEDC_CHANNEL_2
#define MOTOR_PWM_TIMER LEDC_TIMER_1
#define MOTOR_PWM_BIT_NUM LEDC_TIMER_10_BIT
#define RIGHT_PWM_PIN GPIO_NUM_19
#define LEFT_PWM_PIN GPIO_NUM_21
void motor_pwm_init(void)
{
ledc_channel_config_t ledc_channel_left = {0}, ledc_channel_right = {0};
ledc_channel_left.gpio_num = LEFT_PWM_PIN;
ledc_channel_left.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_channel_left.channel = MOTOR_PWM_CHANNEL_LEFT;
ledc_channel_left.intr_type = LEDC_INTR_DISABLE;
ledc_channel_left.timer_sel = MOTOR_PWM_TIMER;
ledc_channel_left.duty = 0;
ledc_channel_right.gpio_num = RIGHT_PWM_PIN;
ledc_channel_right.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_channel_right.channel = MOTOR_PWM_CHANNEL_RIGHT;
ledc_channel_right.intr_type = LEDC_INTR_DISABLE;
ledc_channel_right.timer_sel = MOTOR_PWM_TIMER;
ledc_channel_right.duty = 0;
ledc_timer_config_t ledc_timer = {0};
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_timer.bit_num = MOTOR_PWM_BIT_NUM;
ledc_timer.timer_num = MOTOR_PWM_TIMER;
ledc_timer.freq_hz = 25000;
ESP_ERROR_CHECK( ledc_channel_config(&ledc_channel_left) );
ESP_ERROR_CHECK( ledc_channel_config(&ledc_channel_right) );
ESP_ERROR_CHECK( ledc_timer_config(&ledc_timer) );
}
void motor_pwm_set(float left_duty_fraction, float right_duty_fraction) {
uint32_t max_duty = (1 << MOTOR_PWM_BIT_NUM) - 1;
uint32_t left_duty = lroundf(left_duty_fraction * (float)max_duty);
uint32_t right_duty = lroundf(right_duty_fraction * (float)max_duty);
ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, MOTOR_PWM_CHANNEL_LEFT, left_duty) );
ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, MOTOR_PWM_CHANNEL_LEFT) );
ESP_ERROR_CHECK( ledc_set_duty(LEDC_HIGH_SPEED_MODE, MOTOR_PWM_CHANNEL_RIGHT, right_duty) );
ESP_ERROR_CHECK( ledc_update_duty(LEDC_HIGH_SPEED_MODE, MOTOR_PWM_CHANNEL_RIGHT) );
}
Re: LED-PWM example for a beginner?
Thanks a lot, I had those functions flipped because they were flipped in the ledc example in the IDF...
Who is online
Users browsing this forum: No registered users and 58 guests