all 36 of ESP32 GPIOs has a PWM capability, what is great! Only we must use more complex code to reach the same result.
So, let's program one of that GPIOs with a PWM output signal.
The first thing to think about a PWM signal to be generated is its frequency. We will use a value of 5000 Hz, that works fine with the LED. We must also specify the LED PWM channel and the resolution of the PWM duty cycle, in bits. We can choose a channel from 0 to 15 and a resolution between 1 and 16 bits. We will use channel 0 and a resolution of 8 bits.
int freq = 5000; int ledChannel = 0; int resolution = 8;
Let's use GPIO2, where we have our external LED attached (and the internal one).
#define LED_PIN 2
The ESP32 does not support the analogWrite() function. But it does support a much better one, the ledcWrite() function.
The ledcWrite() is very similar to analogWrite(). It also requires two parameters:
The PWM channel that we want to “write” a value to.
The PWM value we want to write to the selected channel.
This simple function shows off the power of the ESP32. Both the channel and the PWM values are configurable.
Those parameters must be defined during setup() phase, using below functions:
void setup()
{
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(LED_PIN, ledChannel);
}
To turn on the LED with a specific brightness, we must define the "duty cycle".
For example, to turn off the LED, the duty cycle must be zero and the function ledcWrite(ledChannel, dutyCycle) used to send the value thru a specific PWM channel:
int dutyCycle = 0; ledcWrite(ledChannel, dutyCycle);
Different values of the dutyCycle variable will turn on the LED with different brightness. this variable, dutyCycle, will vary from 0 to 255, once the resolution used is 8 bits.
We can use the Potentiometer (connected to analog_value variable) to manually setup the dutyCycle variable, but once their range of values are different, let's use a map function to match input and output:
dutyCycle = map(analog_value, 0, 4095, 0, 255);
Below the complete code:
*****************************************************
* ESP32 Analog Input/Output Test
* Analog Input: ADC_1_0 pin ==> GPIO36 (VP).
* PWM LED pin ==> GPIO 02
*
* MJRoBot.org 6Sept17
*****************************************************/
//Analog Input
#define ANALOG_PIN_0 36
int analog_value = 0;
// PMW LED
#define LED_PIN 2
int freq = 5000;
int ledChannel = 0;
int resolution = 8;
int dutyCycle = 0;
void setup()
{
Serial.begin(115200);
delay(1000); // give me time to bring up serial monitor
Serial.println("ESP32 Analog IN/OUT Test");
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(LED_PIN, ledChannel);
ledcWrite(ledChannel, dutyCycle);
}
void loop()
{
analog_value = analogRead(ANALOG_PIN_0);
Serial.println(analog_value);
dutyCycle = map(analog_value, 0, 4095, 0, 255);
ledcWrite(ledChannel, dutyCycle);
delay(500);
}