LED-PWM example for a beginner?

jabakobob
Posts: 7
Joined: Thu Dec 29, 2016 11:48 am

LED-PWM example for a beginner?

Postby jabakobob » Thu Dec 29, 2016 2:27 pm

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

onehorse
Posts: 70
Joined: Mon Feb 15, 2016 1:35 am

Re: LED-PWM example for a beginner?

Postby onehorse » Thu Dec 29, 2016 5:40 pm

Here is an example using the Arduino IDE:

https://github.com/kriswiner/ESP32/tree/master/PWM

jabakobob
Posts: 7
Joined: Thu Dec 29, 2016 11:48 am

Re: LED-PWM example for a beginner?

Postby jabakobob » Thu Dec 29, 2016 9:39 pm

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)

ESP_Angus
Posts: 2025
Joined: Sun May 08, 2016 4:11 am

Re: LED-PWM example for a beginner?

Postby ESP_Angus » Fri Dec 30, 2016 12:45 am

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

jabakobob
Posts: 7
Joined: Thu Dec 29, 2016 11:48 am

Re: LED-PWM example for a beginner?

Postby jabakobob » Tue Jan 03, 2017 4:44 pm

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):

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) );
}

dwitit
Posts: 1
Joined: Tue Jun 12, 2018 4:26 pm

Re: LED-PWM example for a beginner?

Postby dwitit » Tue Jun 12, 2018 4:28 pm

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 18 guests