8.PWM(Pulse Width Modulation)

1. The introduction of PWM function on BiBoard (ESP32)

The ESP32 used by BiBoard is different from the 328P used by UNO. Because the PWM of ESP32 uses the matrix bus, it can be used on unspecified pins.

The PWM of ESP32 is called LED controller (LEDC). The LED PWM controller is mainly used to control LEDs, and it can also generate PWM signals for the control of other devices. The controller has 8 timers, corresponding to 8 high-speed channels and 8 low-speed channels, totaling 16 channels.

Compared with UNO, directly use "analogWrite()" to input any duty ratio between 0-255. The PWM control of ESP32 on BiBoard is more troublesome. The parameters that need to be controlled are as follows:

  1. Manual selection of PWM channels (0-15) also improves the flexibility of the use of pins

  2. The number of bits of the PWM waveform determines the resolution of the duty cycle of the PWM waveform. The higher the number of bits, the higher the accuracy.

  3. The frequency of the PWM waveform determines the speed of the PWM waveform, the higher the frequency, the faster the speed.

The frequency of the PWM waveform and the number of bits are relative, the higher the number of bits, the lower the frequency. The following example is quoted from the ESP32 programming manual:

For example, when the PWM frequency is 5 kHz, the maximum duty cycle resolution can be 13 bits. This means that the duty cycle can be any value between 0 and 100%, with a resolution of ~0.012% (2 ** 13 = 8192 discrete levels of LED brightness).

The LED PWM controller can be used to generate high-frequency signals, enough to clock other devices such as digital camera modules. Here the maximum frequency can be 40 MHz, and the duty cycle resolution is 1 bit. In other words, the duty cycle is fixed at 50% and cannot be adjusted.

The LED PWM controller API can report an error when the set frequency and duty cycle resolution exceed the hardware range of the LED PWM controller. For example, if you try to set the frequency to 20 MHz and the duty cycle resolution to 3 bits, an error will be reported on the serial port monitor.

2. Configure the PWM frequency on BiBoard in Arduinoin Arduino

As shown above, we need to configure the channel, frequency and number of bits, and select the output pin.

Step 1: Configure the PWM controller

const int freq = 5000; // PWM frequency
const int ledcChannel = 0; // ledc channel, 0-15
const int resolution = 8; // resolution of PWM,8bit(0~255)
ledcSetup(ledcChannel, freq, resolution);

Step 2: Configure the PWM output pins

ledcAttachPin(ledPin, ledcChannel);

Step 3: Output PWM waveform

ledcWrite(ledcChannel, dutyCycle);

In the demo, we choose IO2 as the output pin, connect IO2 to an LED, and you can observe the effect of the LED breathing light.

3. Complete code:

/* In this demo, we show how to use PWM in BiBoard(ESP32)
* It's different from the Arduino UNO based on the ATMega328P
*/

// define the PWM pin
const int ledPin = 2;  // 16 corresponds to GPIO16

// setting PWM properties
const int freq = 5000;          // PWM frequency
const int ledcChannel = 0;      // ledc channel, in ESP32 there're 16 ledc(PWM) channels
const int resolution = 8;       // resolution of PWM
 
void setup(){
  // configure ledc functionalitites
  // channels 0-15, resolution 1-16 bits, freq limits depend on resolution
  // ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits);
  ledcSetup(ledcChannel, freq, resolution);     
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledcChannel);
}
 
void loop(){
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    // changing the LED brightness with PWM
    ledcWrite(ledcChannel, dutyCycle);
    delay(15);
  }

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

Last updated