Addressable LEDs
The robot is equipped with 8 configurable LEDs. This topic was covered in detail during the presentation; here is a brief summary. The configured LEDs in the robot consist of three distinct colors (R - Red, G - Green, B - Blue). Each of these LEDs can have its brightness adjusted in 256 steps, allowing for a total of 16 million shades. Accordingly, each LED component is configurable using 8 bits, resulting in a total of 24 bits to configure all LEDs. The LEDs used in the robot are WS2812 type. Each LED comes with 5 connectors: it requires a power supply (VDD, GND), chip power (VCC), and also has a digital input (DI) and a digital output (DO). The color, brightness and also the the driver for the next input in case its connected in cascade mode is controller by an integrated chip inside the LED.
Addressable LED Management
The robot features eight addressable LEDs. While these were covered in detail during the lecture, here is a brief summary. Each LED module consists of three color channels (R – red, G – green, B – blue). The brightness of each channel can be adjusted in 256 discrete steps, allowing for a total of 16 million possible color combinations. This means each LED is controlled using 8 bits per color channel, totaling 24 bits per LED.
The LEDs used in the robot are WS2812-type addressable LEDs. These LEDs do not require external current-limiting resistors, as they integrate built-in current regulators. The wiring configuration of the WS2812, as specified in the datasheet, is shown in the diagram below.
A WS2812 LED
The digital output (DO) of one LED can serve as the digital input (DI) of the next LED, allowing multiple LEDs to be connected in series. This cascading capability enables the control of an entire LED strip using a single data line, as demonstrated in the following diagram.
A WS2812 LEDs in cascade
To simplify usage, the underlying functions handle the transmission of bit patterns automatically. However, for reference, the 24-bit configuration word for a single LED is structured as follows:
- The color component order is Green-Red-Blue (GRB).
- The data is transmitted starting from the most significant bit (MSB) of each component.
This format ensures consistent color rendering across the LED chain, as illustrated in the diagram below.
Addressable LED configuration with color encoding
⚡Hands-on tasks
Controlling the 8 Addressable Serial LEDs on the Robot
We will write a program to control the 8 programmable LEDs on the robot using the NeoPixel library. The LEDs should follow this sequence, changing color every second: 🟥 Red → 🟩 Green → 🟦 Blue → ⚪ White At the end of the program, all LEDs should be turned off.
To achieve this, we will use MicroPython's neopixel.py module. Alternatively, the robot's pico_car.py module can also be used for controlling the LEDs (see additional tasks for details).
Info
More details in NeoPixels docs
We will import the necessary modules:
import machine # Controls hardware
import neopixel # Handles programmable NeoPixel LEDs
import time # Provides delay functions
The LED strip is connected to GPIO6 on the microcontroller. The NeoPixel() function initializes it, and the second parameter specifies the number of LEDs (8 in this case).
LED_pin = machine.Pin(6) # Define GPIO6 as LED control pin
LED_chain = neopixel.NeoPixel(LED_pin, 8) # Create NeoPixel object for 8 LEDs
The function automatically handles the correct I/O direction, so no additional configuration is needed.
Understanding LED Color Control
Each LED color is controlled using 24-bit values:
- First 8 bits: Red component
- Next 8 bits: Green component
- Last 8 bits: Blue component
For a given LED, the color is stored as a tuple (R, G, B), where:
0means off255means maximum brightness
For example, setting an LED to full red:
To apply changes, we must write the updated data to the LED strip:
Complete LED Color Sequence Program
import machine
import neopixel
import time
# Initialize LED strip on GPIO6 with 8 LEDs
LED_pin = machine.Pin(6)
LED_chain = neopixel.NeoPixel(LED_pin, 8)
# Define colors (R, G, B)
colors = [(255, 0, 0), # Red
(0, 255, 0), # Green
(0, 0, 255), # Blue
(255, 255, 255)] # White
# Loop through colors with 1-second delay
for color in colors:
for i in range(8): # Apply color to all LEDs
LED_chain[i] = color
LED_chain.write() # Update LED strip
time.sleep(1) # Hold for 1 second -> delay
# Turn off all LEDs
for i in range(8):
LED_chain[i] = (0, 0, 0) # Set to black (off)
LED_chain.write()
Try testing various configurations of colors! 🚀
How to change the color?
Simulation
The following simulation demonstrates the example program in action. Feel free to modify the code and experiment with different values to see how it affects the output. Try testing various configurations to deepen your understanding! 🚀
Try it in the Online Simulator
How NeoPixel driver can be inmplemented with PIO?
Here is a short article how NeoPixel LEDs could be driven with PIO (Programmable IO) peripheral.
Additional Tasks
✅ Task 1: Experiment with different brightness levels and color combinations.
✅ Task 2: Implement a gradual brightness increase or decrease for the LEDs.
Example: Smoothly increase the red component from 0 to 255 in steps of 2, with a 10 ms delay between updates.
for j in range(0, 255, 2): # Gradually increase brightness
for i in range(8):
LED_chain[i] = (j, 0, 0) # Red intensity increases, green and blue stay off
LED_chain.write()
time.sleep_ms(10) # Small delay for smooth transition
🚀 Try modifying the code to create dynamic light effects or animations!
Tip
Try range with decreasing order: range(255, 0, -2)