PWM with Arduino and ESP32

analogWrite

for Arduino
Syntax

analogWrite(pin, value)

Parameters
pin: the Arduino pin to write to. Allowed data types: int.
value: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types: int.

TONE

For Arduino
Generates a square wave of the specified frequency (and 50% duty cycle) on a pin. A duration can be specified, otherwise the wave continues until a call to noTone(). The pin can be connected to a piezo buzzer or other speaker to play tones.

tone(pin, frequency)
tone(pin, frequency, duration)
noTone(pin)

LEDC

The ESP32 has a LED PWM controller with 16 independent channels that can be configured to generate PWM signals with different properties.

Here’s the steps you’ll have to follow to dim an LED with PWM using the Arduino IDE:

1. First, you need to choose a PWM channel. There are 16 channels from 0 to 15.

2. Then, you need to set the PWM signal frequency. For an LED, a frequency of 5000 Hz is fine to use.

3. You also need to set the signal’s duty cycle resolution: you have resolutions from 1 to 16 bits.  We’ll use 8-bit resolution, which means you can control the LED brightness using a value from 0 to 255.

4. Next, you need to specify to which GPIO or GPIOs the signal will appear upon. For that you’ll use the following function:

ledcAttachPin(GPIO, channel)

This function accepts two arguments. The first is the GPIO that will output the signal, and the second is the channel that will generate the signal.

5. Finally, to control the LED brightness using PWM, you use the following function:

ledcWrite(channel, dutycycle)

This function accepts as arguments the channel that is generating the PWM signal, and the duty cycle.

// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
 
void setup(){
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledChannel);
}
 
void loop(){
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);
    delay(15);
  }

  // decrease the LED brightness
  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
    ledcWrite(ledChannel, dutyCycle);   
    delay(15);
  }
}

 to set the frequency again, we call the ledcWriteTone function, passing as inputs the PWM channel and the frequency to set. We will set it to 2000 Hz, as the initial configuration.

ledcWriteTone(channel, 2000);