Some Linux boards, like the Coral, have PWM outputs. You can use these to pulse LEDs to dim them, or color mix, control motor speeds with a motor driver, or even hobby servos!
Supported Pins
The Coral only has 3 PWM pins:
- Pin #33 is PWM1
- Pin #32 is PWM2
- Pin #15 is PWM3
These are independent PWM outputs, each can have a different frequency and duty cycle
You can check that the 3 PWM's are enabled with ls /sys/class/pwm/
PWM with Fixed Frequency - LEDs
This example will show you how to use PWM to fade an LED.
Wire up an LED like before, but this time to PWM3 and GND
Double-check you have the right wires connected to the right location, it can be tough to keep track of pins as there are forty of them!
No additional libraries are needed so we can go straight on to the example code
However, we recommend running a pip3 update!
pip3 install --upgrade adafruit-blinka
import time import board import pwmio led = pwmio.PWMOut(board.PWM3, frequency=5000, duty_cycle=0) while True: for i in range(100): # PWM LED up and down if i < 50: led.duty_cycle = int(i * 2 * 65535 / 100) # Up else: led.duty_cycle = 65535 - int((i - 50) * 2 * 65535 / 100) # Down time.sleep(0.01)
Verify the LED is blinking. If not, check that it's wired to GPIO #15, the resistor is installed correctly, and you have a Ground wire to the Coral.
Type Control-C to quit
Servo Control
In order to use servos, we take advantage of pwmio
. Now, in theory, you could just use the raw pwmio
calls to set the frequency to 50 Hz and then set the pulse widths. But we would rather make it a little more elegant and easy!
So, instead we will use adafruit_motor
which manages servos for you quite nicely
Install it with pip3 install adafruit-circuitpython-motor
The PWM output from the Coral is only 2.5V peak, and not very strong, so you need to buffer it, we recommend using an HC4050 or similar low cost level shifter/buffer. Wire VCC and GND to 5V and GND on the Coral, and then the PWM output goes into one of the 6 inputs of the '4050.
- Connect the servo's brown or black ground wire to ground
- Connect the servo's red power wire to 5V power, USB power is good for a servo or two. For more than that, you'll need an external battery pack. Do not use 3.3V for powering a servo!
- Connect the servo's yellow or white signal wire to the control/data pin. In this case we're using the shifted PWM3



import time import board import pwmio from adafruit_motor import servo # create a PWMOut object on Pin PWM3. pwm = pwmio.PWMOut(board.PWM3, duty_cycle=2 ** 15, frequency=50) # Create a servo object, my_servo. my_servo = servo.Servo(pwm) while True: for angle in range(0, 180, 5): # 0 - 180 degrees, 5 degrees at a time. my_servo.angle = angle time.sleep(0.05) for angle in range(180, 0, -5): # 180 - 0 degrees, 5 degrees at a time. my_servo.angle = angle time.sleep(0.05)
PWM Output with Variable Frequency - Buzzers
This example will show you how to beep a piezo buzzer at different PWM frequencies
Connect a common Piezo buzzer to PWM3 and GND. Don't connect a speaker unless you have an amplifier - the pins on the Coral can only drive small buzzers!

import time import board import pwmio piezo = pwmio.PWMOut(board.PWM3, duty_cycle=0, frequency=440, variable_frequency=True) while True: for f in (262, 294, 330, 349, 392, 440, 494, 523): print(f) piezo.frequency = f piezo.duty_cycle = 65536 // 2 # On 50% time.sleep(0.25) # On for 1/4 second piezo.duty_cycle = 0 # Off time.sleep(0.05) # Pause between notes time.sleep(0.5)
If you want to make lots of tones, we recommend using the tone helper functions in simpleio
Install it with pip3 install adafruit-circuitpython-simpleio
and then follow this guide page
The output of the PWM pins isn't very strong, so if you want louder beeps, use the '4050 level shifting arrangement above
Page last edited March 08, 2024
Text editor powered by tinymce.