To get you started with how to program your Pico in CircuitPython, especially for those who may have started out with the official MicroPython setup, we've 'ported' the Getting Started with MicroPython on Pico book examples to CircuitPython. The book is awesome, please download/purchase it to support Raspberry Pi Press!

The Pico's RP2040 microcontroller chip is a digital device, meaning by itself, it only understands digital signals, which are either on or off. Digital devices cannot understand analog(ue) signals, which can range anywhere between on and off. Therefore, included in the RP2040 is an analog(ue)-to-digital converter, or ADC. An ADC takes analog(ue) signals and converts them to digital signals. The ADC on the Pico is available on three pins: GP26, GP27, and GP28. To read analog(ue) signals, you must use one of these three pins.

Each of the three pins can be used as an analog(ue) input, but to do that, you need an analog(ue) signal, which you can easily get from a potentiometer. There are many types of potentiometers available, such as the ones on the PIR sensor from the Burglar Alarm section of this guide. The type of potentiometer you'll use for this example is called a "rotary potentiometer".

Reading a Potentiometer

It's simple to use CircuitPython to read the analog(ue) value from a potentiometer. The built-in module analogio does all the heavy lifting for you, and provides you with an easy way to read analog(ue) signals on analog(ue)-capable pins.

Wiring the Potentiometer

The first step is wiring your potentiometer. Connect it to your Pico as shown below. Place the potentiometer on the breadboard with the pins-side towards you to determine the proper left and right pins.

This is a cute half-size breadboard, good for small projects. It's 2.2" x 3.4" (5.5 cm x 8.5 cm) with a standard double-strip in the middle and two power rails on both...
$5.00
In Stock
These are our favorite trim pots, perfect for breadboarding and prototyping. They have a long grippy adjustment knob and with 0.1" spacing, they plug into breadboards or...
$1.25
In Stock
Handy for making wire harnesses or jumpering between headers on PCB's. These premium jumper wires are 3" (75mm) long and come in a 'strip' of 20 (2 pieces of each of ten rainbow...
$1.95
In Stock

For this example, you'll need your Pico, a potentiometer, and some male-to-male jumper wires.

  • Board GND to breadboard ground rail
  • Board 3V3 to breadboard power rail
  • Board GP26 to potentiometer middle leg
  • Potentiometer left leg to breadboard ground rail
  • Potentiometer right leg to breadboard power rail

Programming to Read the Potentiometer

Update your code.py to the following and save.

"""
Read the potentiometer value. Prints the value to the serial console every two seconds.

REQUIRED HARDWARE:
* potentiometer on pin GP26.
"""
import time
import board
import analogio

potentiometer = analogio.AnalogIn(board.GP26)

while True:
    print(potentiometer.value)
    time.sleep(2)

Now, connect to the serial console. You should see a value between 0 and 65535, depending on the current rotation of the knob, being printed out to the serial console. Try turning the knob on the potentiometer. When you turn it to the left, the value goes down, and when you turn it to the right, the value goes up.

If the values go the opposite direction when you turn the knob, try swapping the ground and power connections to your potentiometer. You may have them backwards!

Don't worry if your value never quite reaches 0 or 65535. Electronic components are built with what's called a tolerance, which means the resulting values may not be precise.

This value is the analog value. While you can say to yourself that 65535 is max voltage and 0 is min voltage, without doing some math in your head, the rest of the values aren't that useful to you. It's much easier to let CircuitPython do the math for you.

Update your code.py to the following and save.

"""
Convert the potentiometer value to a voltage value. Prints the voltage value to the serial console
every two seconds.

REQUIRED HARDWARE:
* potentiometer on pin GP26.
"""
import time
import board
import analogio

potentiometer = analogio.AnalogIn(board.GP26)

get_voltage = 3.3 / 65535

while True:
    voltage = potentiometer.value * get_voltage
    print(voltage)
    time.sleep(2)

The get_voltage equation provides a reasonable approximation of the voltage it represents. The first number is the maximum voltage available from the 3V3 pin on your Pico, and the second number is the maximum analog value. Essentially, dividing 3.3 / 65535 returns a voltage value based on the analog value.

To use the equation, you simply multiply the raw potentiometer value by the get_voltage helper, and print the resulting value to the serial console. Now if check the serial console, you'll see a number between 0 and 3.3, depending on the current rotation of the knob. Turn the knob to see the values change!

That's all there is to reading the values of a potentiometer as both a raw analog(ue) value and a voltage value using CircuitPython and Pico!

Using PWM to Fade an LED

So far, everything you've done with LEDs have involved an on or off state. This is because the digital outputs on a microcontroller and only be on or off. Turning these outputs on and off is known as a pulse, and depending on the speed at which you change the pin state, you can "modulate" these pulses using Pulse Width Modulation. PWM has many uses. This example will show you how to use PWM to fade an LED up and down.

Every pin on the Pico can do PWM, however, you cannot do PWM on every pin at the same time. Some sets of pins on the Pico use the same PWM output, meaning they cannot be used a the same time to create a PWM object. If you want to know which pins use the same outputs, you can read the datasheet, or you can try to create a PWM object using CircuitPython. If you try to create a PWM object on two conflicting pins, CircuitPython will give you a ValueError: All timers for this pin are in use error. If this happens, choose a different pin.

Wiring the LED

The first step is to add an LED to your existing potentiometer setup. 

Need some indicators? We are big fans of these diffused LEDs. They are fairly bright, so they can be seen in daytime, and from any angle. They go easily into a breadboard and will add...
$4.95
In Stock
Handy for making wire harnesses or jumpering between headers on PCB's. These premium jumper wires are 3" (75mm) long and come in a 'strip' of 20 (2 pieces of each of ten rainbow...
$1.95
In Stock
ΩMG! You're not going to be able to resist these handy resistor packs! Well, axially, they do all of the resisting for you!This is a 25 Pack of...
$0.75
In Stock

For this example, you'll need your existing wiring setup, an LED, a resistor, and a male-to-male jumper wire. A 220Ω-1.0KΩ resistor will work; a 220Ω resistor is shown in the diagram.

  • Board GP14 to 220Ω resistor
  • LED+ to 220Ω resistor
  • LED- to breadboard ground rail (using a jumper wire)

Programming to Fade the LED

Update your code.py to the following and save.

"""
Use PWM to fade an LED up and down using the potentiometer value as the duty cycle.

REQUIRED HARDWARE:
* potentiometer on pin GP26.
* LED on pin GP14.
"""
import board
import analogio
import pwmio

potentiometer = analogio.AnalogIn(board.GP26)
led = pwmio.PWMOut(board.GP14, frequency=1000)

while True:
    led.duty_cycle = potentiometer.value

Now try turning the potentiometer. As you turn it, the LED will fade up or down depending on the direction you're rotating the knob. When the knob is all the way to the left, the LED will be off. When it is all the way to the right, it will be brightest.

When creating the PWM object, you provide both the pin you connected the LED to and a frequency. Then, inside the loop, we set the duty cycle equal to the potentiometer raw analog(ue) value.

Duty cycle controls the pin's output. At 0% duty cycle, the pin is off. At 100% duty cycle, the pin is fully on. A duty cycle of 50% means that the pin is on for half the pulses, and off for half. The reading taken from the potentiometer is applied to the LED PWM duty cycle, so a low reading is like a low voltage on an analog(ue) input which means the LED will be dim, and a high reading is like a high voltage which means the LED will be bright.

That's all there is to using PWM with CircuitPython and Pico to fade an LED!

This guide was first published on Jan 21, 2021. It was last updated on 2021-03-03 12:34:49 -0500.

This page (Potentiometer and PWM LED) was last updated on Oct 23, 2021.

Text editor powered by tinymce.