8: Smooth Chase with PWM

This project takes the basic LED chase and makes it look smoother by fading between the LEDs.

This combines two ideas: a chase pattern (turning different LEDs on at different times) and PWM (so brightness can change smoothly instead of jumping).

Coding ideas you will use:

Learn more (optional):

Goal

Create a moving light effect across three LEDs using PWM.

Parts you need

Important: choose the right resistor

Your kit has 150Ω and 100Ω resistors.

  • For a red or yellow LED, use 150Ω
  • For a green, blue, or white LED, use 100Ω

Using the wrong resistor can damage an LED.

Wiring idea

Build it first, then compare your setup to the diagram. Did you connect each part to the pin you meant to use?

Use the same wiring as the three-LED chase project. Each LED should have its own resistor and its own path back to GND.

Hint

The circuit is the same as what you built in 7: LED Chase.

Example pins: GP6 (GPIO 6), GP7 (GPIO 7), and GP8 (GPIO 8).

Wiring diagram showing three LEDs connected to GP6 (GPIO 6), GP7 (GPIO 7), and GP8 (GPIO 8) through separate resistors, all returning to GND for a chase animation

Code

Pin reminder

Wired your LEDs to different GPIO pins? Update LED_GPIOS in the code below to match your wiring.

import machine
import time

# Choose the GPIO pins your LEDs are connected to.
LED_GPIOS = [6, 7, 8]

# Set up PWM on those pins
leds = [machine.PWM(machine.Pin(gpio)) for gpio in LED_GPIOS]

for l in leds:
    l.freq(1000)

# --- ADJUST THESE TO CHANGE THE FEEL ---
speed = 400         # Lower is slower (try 200 for a real crawl)
width = 30000       # Higher makes the "trail" longer
# ---------------------------------------

max_val = 65535
position = 0

print("Slow fade across GPIO pins:", LED_GPIOS)

while True:
    # 1. Move the wave position slowly
    # We use (max_val + width) so the light can fully "fade out" 
    # before restarting on the first pin
    position = (position + speed) % (max_val + width)

    for i in range(len(leds)):
        # 2. Give each LED a fixed spot on the line
        # LED 0 is at 0, LED 1 is at 21845, LED 2 is at 43690
        led_spot = i * (max_val // (len(leds) - 1))

        # 3. How far is the "wave" from this LED?
        distance = abs(position - led_spot)

        # 4. If the wave is close, turn on the light
        if distance < width:
            # Linear math: Brightness drops as distance increases
            brightness = int((1 - (distance / width)) * max_val)
            leds[i].duty_u16(brightness)
        else:
            leds[i].duty_u16(0)

    time.sleep(0.01)
Arduino Code Coming Soon

What to notice

Try this