Light up WS2811 LEDs with a Raspberry Pi 5 via SPI

A few weeks ago I bought 300 addressable LEDs. To be more precise, 6 x 50 12V WS2811 with a spacing of 25 cm each. Also known as NeoPixel. I wanted to control these LEDs with a Raspberry Pi. So I bought the latest model, Raspberry Pi 5 with 8GB RAM.

WS2811 LEDs by Raspberry Pi 5 SPI

After I had set up my Raspberry Pi, I wanted to follow the tutorial NeoPixels on Raspberry Pi by Tony DiCola to carry out a first test with the LEDs. I had already done the wiring as described under Using External Power Source Without Level Shifting. But then I read the following information in the next item Python Installation of NeoPixel Library.

The next line then said that you should watch the tutorial CircuitPython NeoPixel Library Using SPI. With the help of the Adafruit_CircuitPython_NeoPixel_SPI library, an LED ring is controlled via an FT233H. I would like to show how I did this with a Raspberry Pi 5.

Install Raspberry Pi OS

Since my last point of contact with a Raspberry Pi has been the post Installing ownCloud 8.1 on a Raspberry Pi in 2016, I will start here with the basic requirements. Installing an operating system on the Raspberry Pi is much easier than it used to be. Simply follow the instructions under Install an operating system. You can simply skip this part if you like.

Install Raspberry Pi Imager

You can simply install Raspberry Pi Imager on Ubuntu for example with the following command.

sudo apt-get install rpi-imager

Operating System and Storage

I have choosen Raspberry Pi OS (64-bit) as operating system. For the storage I have selected a microSD. Then press the Write button and wait a little.

Raspberry Pi Imager Operating System

Raspberry Pi OS setup

The initial setup of Raspberry Pi OS is pretty easy.

  • Choose country, language and timezone
  • Enter username and password
  • Select WiFi Network
  • Choose Browser
  • Update Software
  • Restart

Wiring WS2811 to Raspberry Pi 5

Here is the wiring I made to get a Raspberry Pi 5 working with WS2811 via SPI.

  • Pi Ground to NeoPixel GND
  • Pi GPIO10 to NeoPixel Din
  • Power supply ground to NeoPixel GND
  • Power supply 12V to NeoPixel 12V

I created the image with the software Fritzing containing parts of Peter Van Epp and Rlah. Please note that the part of the NeoPixels does contain 5V instead of 12V. Feel free to download the resulting file wiring.fzz.

Raspberry Pi 5 WS2811 SPI Fritzing Wiriing

Python setup

Please open a terminal on your Rasperry Pi OS and create a project folder. For example.

mkdir neopixel
cd neopixel

Enable SPI

To use SPI we need to enable it. Run the following command.

sudo raspi-config

Choose 3 Interface Options and afterwards I4 SPI and agree with Yes. Close the configs afterwards.

Create python environment

As mentioned in Use pip with virtual environments we will need to create a virtual environment. I have decided to take the per-user version by running the following command.

python -m venv ~/.env

We can activate the environment with the next command.

source ~/.env/bin/activate

And disable later with this command.

deactivate

Install Adafruit_CircuitPython_NeoPixel_SPI

With active python environment we install Adafruit_CircuitPython_NeoPixel_SPI with the following command.

pip3 install adafruit-circuitpython-neopixel-spi

LED test example with SPI

Create the following file neo.py in your project directory. It is just a modified version of CircuitPython NeoPixel Library Using SPI - Example Code by Carter Nelson.

import time
import board
import neopixel_spi as neopixel

NUM_PIXELS = 50
PIXEL_ORDER = neopixel.GRB
COLORS = (0xFF0000, 0xFFFF00, 0x00FF00, 0x00FFFF, 0x0000FF, 0xFF00FF)
DELAY = 0.2

spi = board.SPI()

pixels = neopixel.NeoPixel_SPI(spi,
                                NUM_PIXELS,
                                pixel_order=PIXEL_ORDER,
                                auto_write=False)

while True:
    for color in COLORS:
        for i in range(NUM_PIXELS):
            pixels[i] = color
            pixels.show()
            time.sleep(DELAY)
            pixels.fill(0)

An run the code with the following command.

python3 neo.py

Afterwards your 50 LEDs should one after an other with a delay of 200ms light up. First with green, then yellow, red, purple, blue and cian.

Next Previous