ESP32/ESP8266 PWM with MicroPython – Dim
LED
This tutorial shows how to generate PWM signals with the ESP32 and ESP8266
boards using MicroPython firmware. As an example, we’ll dim the brightness of
an LED by changing the duty cycle over time.
Prerequisites
To follow this tutorial you need to have MicroPython firmware installed in your
ESP32 or ESP8266 boards. You also need an IDE to write and upload the code
to your board. We suggest using Thonny IDE or uPyCraft IDE:
Thonny IDE:
Installing and getting started with Thonny IDE
Flashing MicroPython Firmware with esptool.py
uPyCraft IDE:
Install uPyCraft IDE (Windows, Mac OS X, Linux)
Flash/Upload MicroPython Firmware to ESP32 and ESP8266
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Schematic
For this example, wire an LED to your ESP board. We’ll wire the LED to
GPIO 5 in both boards, but you can choose another suitable PWM pin. See the
best pins to use in our ESP32 Pinout Reference Guide.
Parts required
Here’s a list of the parts you need to build the circuit:
ESP32 or ESP8266 (read: ESP32 vs ESP8266)
5mm LED
330 Ohm resistor
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!
Schematic – ESP32
Follow the next schematic diagram if you’re using an ESP32 board:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Schematic – ESP8266
Follow the next schematic diagram if you’re using an ESP8266 board:
Script
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Here’s the script that changes the LED brightness over time by increasing the
duty cycle. This script works with the ESP32 and ESP8266.
# Complete project details at https://RandomNerdTutorials.
from machine import Pin, PWM
from time import sleep
frequency = 5000
led = PWM(Pin(5), frequency)
while True:
for duty_cycle in range(0, 1024):
led.duty(duty_cycle)
sleep(0.005)
View raw code
How the code works
To create a PWM pin, import the PWM class in addition to the Pin class from
the machine module.
from machine import Pin, PWM
Then, create a PWM object called led .
led = PWM(Pin(5), frequency)
To create a PWM object, you need to pass as parameters, the pin it is connected
to, the signal frequency and the duty cycle.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Frequency: The frequency can be a value between 0 and 78125. A
frequency of 5000 Hz can be used to control the LED brightness.
Duty cycle: The duty cycle can be a value between 0 and 1023. In which
1023 corresponds to 100% duty cycle (full brightness), and 0 corresponds
to 0% duty cycle (unlit LED).
We’ll just set the duty cycle on the while loop, so we don’t need to pass the
duty cycle parameter. If you don’t set the duty cycle when instantiating the PWM
object, it will be 0 by default.
To set the duty cycle use the duty() method on the PWM object and pass the
duty cycle as an argument:
led.duty(duty_cycle)
Inside the while loop, we create a for loop that increases the duty cycle by
1 in each loop with an interval of 5 ms between each change.
for duty_cycle in range(0, 1024):
led.duty(duty_cycle)
sleep(0.005)
The range() function has the following syntax:
range(start, stop, step)
Start: a number that specifies at which position to start. We want to start
with 0 duty cycle;
Stop: a number that specifies at which position we want to stop,
excluding that value. The maximum duty cycle is 1023, because we are
incrementing 1 in each loop, the last value should be 1023+1. So, we’ll
use 1024.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Step: an integer number that specifies the incrementation. By default,
incrementation is 1.
In each for loop, we set the LED’s duty cycle to the current duty_cycle value:
led.duty(duty_cycle)
After that, the duty_cycle variable is incremented by 1.
Demonstration
Save the code to your ESP board using Thonny IDE or uPyCraft IDE. The LED
attached to GPIO 5 should increase brightness over time.
Wrapping Up
We hope you’ve found this MicroPython tutorial useful. If you want to learn more
about MicroPython, make sure you take a look at our eBook: MicroPython
Programming with ESP32 and ESP8266.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
If you like MicroPython, you may also like:
ESP32/ESP8266 GPIOs Explained with MicroPython
ESP32/ESP8266 Digital Inputs and Digital Outputs with MicroPython
ESP32/ESP8266 Analog Readings with MicroPython
ESP32/ESP8266 MicroPython Web Server – Control Outputs
Thanks for reading.
SMART HOME with
Raspberry Pi, ESP32,
ESP8266 [eBook]
Recommended Resources
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Build a Home Automation System from Scratch » With Raspberry Pi,
ESP8266, Arduino, and Node-RED.
Home Automation using ESP8266 eBook and video course » Build IoT
and home automation projects.
Arduino Step-by-Step Projects » Build 25 Arduino projects with our course,
even with no prior experience!
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
What to Read Next…
ESP32 Deep Sleep with Arduino IDE and Wake Up Sources
ESP32/ESP8266: Firebase Web App to Display Sensor Readings (with
Authentication)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
ESP8266 Web Server with Arduino IDE
Enjoyed this project? Stay updated by subscribing our
newsletter!
6 thoughts on “ESP32/ESP8266 PWM with
MicroPython – Dim LED”
Dušan
December 16, 2020 at 9:05 pm
Hello, I have some trouble with multiple PWM frequencies:
from machine import PWM, Pin
ledR = PWM(Pin(13), freq = 5000, duty = 200)
ledY = PWM(Pin(12), freq = 5000, duty = 200)
ledG = PWM(Pin(14), freq = 5000, duty = 200)
ledB = PWM(Pin(2), freq = 5, duty = 50)
Last line is setting frequency for all the LEDs. It seems like they share
the same frequency. Is there a way to solve it?
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Reply
Sara Santos
December 17, 2020 at 11:14 am
Hi.
Can you try using different GPIOs?
Regards,
Sara
Reply
Dušan
December 18, 2020 at 2:39 pm
I have tested completely all GPIOs. It seems like MicroPython (my
version esp32-idf4-20200902-v1.13.bin) on ESP32 is using just 8
PWM channels (on 9th says: “out of PWM channels”), but sharing just
one timer for all of them. Or maybe I am doing something wrong? You
can try this:
from machine import Pin, PWM
from time import sleep
def TestPWM(pins):
pwm = []
print(“Setting PWM:”)
for pin in pins:
print(“*”, pin, end = “: “)
pwm.append(PWM(Pin(pin), freq = pin, duty = 500 + pin))
sleep(0.5)
print(pwm[-1])
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
print("After that:")
for p in pwm:
print("*", p)
print("Frequencies:")
for i in range(len(pwm)):
pwm[i].freq(10 + i)
print("* setting one to", 10 + i, end = ": ")
for p in pwm:
print(p.freq(), end = " ")
print()
for p in pwm:
p.deinit()
TestPWM((2, 3, 4, 5, 12, 13, 14, 15))
TestPWM((14, 15, 16, 17, 18, 19, 21, 22))
TestPWM((21, 22, 23, 25, 26, 27, 32, 33))
print(“OK”)
Reply
Dušan
December 18, 2020 at 10:44 pm
Now I have tested different versions of MicroPython (1.9, 1.13 IDF3)
and also ESP8266 – it is all the same. :-/ It means that I have to use
machine.Timer() with 4 channels available and create my own pwm
class?
For higher frequencies it is also possible to use 8× RMTs on ESP32,
but it is not so easy to set precise frequency. We may use it for
LEDs:
import esp32
from machine import Pin, PWM
ledR = esp32.RMT(0, pin = Pin(13))
ledR.loop(True)
ledY = esp32.RMT(1, pin = Pin(12))
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
ledY.loop(True)
ledG = esp32.RMT(2, pin = Pin(14))
ledG.loop(True)
duties:
ledR.write_pulses((50, 50)) # 50:50 = 50 %
ledY.write_pulses((10, 90)) # 10:90 = 10 %
ledG.write_pulses((100, 0)) # 100:0 = 100 %
ledB = PWM(Pin(2), freq = 5, duty = 50)
In fact those write_pulses values are number of clock ticks (by
default 100 ns) for output value 1 and 0.
Lowest possible frequency is cca 5 Hz:
* maximum value for write_pulses is 32767
* source clock frequency is 80 MHz
* maximum frequency divider is 255 => minimal clock frequency 314
kHz
=> one pulse time is 0.1 s at most
=> whole 1:1 period is 0.2 s = 5 Hz
Reply
Sara Santos
December 19, 2020 at 12:03 pm
Hi.
It seems that different frequencies are not supported in
MicroPython. Read this:
https://github.com/micropython/micropython/blob/0fff2e03fe074719
97a6df6f92c6960cfd225dc0/docs/esp8266/quickref.rst#pwm-pulse-
width-modulation
And this: https://github.com/micropython/micropython/pull/3608
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Regards,
Sara
gou ru vernooij
October 15, 2021 at 12:33 pm
beste random nerd tutorials,
ik ben erg telurgestelt in de informatie die op uw website staat, alhoewel
vindt ik het erg fijn hoe de codering mooi in reitjes staat. ik zou het fijn
vinden als er ook met braiietaal gewerkt kan worden zodat blinde
mensen de code’s ook kunnen overtypen. bij deze ben ik berijd 50 cent
te investeeren zodat de site kan verbeteren en braiie taal invoegen.
met geachte groet.
gou ru vernooij
Reply
DO NOT SELL OR SHARE MY INFORMATION
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF