Pulse Width Modulation (PWM) is a widely used technique for power delivery. ESP32 has dedicated hardware for PWM. Pulse-width modulation (PWM) of a signal or power source is a technique in which the duty cycle of a periodic signal (a sinusoidal or a square signal, for example) is modified. The duty cycle of a periodic signal is the relative width of its positive part relative to the period.
The typical construction of a PWM circuit is carried out using a comparator with two inputs and one output. One of the inputs is connected to a sawtooth wave oscillator, while the other is available for the modulating signal. At the output, the frequency is usually equal to that of the sawtooth signal and the duty cycle is a function of the carrier. The main disadvantage of PWM circuits is the possibility of radio frequency interference. These can be minimized by placing the controller close to the load and filtering the power supply.
ESP32’s PWM can drive LEDs, motors (normal DC Motors, Brushless Motors), smart lights and so on. A typical PWM signal has PWM Frequency, PWM Resolution, and PWM Duty Cycle. If we alter the PWM’s duty cycle parameter, then the width of the pulse will also change. Resolution is a measurement to make us understand how many discrete levels of duty cycle we can control. PWM resolution = log2(Number of Levels). The higher the resolution will be, the finer it will be to control the duty cycle.
---
Documentations from Espressif can be found here :
1 | https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/mcpwm.html |
In Arduino we use the analogWrite()
function to achieve PWM. But Analog Write function is not yet implemented in ESP32 Arduino version. Instead a new Function called ledcWrite()
is introduced. Attach a LED with Pin 5 and test with this code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #define LED_GPIO 5 #define PWM1_Ch 0 #define PWM1_Res 8 #define PWM1_Freq 1000 int PWM1_DutyCycle = 0; void setup() { ledcAttachPin(LED_GPIO, PWM1_Ch); ledcSetup(PWM1_Ch, PWM1_Freq, PWM1_Res); } void loop() { while(PWM1_DutyCycle < 255) { ledcWrite(PWM1_Ch, PWM1_DutyCycle++); delay(10); } while(PWM1_DutyCycle > 0) { ledcWrite(PWM1_Ch, PWM1_DutyCycle--); delay(10); } } |
This is a test code for servo motor with a potentiometer :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <ESP32Servo.h> Servo servo1; // create a servo object #define potWiper 36 #define servoPin 19 #define twoTo12th 4095 #define delay1 150 int intValue; void setup() { servo1.attach(servoPin); // attach the servo to servoPin Serial.begin(9600); // setup display monitor (work at 9600 baud) } void loop() { intValue = analogRead(potWiper); // read value at pin potWiper pin intValue = map(intValue, 0, twoTo12th, 0, 180); // convert value read to value from 0 to 180 servo1.write(intValue); // move the servo to position intValue Serial.print("Servo Angle = "); // display the Serial.println(intValue); // servo angle on display monitor delay(delay1); // allow the servo time to get to position } |
This is an extremely short snippet/sketch which you can use for the DC motors and pot :
1 2 3 4 5 6 7 8 9 10 | const byte led_pin = 15; const byte pot_pin = 4; void setup() { ledcAttachPin (led_pin,0); ledcSetup(0,5000,8); // channel 0, pwm freq 5 khz, Resolution 8 bits } void loop() { ledcWrite(0,analogRead(pot_pin); } |
An L293 board/module can control 2 DC motors & it sources 500ma current. For control of each motor 2 sets of control, pins are provided. You can use this module with the above code to build a basic robotic car.
Tagged With esp32 arduino output pwm pulse , pwm in esp32