Raspberry Pi Pico: Fading an LED using PWM (Arduino IDE)

Learn how to generate PWM signals with the Raspberry Pi Pico using Arduino IDE. As an example, we’ll show you how to dim the brightness of an LED by changing the duty cycle over time.

Raspberry Pi Pico Fading an LED using PWM with Arduino IDE

We have a similar guide using MicroPython firmware: Raspberry Pi Pico: PWM Fading an LED (MicroPython).

Table of Contents

Prerequisites

You need to install the Raspberry Pi Pico boards on Arduino IDE and you must know how to upload code to the board. Check out the following tutorial first if you haven’t already:

Introducing PWM (Pulse-Width Modulation)

PWM, or Pulse Width Modulation, is a technique that controls the power delivered to devices. It achieves this by turning the power on and off very quickly.

For example, if you alternate an LED’s voltage between HIGH and LOW very fast, your eyes can’t keep up with the speed at which the LED switches on and off; you’ll simply see some gradations in brightness.

Fading LED

That’s basically how PWM works — by producing an output that changes between HIGH and LOW at a very high frequency.

The duty cycle refers to the percentage of time the power is on compared to the total time of the on-off cycle—take a look at the following diagram.

How PWM works

By adjusting the duty cycle, we can control the average power delivered to the device. For instance, a higher duty cycle means the device receives more power, while a lower duty cycle results in less power. This enables us to control things like brightness in LEDs, speed in motors, or volume in speakers.

For example, a duty cycle of 50 percent results in 50 percent LED brightness, a duty cycle of 0 means the LED is fully off, and a duty cycle of 100 means the LED is fully on. Changing the duty cycle is how you produce different levels of brightness.

Raspberry Pi Pico GPIOs

The Raspberry Pi Pico comes with 40 pins, 26 of which are programmable GPIOs that you can use to connect peripherals. All Raspberry Pi Pico GPIOs can output PWM signals—they are marked in the diagrams in light green color.

You can use the following pinouts as a reference to identify and locate each GPIO on your board. The pinout is slightly different for the Pico and Pico W.

The following picture shows the Raspberry Pi Pico pinout (which functions are supported by each pin).

Raspberry Pi Pico Pinout
Image source: raspberrypi.com
Raspberry Pi Pico W pinout

The pins marked in red are power pins that output 3.3V. The black pins are GND pins. All pins in light green can be used as “regular” GPIOs (input and output).

To learn more about the Pico Pinout, read the following guide: Raspberry Pi Pico and Pico W Pinout Guide: GPIOs Explained.

Raspberry Pi Pico – PWM Channels

The Raspberry Pi Pico has 8 independent PWM generators called slices. Each slice has two channels, which makes a total of 16 PWM channels.

The frequency of the PWM signal can range between 8Hz and 62.5MHz, while the microcontroller is running at a frequency of 125MHz.

Two channels of the same slice run at the same frequency, but can have a different duty rate. 

analogWrite() and Other Functions

When it comes to generating PWM signals on the Raspberry Pi Pico in an easy way using Arduino C/C++, you can use the following functions:

  • analogWriteFreq(uint32_t frequency) to set the frequency of the PWM signal. It supports a frequency of 100Hz to 1MHz*.
  • analogWriteRange(uint32_t range) to set the range of the PWM signal — the maximum value you’ll use to set 100% duty cycle. It supports a value from 16 to 65535.
  • analogWriteResolution (int resolution) to set the resolution of the PWM signal — up to 16-bit.
  • analogWrite(GPIO, duty cycle) to output a PWM signal to a specified pin with a defined duty cycle. It continuously outputs a PWM signal until a digitalWrite() or other digital output is performed.

* there are some restrictions to the combination of frequency and ranges. According to the documentation: “The PWM generator source clock restricts the legal combinations of frequency and ranges. For example, at 1MHz only about 6 bits of range are possible. When you define an analogWriteFreq and analogWriteRange that can’t be fulfilled by the hardware, the frequency will be preserved but the accuracy (range) will be reduced automatically. Your code will still send in the range you specify, but the core itself will transparently map it into the allowable PWM range“.

Wiring the Circuit

Now, let’s create an example to better understand those PWM concepts. We’ll create a simple example to dim an LED (increase and decrease brightness smoothly).

Before proceeding, connect an LED to the Raspberry Pi Pico. We’re connecting to GPIO 20, but you can use any other GPIO.

Parts Required

Raspberry Pi Pico LED PWM

Here’s a list of the parts you need to build the circuit:

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 – Raspberry Pi Pico

You can use the following diagram as a reference to connect the LED to the Raspberry Pi Pico board.

Raspberry Pi Pico LED connected to GPIO 20 diagram

RPi Pico Fading an LED – Arduino Sketch

The following code creates a PWM signal on GPIO 20 and increases and decreases the duty cycle over time to dim the LED.

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-pwm-analogwrite-arduino/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/

// Pin connected to the LED
const int ledPin = 20;

// Time interval between brightness steps (in milliseconds)
const int fadeInterval = 10;

// Maximum and minimum brightness values
const int maxBrightness = 255;
const int minBrightness = 0;

// Current brightness value
int brightness = minBrightness;

// Direction flag for fading (true = increasing, false = decreasing)
bool fadingDirection = true;

void setup() {
  // Initialize the LED pin as an output
  pinMode(ledPin, OUTPUT);
  // Adjust PWM properties if needed
  /*analogWriteFreq(5000);
  analogWriteRange(65535);
  analogWriteResolution(16);*/
}

void loop() {
  // Update the brightness value based on the fading direction
  if (fadingDirection) {
    for (int i = brightness; i <= maxBrightness; i++) {
      brightness = i;
      Serial.println(brightness);
      
      // Set the LED brightness
      analogWrite(ledPin, brightness);
      
      // Delay for the fade interval
      delay(fadeInterval);
    }
    
    fadingDirection = false;
  } else {
    for (int i = brightness; i >= minBrightness; i--) {
      brightness = i;
      Serial.println(brightness);
      
      // Set the LED brightness
      analogWrite(ledPin, brightness);
      
      // Delay for the fade interval
      delay(fadeInterval);
    }
    
    fadingDirection = true;
  }
}

View raw code

How the code works

Here are the main steps you need to take into account when controlling an LED with PWM.

First, define the pin that the LED is attached to. In this case, it is connected to GPIO 20. If you’re using a different GPIO number, change that on the code.

const int ledPin = 20;

In the setup(), set the LED as an output using the pinMode() function.

pinMode(ledPin, OUTPUT);

In the setup(), you can adjust the properties of the PWM signal using the analogWriteFreq(), analogWriteRange(), and analogWriteResolution().

  // Adjust PWM properties if needed
  /*analogWriteFreq(5000);
  analogWriteRange(65535);
  analogWriteResolution(16);*/

If you don’t specify the range and resolution of the PWM signal, it will use an 8-bit resolution with a maximum range of 255 (100% duty cycle).

In the loop(), you increase and decrease the duty cycle to increase and decrease the LED brightness. The following line outputs the PWM signal with the defined duty cycle values.

analogWrite(ledPin, brightness);

Uploading the Code to the Raspberry Pi Pico

For you to be able to upload code to the Raspberry Pi Pico, it needs to be in bootloader mode.

If the Raspberry Pi is currently running MicroPython firmware, you need to manually put it into bootloader mode. For that, connect the Raspberry Pi Pico to your computer while holding the BOOTSEL button at the same time.

Raspberry Pi Pico Bootloader mode

For future uploads using Arduino IDE, the board should go automatically into bootloader mode without the need to press the BOOTSEL button.

Now, select your COM port in Tools > Port. It may be the case that the COM port is grayed out. If that’s the case, don’t worry it will automatically find the port once you hit the upload button.

Raspberry Pi Pico - COM port not found Arduino IDE

Upload the code.

Arduino 2.0 Upload Button

You should get a success message.

Done uploading code Raspberry Pi Pico Arduino IDE

Demonstration

After uploading the code, the LED should start “breathing”. It will increase and decrease brightness over time gradually.

Wrapping Up

To wrap up, to output a PWM signal on a specified pin of the Raspberry Pi Pico, first, you need to declare that pin as an output. After that, you simply use the analogWrite() function and pass as arguments the GPIO number and the duty cycle.

We hope you’ve found this tutorial useful. If you’re just getting started with the Raspberry Pi Pico, make sure you read our getting started guide:

Check out all our Raspberry Pi Pico Guides »

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

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!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.