Raspberry Pi Pico
Adjusting LED Brightness (PWM)

So far, we have contented ourselves with simply turning our LED on or off. If we want to vary the brightness of the LED or fade it on and off, we need to be able to do more. Digital signals are, by definition, a question of on and off. If we simply send a high or low signal once every half a second, we are seeing only two states on our LED. To see more than that we need to send an analogue signal.

Pulse Width Modulation (PWM) is a technique used in electronics to simulate an analogue output. Instead of having a consistent high or low signal with our GPIO pin, the pin is switched from high to low repeatedly.

When setting up PWM, we choose the frequency. This determines how frequently the pin is switched between on and off. We also choose the duty cycle. This determines the proportion of the time that the pin is set to high.

I used the following circuit to test this out. There is an LED connected to GP13, with a 330 ohm resistor connecting its cathode to GND.

Pico Circuit

The following program varies the duty cycle using for loops to fade the LED in and out.

from machine import Pin, PWM
from time import sleep

pwm_led = PWM(Pin(13))

pwm_led.freq(500)

while True:
    for i in range(65535):
        pwm_led.duty_u16(i)
        sleep(0.0001)
    for i in range(65535, 0, -1):
        pwm_led.duty_u16(i)
        sleep(0.0001)  

Varying the frequency and the duty cycle will have an effect on the circuit. A little bit of experimentation, changing these in the program, will give you a better sense of what that effect is.

The Raspberry Pi Pico is capable of driving any of its GPIO pins using PWM. There are some limitations though. The PWM block has 8 identical slices. Each slice can drive two output PWM signals. That gives you a total of 16 PWM outputs.

The following table gives you the details of how those channels and slices correspond to the GPIO pins. Just make sure that your circuits use different slices and channels for no more than 16 PWM signals.

SliceGPIO
PWM0 AGP0, GP16
PWM0 BGP1, GP17
PWM1 AGP2, GP18
PWM1 BGP3, GP19
PWM2 AGP4, GP20
PWM2 BGP5, GP21
PWM3 AGP6, GP22
PWM3 BGP7
PWM4 AGP8
PWM4 BGP9, GP25
PWM5 AGP10, GP26
PWM5 BGP11, GP27
PWM6 AGP12, GP28
PWM6 BGP13
PWM7 AGP14
PWM7 BGP15