Learn to generate PWM signals with the ESP32 using Arduino IDE. We’ll explain two different methods: using analogWrite and using the LEDC API. As an example, we’ll build a simple circuit to fade an LED.
Updated 11 June 2024
Before proceeding with this tutorial you should have the ESP32 add-on installed in your Arduino IDE. Follow the next tutorial to install the ESP32 on the Arduino IDE, if you haven’t already.
This tutorial is compatible with ESP32 board add-on version 3.X or above – learn more in our migration guide.
Table of Contents
- ESP32 PWM Controller
- Dimming an LED with the ESP32
- ESP32 PWM Example using analogWrite – Code
- ESP32 PWM Example using the LEDC API – Code
Parts Required
To follow this tutorial you need these parts:
- ESP32 DOIT DEVKIT V1 Board – read best ESP32 development boards
- 3x 5mm LED
- 3x 330 Ohm resistor (or similar values)
- Breadboard
- Jumper wires
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
ESP32 LED PWM Controller
The ESP32 has an LED PWM controller with 6 to 16 independent channels (depending on the ESP32 model) that can be configured to generate PWM signals with different properties.
There are different functions you can use to generate PWM signals and achieve the same results. You can use analogWrite (like in Arduino boards) or you can use LEDC functions.
analogWrite
The most basic function is analogWrite which accepts as arguments the GPIO where you want to generate the PWM signal and the duty cycle value (ranging from 0 to 255).
void analogWrite(uint8_t pin, int value);
For example:
void analogWrite(2, 180);
Set the Frequency and Resolution
You can set the resolution and frequency of the PWM signal on a selected pin by using the analogWriteResolution and analogWriteFrequency functions.
To set the resolution:
void analogWriteResolution(uint8_t pin, uint8_t resolution);
To set the frequency:
void analogWriteFrequency(uint8_t pin, uint32_t freq);
LEDC Functions
Alternatively, you can use the Arduino-ESP32 LEDC API. First, you need to set up an LEDC pin. You can use the ledcAttach or ledcAttachChannel functions.
ledcAttach
The ledcAttach function sets up an LEDC pin with a given frequency and resolution. The LEDC channel will be selected automatically.
bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution);
This function will return true if the configuration is successful. If false is returned, an error occurs and the LEDC channel is not configured.
ledcAttachChannel
If you prefer to set up the LEDC channel manually, you can use the ledcAttachChannel function instead.
bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel);
This function will return true if the configuration is successful. If false is returned, an error occurs and the LEDC channel is not configured.
ledcWrite
Finally, after setting the LEDC pin using one of the two previous functions, you use the ledcWrite function to set the duty cycle of the PWM signal.
void ledcWrite(uint8_t pin, uint32_t duty);
This function will return true if setting the duty cycle is successful. If false is returned, an error occurs and the duty cycle is not set.
For more information and all functions of the LEDC PWM controller, check the official documentation.
Dimming an LED with the ESP32
To show you how to generate PWM signals with the ESP32, we’ll create two simple examples that dim the brightness of an LED (increase and decrease brightness over time). We’ll provide an example using analogWrite and another using the LEDC functions.
Schematic
Wire an LED to your ESP32 as in the following schematic diagram. The LED should be connected to GPIO 16.
(This schematic uses the ESP32 DEVKIT V1 module version with 30 GPIOs – if you’re using another model, please check the pinout for the board you’re using.)
Note: You can use any pin you want, as long as it can act as an output. All pins that can act as outputs can be used as PWM pins. For more information about the ESP32 GPIOs, read: ESP32 Pinout Reference: Which GPIO pins should you use?
ESP32 PWM Example using analogWrite – Code
Open your Arduino IDE and copy the following code. This example increases and decreases the LED brightness over time using the analogWrite function.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-pwm-arduino-ide/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
// the number of the LED pin
const int ledPin = 16; // 16 corresponds to GPIO 16
void setup() {
// set the LED as an output
pinMode(ledPin, OUTPUT);
}
void loop(){
// increase the LED brightness
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
// changing the LED brightness with PWM
analogWrite(ledPin, dutyCycle);
delay(15);
}
// decrease the LED brightness
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
// changing the LED brightness with PWM
analogWrite(ledPin, dutyCycle);
delay(15);
}
}
You start by defining the pin the LED is attached to. In this example, the LED is attached to GPIO 16.
const int ledPin = 16; // 16 corresponds to GPIO 16
In the setup(), you need to configure the LED as an output using the pinMode() function.
pinMode(ledPin, OUTPUT);
In the loop(), you vary the duty cycle between 0 and 255 to increase the LED brightness.
// increase the LED brightness
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
// changing the LED brightness with PWM
analogWrite(ledPin, dutyCycle);
delay(15);
}
Notice the use of the analogWrite() function to set up the duty cycle. You just need to pass as arguments the LED pin and the duty cycle.
analogWrite(ledPin, dutyCycle);
Finally, we vary the duty cycle between 255 and 0 to decrease the brightness.
// decrease the LED brightness
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
// changing the LED brightness with PWM
analogWrite(ledPin, dutyCycle);
delay(15);
}
Testing the Example
Upload the code to your ESP32. Make sure you have the right board and COM port selected. Look at your circuit. You should have a dimmer LED that increases and decreases brightness over time.
ESP32 PWM Example using the LEDC API – Code
Open your Arduino IDE and copy the following code. This example increases and decreases the LED brightness over time using the ESP32 LEDC functions.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-pwm-arduino-ide/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
// the number of the LED pin
const int ledPin = 16; // 16 corresponds to GPIO16
// setting PWM properties
const int freq = 5000;
const int resolution = 8;
void setup(){
// configure LED PWM
ledcAttach(ledPin, freq, resolution);
// if you want to attach a specific channel, use the following instead
//ledcAttachChannel(ledPin, freq, resolution, 0);
}
void loop(){
// increase the LED brightness
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
// changing the LED brightness with PWM
ledcWrite(ledPin, dutyCycle);
delay(15);
}
// decrease the LED brightness
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
// changing the LED brightness with PWM
ledcWrite(ledPin, dutyCycle);
delay(15);
}
}
You start by defining the pin the LED is attached to. In this example, the LED is attached to GPIO 16.
const int ledPin = 16;
Set the PWM properties: frequency and resolution.
// setting PWM properties
const int freq = 5000;
const int resolution = 8;
As we’re using 8-bit resolution, the duty cycle will be controlled using a value from 0 to 255.
In the setup(), set up the LEDC pin—use the ledcAttach function as follows.
ledcAttach(ledPin, freq, resolution);
This will configure the LEDC pin with the frequency and resolution defined previously on a default PWM channel.
If you want to set up the PWM channel yourself, you need to use ledcAttachChannel instead. The last argument of this function is the PWM channel number.
ledcAttachChannel(ledPin, freq, resolution, 0);
Finally, in the loop(), you increase and decrease the brightness of the LED over time.
The following lines increase the LED brightness.
// increase the LED brightness
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
// changing the LED brightness with PWM
ledcWrite(ledPin, dutyCycle);
delay(15);
}
Notice the use of the ledcWrite() function to set up the duty cycle. You just need to pass as arguments the LED pin and the duty cycle.
ledcWrite(ledPin, dutyCycle);
Finally, we vary the duty cycle between 255 and 0 to decrease the brightness.
// decrease the LED brightness
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
// changing the LED brightness with PWM
ledcWrite(ledPin, dutyCycle);
delay(15);
}
Testing the Example
Upload the code to your ESP32. Make sure you have the right board and COM port selected. Look at your circuit. You should have a dimmer LED that increases and decreases brightness over time just like in the previous example.
Wrapping Up
In summary, in this article, you learned how to use the LED PWM controller of the ESP32 with the Arduino IDE to dim an LED. The concepts learned can be used to control other outputs with PWM by setting the right properties to the signal.
We have more ESP32 resources you may like:
- Getting Started with ESP32 Dev Module
- ESP32 Pinout Reference: Which GPIO pins should you use?
- ESP32 Digital Inputs and Digital Outputs (Arduino IDE)
- ESP32 ADC – Read Analog Values with Arduino IDE
- ESP32 with PIR Motion Sensor using Interrupts and Timers
- More ESP32 Tutorials and Projects
This is an excerpt from our course: Learn ESP32 with Arduino IDE. If you like ESP32 and you want to learn more, we recommend enrolling in Learn ESP32 with Arduino IDE course.
Hi,
This is a good tutorial for PWM or analog output, however could you try my analogWrite implementation for ESP?
Please give it a shout here https://github.com/ERROPiX/ESP32_AnalogWrite
Thank you
Hi.
Thank you for sharing that library.
I’ll give it a try, and update the article to include your solution.
Regards,
Sara 🙂
Obrigado pelo biblioteca, me ajudou muito em meus projetos.
Trying to figure out where the ledxxxxx functions are defined. Don’t see any #include x.h in the codes
Hi dale.
Those functions are part of the ESP32 core library for the Arduino IDE by default.
So, once you have ESP32 installed on Arduino IDE, you don’t need to include anything else in your code to use those functions.
Regards,
Sara 🙂
Good & simple
Thanks 🙂
Hi, I’m trying to connect LED PWM and servo. PWM works perfect, but when I write
myservo.attach(33); to setup PWM stops working. Using
https://randomnerdtutorials.com/esp32-servo-motor-web-server-arduino-ide/
Any idea?
Hi Lucasz.
Can you provide more details?
Are you getting any error on the serial monitor?
Regards,
Sara
I am having the same problem! I have 2 similar projects, except one has a servo as well. I am trying to use PWM to vary the backlight intensity of an LCD on both projects, It works perfectly on one board, very badly on the other. I finally traced it down to a conflict between Servo.h and the ledc both using the same hardware timer (Servo wins out, and the PWM can only output a few hundred millivolts. (More if you lower the PWM frequency)
Any idea of how to solve this issue?
Actually, I see now, that as my servo output goes up (higher degrees of rotation) the PWM output goes up as well. This is for a PWM output of 255(in 8 bit resolution) The max PWM output is still only a few hundred millivolts.
Actually, I have figured out the issue, for anyone else happening to read this. The Servo and ledc are using the same timer, and Serho.h grabbed the timer first. You need to set things up so that the ledc uses a different timer than Servo.
Hi Sara,
“All GPIOs are outputting the same PWM signal. So, all three LEDs increase and decrease the brightness simultaneously, resulting in a synchronized effect.”
Is itpossible to setup the different channels with different frequency and PWM in order to control the LED brightness separately?
Hi.
Yes, you can do that.
However, please note that 0 and 1 will share the same frequency, as well as channels 2 and 3, 5 and 5. See this discussion that might be helpful: https://rntlab.com/question/esp32-pwm-frequency-selection/
Regards,
Sara
You can also use macros when defining constants.
So instead of const int ledPin = 16, you can use:
#define LEDPIN 16
it saves memory
const int ledPin = 16
Will not actually consume any RAM: the compiler knows there is no reason to create a variable in RAM, so it’ll stay out of RAM (it will be stored in flash memory).
#define ledPin 16
Can actually become a bad practice… Why?
Because it can lead to very hard to find bugs.
Think about this mistake:
#define ledPin 16;
The “text-replace” nature of
#define
can mislead you with a stray semicolon or other unexpected replace…Apart from that, concerning the desired light effect on a LED, here is a simple idea to give the impression that it breathes:
void loop(){
ledcWrite(ledChannel, 128 – 128 * cos(2*PI*(millis() % 2001)/2000));
}
hi
can I have different frequencies for each of 16 pins?
(different PWMs with adjaustble duty cycles and frequencies for all pins)?
Hi.
In theory, that’s possible. You need to create different PWM channels with different frequencies.
However, I’m not sure if in practical terms, the ESP32 can handle all the 16 channels at the same time. You have to experiment to find out.
Regards,
Sara
thank you very much for the reply.
one another question
can we change the frequency of a channel while running the program (with coding in the loop)?
without resetting the esp?
Hi. I never tried that.
But, it should be possible.
Regards,
Sara
I have tried this driving a two tone sounder.
change the frequency with ledcSetup(), and remember to then perform a ledcWrite().
void loop() {
// put your main code here, to run repeatedly:
ledcSetup(1, 2048, 8);
ledcWrite(1, 127);
delay(2000);
ledcSetup(1, 4069, 8);
ledcWrite(1, 127);
delay(2000);
}
thank mike . seems works .
I’ve used Arduinos for a long time now but now need to use the ESP32 Devkit. I need to drive 4 motors (same freq for each, but different duty cycle) and I need to drive two or four RC type servos. When I run code for PWM for the BLDC motors, it works fine. If I run code to just position the servos, it works fine. When I try to combine the code, it appears that setting the freq for the PWM messes up the servos. It doesn’t want to give me a 50Hz frame rate. Do you know if there is a conflict between the servo library and the standard PWM functions of the ESP32? I’ve bought two of your courses, but the answer doesn’t seem to be there and I haven’t found anything online yet.
Hi Mark.
Please post your question on the RNTLAB forum. I can help you better there: https://rntlab.com/forum/
Just login with the email you used to buy the courses.
Regards,
Sara
I’m wondering and confounded by how you would set off a second (or more) LED light at a different time, but repeat the same cycle as the first LED? Say, when the first LED begins to decrease brightness, the second LED would start to increase its brightness.
I’ve tried calling a custom function nextLight() within the for loop. Doing that simply stops the first LED’s cycle while the nextLight LED runs fully. It’s wonky. Unintuitive.
const int redLED1=26;
const int redLED2=25;
// setting PWM properties
const int freq=5000; // 5000Hz for our LEDs here
const int freq2=5000;
const int ledChannel=0;
const int ledChannel2=2;
const int resolution=8;
const int resolution2=8;
void setup() {
ledcSetup(ledChannel, freq, resolution);
ledcSetup(ledChannel2,freq2,resolution2);
// attach the channel to the GPIO to be controlled
ledcAttachPin(redLED1, ledChannel);
ledcAttachPin(redLED2, ledChannel2);
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
//increase LED brightness channel 1
for(int dutyCycle=0;dutyCycle<=255; dutyCycle++){
// changing the LED brightness with PWM
ledcWrite(ledChannel, dutyCycle);
delay(15);
}
// decrease LED brightness channel 1
for(int dutyCycle=255;dutyCycle>=0;dutyCycle–){
// changing the LED brightness with PWM
if(dutyCycle==250){
nextLight():
}
ledcWrite(ledChannel, dutyCycle);
delay(15);
}
}
void nextLight(){
for(int dutyCycle=0;dutyCycle<=255; dutyCycle++){
// changing the LED brightness with PWM
ledcWrite(ledChannel2, dutyCycle);
delay(15);
}
for(int dutyCycle=255;dutyCycle>=0;dutyCycle–){
// changing the LED brightness with PWM
ledcWrite(ledChannel2, dutyCycle);
delay(15);
}
}
Hi.
Have you considered using tasks?
Read this tutorial: https://randomnerdtutorials.com/esp32-dual-core-arduino-ide/
Regards,
Sara
Did you try this?
ledcWrite(ledChannel1, 255-dutyCycle);
Thank you Sara.
I tried the PWM example as coded in the tutorial and it did not function. I looked at a PinOut of a 30 Pin ESP32 board and found that ADC channel 0 is on the same pin as GP04. I moved the led to GP04, changed the code to reflect the move and the PWM example is now functional. It seems as if ADC channels are tied to specific GPIO’s.
Hi! I haven’t understood the channel that we need to choose. what is it depend on? in your code I have tried to change the channel from 0 to 2 It still worked.
Hi.
You can choose any channel from 0 to 15.
Regards,
Sara
Hello Sara, I am writing to you from Ecuador, my question is how can I perform a power control of a led using a potentiometer in an MCU Esp 32, thank you very much
Hello Sarah,
I am not sure I understand the nature of the programmability of the LED channels and
I feel confused by this sentence above, “You can get the same signal from the same channel in different GPIOs.”
Might it be,
You can set the same PWM signal to more than one GPIOs.
Is it that you set a GPIO to a channel?
Or are we setting a channel more than once to different GPIOs.
For what it is worth I am on page 304 of your Building Web Server book and am getting a lot of value out of the book! I came here to better understand the LED and PWM system in the ESP32.
Thanks,
Forrest Erickson
Hi Forrest.
What I mean by “You can get the same PWM signal on more than one GPIO” is that you can set the same PWM signal (and the same channel) on more than one GPIO.
In the ESP32, PWM channels produce PWM signals. You then attach those channels to the GPIOs where you want to have the signals. If you want to have the same signals on multiple GPIOs, you don’t need to create multiple PWM channels. You can use the same channel for multiple GPIOs.
For example, it is possible to have the following scenarios:
– PWM channel 1 –> signal on GPIO 23
– PWM channel 1 –> signal on GPIO 22
– PWM channel 1 –> signal on GPIO 21
All GPIOs will have the same PWM signal.
I’m sorry if this is confusing. English is not my native language, and sometimes my sentences seem clear to me, but not so much for others.
Regards,
Sara
Sara,
Thanks for the clarification. You did great. Re: “English is not my native language, and sometimes my sentences seem clear to me, but not so much for others.”
It is my native and I still mangle it.
I still had questions about the independence of the setup of the channels and did some experimenting based on your example code. I have pushed the results of the experiments to my github at: https://github.com/ForrestErickson/PWMExperiments
Bottom line. You cannot program the frequency of channel 0 and 1. The last one you set governs both.
I also experimented with higher frequencies and resolutions and here is a summary of what I found:
// Set Freq: 80KHz 100KHz 200KHz 50KHz
//const int resolution = 8; // Freq became 80.00 100.00 200.00
//const int resolution = 9; // Freq became 80.00 100.0 156.3
const int resolution = 10; // Freq became 78.13 78.13 78.13 50.00
//const int resolution = 11; // Freq became 39.06 39.06 39.06
//const int resolution = 12; // Freq became 19.53 19.53 19.53
Hope this helps visitors.
Should have said, “Bottom line. You cannot INDEPENDENTLY program the frequency of channel 0 and 1.”
Thanks for sharing your results.
It will definitely be useful for our readers.
Regards,
Sara
Hello Sir/ Mam,
I need help regarding the Motor driver control with esp32 using pwm signals.
I tried with esp32 but both motors are working at a time I need individual pwm control for each motors.
This is my ESP32 code:
//ESP32
// Set the Motor_1 PWM and Direction pin
const int m1_pwm = 16; // 16 corresponds to GPIO16–>ESP32–>RX2
const int m1_dir = 4; // 4 corresponds to GPIO4—->ESP32–>D4
//// Set the Motor_2 PWM and Direction pin
const int m2_pwm = 17; // 17 corresponds to GPIO17–>ESP32–>TX2
const int m2_dir = 5; // 5 corresponds to GPIO4—->ESP32–>D5
// setting PWM properties for motor 1
const int freq_1 = 5000;
const int resolution_1= 8;
const int pwmChannel_1 = 0;
// setting PWM properties for motor 2
const int freq_2 = 5000;
const int resolution_2= 8;
const int pwmChannel_2 = 0;
void setup(){
// configure Motor PWM functionalitites
ledcSetup(pwmChannel_1, freq_1, resolution_1);
ledcSetup(pwmChannel_2, freq_2, resolution_2);
// attach the channel to the GPIO to be controlled
ledcAttachPin(m1_pwm, pwmChannel_1);
ledcAttachPin(m2_pwm, pwmChannel_2);
pinMode(m1_dir,OUTPUT); // Motor 1 direction output pin
pinMode(m2_dir,OUTPUT); // Motor 1 direction output pin
}
void loop(){
digitalWrite(m1_dir,HIGH); // m1 with clock wise direction
ledcWrite(pwmChannel_1, 255); //0 t0 255 value
delay(1000);
digitalWrite(m1_dir,LOW); // m1 with anti clock wise direction
ledcWrite(pwmChannel_1,50);
delay(1000);
ledcWrite(pwmChannel_1,0); //stop the motor 1
delay(1000);
digitalWrite(m2_dir,HIGH); // m2 with clock wise direction
ledcWrite(pwmChannel_2, 20);
delay(1000);
digitalWrite(m2_dir,LOW); // m2 with anti clock wise direction
ledcWrite(pwmChannel_2, 150);
delay(1000);
ledcWrite(pwmChannel_2, 0); //Stop the motor 2
delay(1000);
}
When I run this code both motor are woking at a time There is no sequence of operation.
Arduino Uno Code:
//ARDUINO UNO
//Motor 1 Direction and PWM
#define m1_dir 8
#define m1_pwm 9
//Motor 2 Direction and PWM
#define m2_dir 10
#define m2_pwm 11
void setup()
{
//Motor 1 setup
pinMode(m1_dir,OUTPUT);
pinMode(m1_pwm,OUTPUT);
//Motor 2 setup
pinMode(m2_dir,OUTPUT);
pinMode(m2_pwm,OUTPUT);
}
void loop()
{
digitalWrite(m1_dir,HIGH); // m1 with clock wise direction
analogWrite(m1_pwm,255);
delay(1000);
digitalWrite(m1_dir,LOW); // m1 with anti clock wise direction
analogWrite(m1_pwm,50);
delay(1000);
analogWrite(m1_pwm,0); //stop the motor 1
delay(1000);
digitalWrite(m2_dir,HIGH); // m2 with clock wise direction
analogWrite(m2_pwm,255);
delay(1000);
digitalWrite(m2_dir,LOW); // m2 with anti clock wise direction
analogWrite(m2_pwm,50);
delay(1000);
analogWrite(m2_pwm,0); //stop the motor 2
delay(1000);
}
Arduino uno is working fine.
Please find the attached Google drive link for more information.
LInk: https://drive.google.com/drive/folders/1Mxnd4OIE9hLgx_0LpEF3GXx2r5O5J6yQ?usp=sharing
Please I need Help
Thank you in advace.
Hi.
Change the number of your PWM channel 2.
Instead of:
const int pwmChannel_2 = 0
use
const int pwmChannel_2 = 1
Regards,
Sara
Hola Sara, he generado 2 ondas PWM en diferentes GPIO que varía según un potenciometro como señal analogica de entrada.
Mi consulta es: ¿Se podría desfasar 90 grados las ondas?
Hi.
I don’t know exactly what’s the best way to do that.
The easiest way is to add a delay whose time corresponds to 90 degrees phase (I’m not sure if this works in a practical application).
Alternatively, you can use MCPWM instead that provides functions to set the phase: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/mcpwm.html
I hope this helps.
Regards,
Sara
Hi,
I tried passing a potentiometer value which is read on ADC to PWM but it didn’t work. can you walk me through how to do it?
BTW below is the code I wrote:
const int ledPin=16;
const int potPin=4;
const int freq=5000;
const int ledChannel=0;
const int resolution=16;
int dutyCycle=0;
void setup() {
// put your setup code here, to run once:
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(potPin, ledChannel);
}
void loop() {
// put your main code here, to run repeatedly:
dutyCycle=analogRead(potPin);
//dutyCycle=dutyCycle/4;
ledcWrite=(ledChannel, dutyCycle);
}
Hi.
What didn’t work about that?
Regards,
Sara
The ADC value that is saved in an int-type variable named dutyCycle is not accepted as a duty cycle parameter in PWM function
When I use PWM for my LEDs and use small values only, do I still need a resister for the LEDs?
A soros ellenállás a GPIO kimeneti áramának korlátozása miatt fontos, az esp védelmében.
attól hogy csak rövit impulzusokra kapcsolja be a ledet attól még túllépheti a GPIO maximálisan megengedett áramkorlátját, ami a kimenet meghibásodásához vezethet.
Steve
Hi!
In your forum ( https://rntlab.com/question/esp32-two-frequency-pwm-output/) you sayed channel 0 and channel 1 are grouped together.
How can I select channel to set different frequencies in different GPIOs?
Espressiv datasheet says from 0 to 15 but I can’t find how they are grouped.
Thank you in advance.
Hi.
Choose channels 0 and 3, for example.
Those are not grouped.
To know which ones are grouped, you have to test them. I remember that those two are independent.
Regards,
Sara
Thank you very much for your answer!
I haven’t an oscilloscope. Is there a simple way to test it without an oscilloscope?
Thank you again!
I will try to connect piezo element with audible frequency and then post the results
Thanks a lot
I connected a piezo element to ground and alternating to GPIOs 16 and 17.
I can hear the same frequence using with channels 0 1 or 2 3. Frequence is different with 0 2, 0 3, 1 3.
I think it could be a good test if you can’t use an oscilloscope.
I uploaded this sketch:
const int ledPin0 = 16;
const int ledPin1 = 17;
const int freq0 = 500;
const int freq1 = 100;
const int ledChannel0 = 1; const int ledChannel1 = 3; //OK
//const int ledChannel0 = 3; const int ledChannel1 = 3; //OK
//const int ledChannel0 = 0; const int ledChannel1 = 3; //OK
// const int ledChannel0 = 0; const int ledChannel1 = 1; //NO it sounds the same frequence
// const int ledChannel0 = 2; const int ledChannel1 = 3; //NO it sounds the same frequence
const int resolution = 8; // dutycycle 128 is 50%
void setup(){
ledcSetup(ledChannel0, freq0, resolution);
ledcSetup(ledChannel1, freq1, resolution);
ledcAttachPin(ledPin0, ledChannel0);
ledcAttachPin(ledPin1, ledChannel1);
} //fine set up
void loop(){
ledcWrite(ledChannel0, 128);
ledcWrite(ledChannel1, 128);
} // fine void loop
hi:
the functions used to control the PWM on the LEDs were unfamiliar for me, but that makes me wonder how I know how many or where I can find all the functions that ESP32 can handle, by any chance do you know where?
Thank you in advance.
https://github.com/espressif/arduino-esp32
Hi Sara:
thanks for the link, I wonder if there is a link very similar to the arduino page where it tells you in the language reference what functions are available to use when you are programming the arduino board. Is there something similar?
thank you.
Hi Sara.
Do you have an example of used millis instead of delay for ESP32 PWM with Arduino IDE (Analog Output)?
Thanks
Summer
Hi Sara.
do you have example to vary the frequency of PWM?
Thanks
Summer
I think the tutorial is very confusing because it glosses over the fact that pairs of PWM channels use the same timer and therefore must use the same frequency. e.g Channel pairs (0,1) (2,3) (4,5) (6,7) must have the same frequency.
I also don’t see how the clock source is selected. Does Arduino have some algorithm for doing this automatically ? Is the source fixed ?
Hi,
I see this is an old tutorial, but have you tried the new ESP32-C3 processors yet?
It seems Arduino doesn’t like the ledcSetup command for the C3 variety – using the 2.0.14 board manager from espressif.
Any thoughts? I can’t get the simple code to compile because:
error: ‘ledcSetup’ was not declared in this scope
ledcSetup(PWM_CHANNEL1, PWM_FREQ1, PWM_RESOLUTION1);
…
exit status 1
‘ledcSetup’ was not declared in this scope
any thoughts would be appreciated
i have got the same problem. Do you know a solution?
Hi.
If you update the ESP32 boards to version 3.0, there are a few changes required to make the code compile. We’ll be updating all our guides in the upcoming weeks.
Here’s the required changes for PWM:
Previously for version 2 ESP32 board add-on inside the setup function:
pinMode(LED_PIN, OUTPUT);
// configure LED PWM functionalities
ledcSetup(ledChannel, freq, resolution);
// attach the channel to the GPIO to be controlled
ledcAttachPin(LED_PIN, ledChannel);
ledcWrite(ledChannel, 0);
For the NEW version 3 ESP32 board add-on inside the setup function:
ledcAttachChannel(LED_PIN , freq, resolution, ledChannel);
ledcWrite(LED_PIN, 0);
I hope this helps.
Regards,
Sara
It seems the latest board managers use an updated set of APIs. I had some demos running that used ledcSetup etc. I replaced
ledcAttachPin(LED2, LED2PWMCHANNEL);
ledcSetup(LED2PWMCHANNEL, 4000, 8);
with
ledcAttach(LED2, 4000, 8);
This automatically finds an open PWM channel and uses it. There is a variant that allows you to select a particular channel; useful in more complex configurations, I imagine.
Also, analogWrite can be called directly now. I replaced
ledcWrite(LED2PWMCHANNEL, theMessage.ledLevel);
with
analogWrite(LED2, theMessage.ledLevel);
Note: I cut-pasted the code directly from a running program. The two constants (LED2, LED2PWMCHANNEL) were defined earlier in the program.
Steve
Quick followup: I’m using the esp32 board manager, version 3.0. The documentation I used to update my apps is located here: espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/ledc.html
Steve
Hi:
my esp32 dev kit v1 have 30pins, from pinout diagram it supports 22 pins with PWM, is that means 16 PWM channel not only support 16 pins output with PWM?
I don’t think anyone above has mentioned it, but it’s worth pointing out that if you use ledcAttachChannel(pin, frequency, resolution, channel); followed by ledcWrite(pin,dutycycle); then you will need to put a delay() statement in between with a value equal to or greater than the period of the PWM frequency. For example:-
ledcAttachChannel(pwmout, 10000, 8, 0);
delayMicroseconds(100);
ledcWrite(pwmout, 127);
Thanks for your feedback.
Regards,
Sara
From my point of view, with the “new” ESP-IDF 3.0.x, there is something missing in the documentation:
I used the LEDC to control one LED with higher current connected to 3 ESP outputs in parallel. All 3 pins related to one channel. With the old command from ESP-IDF 2.x “ledcWrite(LEDchan, ledBrightness);” all outputs of the channel operated synchronized acc. to the spec. .
In the original ESP docs for the ESP-IDF 3.0.x as well as in your updated article I’m missing a write command for a specific channel. The documented write command is related only to a specific pin. I hope, writing to a channel is not obsolete now.
Hi.
I’m afraid that is obsolete now and it was removed from the documentation.
Regards,
Sara
Hi Sara,
good news! I recently opened an issue (#10010) for the ESP32-Arduino-Core on github regarding this. And ist is already solved and closed. The function was obviously removed by accident.
rgds purehunter
Thanks for letting me know.
Regards,
Sara
Hey!
AnalogWrite did not work for me.
The other option did work though..
Why is that? 🙁
Thanks!
Follow up comment to the one above:
Im using PlatformIO with and ESP32 DevKitC with WROOM32U
the board is from ali express and is a copy of the ESP32-DevKitC V4.
I picked az-delivery-devkit-v4 on platformIO as it was the closest thing.
Also im a total noobie and this is my first code ever in this field of interest.
Thanks!
I prefer not to compete, and I love open source. I am making a solar charge controller. The user interface is via a webpage, hosted on an esp32 in the softAP mode for offline use. I have assembled buck converters that come inexpensively on aliexpress. Each buck converter can handle up to 40 watts, and input voltages up to 60v. Each panel gets 8 of these mini buck converters and its own esp32 with current sensing and voltage sensing to charge the battery module safely. If you want to publish it on you site after I am done, I’d be happy to contribute to your wonderful repository of esp projects. In the end, I will have the basis for a nice diy charge controller.
Hi Sara,
Thanks for this code works fine in my ESP 32 Dev Module. However I tried using the code in an RGB using “ledcAttachChannel(ledPin, freq, resolution, 0);” controlled by a PS3 controller. However compiler does’nt agree with it, getting an error message below,
C:\Users\Admin\Documents\Arduino\sketch_nov23b_PS3Controller_RGB\sketch_nov23b_PS3Controller_RGB.ino: In function ‘void setup()’:
C:\Users\Admin\Documents\Arduino\sketch_nov23b_PS3Controller_RGB\sketch_nov23b_PS3Controller_RGB.ino:98:20: error: too few arguments to function ‘bool ledcAttachChannel(uint8_t, uint32_t, uint8_t, uint8_t)’
98 | ledcAttachChannel(redChannel, ledFreq, ledResolution);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:\Users\Admin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/esp32-hal.h:81,
from C:\Users\Admin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/Arduino.h:36,
from C:\Users\Admin\AppData\Local\Temp\arduino\sketches\8477042612A4719C5780DF660271FDF4\sketch\sketch_nov23b_PS3Controller_RGB.ino.cpp:1:
C:\Users\Admin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/esp32-hal-ledc.h:99:6: note: declared here
99 | bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel);
| ^~~~~~~~~~~~~~~~~
C:\Users\Admin\Documents\Arduino\sketch_nov23b_PS3Controller_RGB\sketch_nov23b_PS3Controller_RGB.ino:99:20: error: too few arguments to function ‘bool ledcAttachChannel(uint8_t, uint32_t, uint8_t, uint8_t)’
99 | ledcAttachChannel(greenChannel, ledFreq, ledResolution);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\Admin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/esp32-hal-ledc.h:99:6: note: declared here
99 | bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel);
| ^~~~~~~~~~~~~~~~~
C:\Users\Admin\Documents\Arduino\sketch_nov23b_PS3Controller_RGB\sketch_nov23b_PS3Controller_RGB.ino:100:20: error: too few arguments to function ‘bool ledcAttachChannel(uint8_t, uint32_t, uint8_t, uint8_t)’
100 | ledcAttachChannel(blueChannel, ledFreq, ledResolution);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\Admin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\3.0.7\cores\esp32/esp32-hal-ledc.h:99:6: note: declared here
99 | bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel);
| ^~~~~~~~~~~~~~~~~
C:\Users\Admin\Documents\Arduino\sketch_nov23b_PS3Controller_RGB\sketch_nov23b_PS3Controller_RGB.ino:104:3: error: ‘ledcAttachpin’ was not declared in this scope; did you mean ‘ledcAttach’?
104 | ledcAttachpin(ledRed, redChannel);
| ^~~~~~~~~~~~~
| ledcAttach
exit status 1
Compilation error: too few arguments to function ‘bool ledcAttachChannel(uint8_t, uint32_t, uint8_t, uint8_t)’
I’m just learning these ESP32 because I have a project using a PS3 controller via bluetooth to control an RC car. Currently I’m just using PS3 controller to turn on/off led lights and its working. However I’m still trying to find out how I can get a code to control an rc car using PS3 controller and ESP32.
I have been successfull using a phone app and a web page controlling an rc car.
However incorporating a PS3 controller and ESP32 to control an RC car(using L298N motor driver for the dc motor wheels) is tough currently.
I hope you can help me.
Thanks
Rick
Hi.
Please update your ESP32 boards installation to version 3.
The PWM methods have changed. You must still be running ESP32 version 2.
Let me know if you can solve the issue.
Regards,
Sara
Hi Sara,
Thanks for a quick response. I just want to clarify the ESP32 boards you said I’m using version 2. How do I update to version 3. Currently my ESP32 boards on my library installed is Arduino ESP32 Boards 2.0.18 and ESP32 by Expressif Systems is version 3.07 both installed.
Where do I get the version 3 of ESP32 boards you’re suggesting. Sorry I’m just new to this libraries.
I got this information from my Arduino IDE by typing on my boards manager ESP32 and it populates my boards to 3 boards. Two I mentioned above and the 3rd one is esp32_bluepad32 by Ricardo Quesada.
Thanks
Rick
Hi.
It seems you already have the latest version.
Uninstall the Arduino ESP32 Boards 2.0.18 and the one by Ricardo Quesada. You only need the one by expressif.
Additionally, make sure that you have an ESP32 board selected in Tools > Board when trying to compile an ESP32 code.
Regards,
Sara
Hi Sara,
Thanks for a quick response. I followed your suggestion and it worked no compiling or issues whatsoever.
Now my project is incorporating the PS3 controller to this Tutorial.
Thanks again
Rick
That’s great.
I’m glad it’s working now.
Regards,
Sara