Connect and Control WS2812 RGB LED Strips via Raspberry Pi

If you are looking for RGB LED strips, you will probably come across the WS2812 or the WS2801. These two LED strips are very different, but both can be controlled with the Raspberry Pi. After using the latter in a previous tutorial and using it in our Ambilight, this tutorial is about using the Raspberry Pi WS2812 RGB LED Strip.

The models WS2812B and WS2811 are also compatible and can be addressed with this guide.

It must be said that one should not be fooled by the “smaller” model number of the WS2801. This has – apart from the price – a few advantages, which will be discussed in more detail below.

 

Components

DC Steckeradapter

A plug adapter makes connecting the power cable to the power supply very easy.

Anyone who has already used an RGB LED strip (such as Ambilight) can continue to use the accessories. This includes the following in addition to a Raspberry Pi:

 

The maximum power of the power supply depends on the number of LEDs. According to the data sheet, an LED under full load (= maximum brightness) needs about 60mA. At 5m and 30 LEDs / m, this is 9 amps. So, a power supply, which has up to 10A is suitable. If you have more LEDs in use, you may need more than one power supply (more on that later).

In addition, of course, the actual RGB LED strip of the type WS2812 (B) or WS2811 (also called NeoPixel) is required. These are available in three different versions, which differ in the number of LEDs per meter:

  1. LED Strip mit 30 LEDs per meter
  2. LED Strip mit 60 LEDs per meter
  3. LED Strip mit 144 LEDs per meter

The length should be chosen depending on the project to be implemented. But mostly 5m rolls are a bit cheaper. My recommendation is the middle version with 60 LEDs/m. These have a higher density of lights and thus a higher brightness. In terms of price, however, they are still cheaper than a similarly long WS2801 strip with only 32 LEDs

 

NeoPixel WS2812B / WS2811 vs. WS2801 on a Raspberry Pi

Raspberry Pi WS2812 RGB LED Detailansicht

With only one data line, the frequency must be higher to carry the same amount of data.

In a previous tutorial we already saw how to control a WS2801 RGB LED strip. That stip differs from the WS2812B or WS2811 and has some advantages, which I would like to list here first:

  • Having two data lines requires fewer calculations.
  • As a result, a higher frequency can be achieved.
  • The brightness of the WS2801 is higher.
  • It is also possible to control the WS2801 and play music, which is not possible with the WS2812 (more on this below)

Now the question arises, why one should still use a WS2812 RGB LED strip on the Raspberry Pi, if the WS2801 nevertheless brings some advantages? The answer is quite simple: the cheaper price. In comparison, one meter of WS2801 is quite expensive, which is why you want to handle it more sparingly. At relatively low prices for several feet of a WS2812 strip, even a large projects can be realized without a huge budget.

However, it must be said that it is unfortunately not possible to simultaneously play sounds via the Raspberry Pi onboard sound card and control the strip. This is because the Raspberry Pi is not a real-time system like the Arduino or ESP8266 is. For the sound reproduction PWM is used, which is also needed to control the WS2812 on the Raspberry Pi. Using both at the same time is not possible, which is why someone who relies on the sound reproduction should just take the WS2801.

 

Connecting the NeoPixel WS2812 to the Raspberry Pi

Before we connect the Raspberry Pi to the WS2812 LED Strip, we finish the power supply. If your strip has less than 20-30 LEDs, external power is not required. If it has more LEDs, the power of the Pi, however, is no longer enough and an external power supply is required.

The power supply itself depends on the selected type. For a power adapter with additional DC adapter (beginners), only the DC adapter needs to be connected, which will be followed by the power cables of the WS2812B. Once you have chosen this method, you can jump to the next point. A switched-mode power supply (for experienced users), however, is a little more complex.

Before, however, the note: When working with 230V caution is necessary because of mortal danger! Get help from an electrician or get back to the safe version of the normal power supply! Perform all work with a separate network connection.

First, we need a standard power cable that can handle 10A. Mostly on the bottom of the plug is a corresponding note (230V, 10A). We cut this cable carefully with a utility knife or similar.It contains two or three cables with different colors. These cables must also be carefully stripped.

Aufgeschnittenes Netzkabel mit abgetrennter Isolation

Power cord with separated insulation and two inner cables (black => L, blue => N).

My cable has only two inner cables, but that’s enough. For connection to the switching power supply, the colors of the inner cables serve as orientation. The switching power supply has the connections “L”, “N” and “PE” or a grounding symbol.

  • The black or brown inner cable comes to the outer conductor “L”.
    The blue inner cable comes to the neutral conductor “N”.
    The green-yellow inner cable is connected to the protective conductor “PE” or earthing symbol.
Multimeter am Schaltnetzteil des WS2801 LED Strip

The voltage should be about 5V.

After the locking screws have been tightened, the power cord can be plugged into the socket and the voltage at the power supply can be measured with a multimeter. Although this is not mandatory, but can be made as a hedge. VCC is connected to V+ and GND to COM. If the voltage is not exactly 5V, this is not a problem.

Theoretically, it is also possible to power the Raspberry Pi from this power supply. Some users (according to comments in the WS2801 tutorial) also have done this. For reasons of space, this will not be discussed here.

 

Connection between Raspberry Pi and WS2812 NeoPixel stripes

If the power supply is set up so far, we connect the Raspberry Pi to the WS2812 RGB LED strip. The (switching) power supply must first be disconnected from the power.

Since there is only one data line, we only need one pin (GPIO 18). It is important that the ground connections of the Raspberry Pi and the switching power supply are connected, but not the 5V voltages! Overall, only two cables run from the Raspberry Pi to the WS2812 LED Strip: GPIO 18 (to DIN) and GND to COM of the PSU and GND of the strip.

 

Raspberry Pi WS2812 Steckplatine

Schematic connection between Raspberry Pi, WS2812 and the external power supply

Depending on the length of the LED strip, the external power connection should be installed in several places. Ideally, the VCC and GND will be connected in parallel with the switching power supply on approximately every meter (so that many cables will lead to the power supply input).

Note: For lengths less than 1m, the power supply can also be omitted and the input voltage from the RV 5V pin of the Raspberry Pi come.

 

Preparation & Installation

Before we install the Raspberry Pi library for the WS2812 LEDs, some preparations have to be made:

  1. The package sources are updated:
    sudo apt-get update
  2. We install the required packages (confirm with Y):
    sudo apt-get install gcc make build-essential python-dev git scons swig
  3. The audio output must be deactivated. For this we edit the file
    sudo nano /etc/modprobe.d/snd-blacklist.conf

    Here we add the following line:

    blacklist snd_bcm2835

    Then the file is saved by pressing CTRL + O and CTRL + X closes the editor.

  4. We also need to edit the configuration file:
    sudo nano /boot/config.txt

    Below are lines with the following content (with Ctrl + W you can search):

    # Enable audio (loads snd_bcm2835)
    dtparam=audio=on

    This bottom line is commented out with a hashtag # at the beginning of the line: #dtparam=audio=on

  5. We restart the system
    sudo reboot

 

Now we can download the library.

git clone https://github.com/jgarff/rpi_ws281x

In this directory are on the one hand some C files included, which can be easily compiled. The example code for this is easy to understand. In order to use them in Python, we need to compile them:

cd rpi_ws281x/
sudo scons

However, in this tutorial we are mainly interested in the Python variant and therefore switch to the Python folder:

cd python

Here we carry out the installation:

sudo python setup.py build
sudo python setup.py install

This will allow us to carry out a first test in the next step.

 

Test the Raspberry Pi WS2812 RGB LED Strip

In the example folder are some example files, with which the LED strips can be tested. In addition, even two WS2801 LED strips can be independently controlled by Raspberry Pi (multistrandtest.py).

We are initially interested in the simple version. For this we have to complete a few details before the test and therefore we edit the sample file.

sudo nano examples/strandtest.py

The file looks like this, where we have to state LED_COUNT (number of LEDs to be addressed) and LED_PIN (18 us).

Then we save (CTRL + O) and return to the terminal (CTRL + X). Now the file can be executed (passing the path to the compiled files is important):

sudo PYTHONPATH=".:build/lib.linux-armv7l-2.7" python examples/strandtest.py

The LEDs of the WS2812 strip should light up as in the video below. In the upper code only a few effects (rainbow, etc.) are defined, however, it is also possible to create further effects analogously (everybody who wants to post his code for effects as a comment is welcome).

 

Something more

Pimoroni pHAT für Raspberry Pi WS2812B

The pHAT is available for Raspberry Pi 3 Model B and Zero.

The WS2812 NeoPixel LEDs are also used in many other projects (mainly designed for Arduino), so you can certainly port some of them.

In addition, the Raspberry Pi Shop Pimoroni made an attachment for the Model B (from version B +) and the Raspberry Pi Zero and calls this unicorn pHAT. However, this RGB LED matrix uses its own software for operation.

Incidentally, the library I use is also offered by another developer as a server application.

69 Responses

  1. Great Tutorial, Thanks!
    I noticed you do not use a level converter between the PI and LED’s.
    Is a level converter a good idea or not necessary in this application?
    Thanks

    Reply
      • Doesnt the data input of the pixel strip be at 5v TTL level.
        The PWM pin18 is output at 3.3V,
        is it not safer to use a 74HC245
        buffer in case led power shorts to data line?

      • Yes, you could but it is not needed. Until you don’t connect the 5V power to the data line, it should be save. Data level must not be at 5V.

      • I tried anyway and yes it worked first time, I had to change the ws2812 strip colour sequence to get correct colours tho. Strip is in a 40 x 15 layout to show animation/scrolling text.
        Now writing code to map the strip laid out in an S type formation to an x,y matrix to make it easier to scroll pixels left,right,up and down.
        I would like to use the faster/lower power banana pi with the raspian image, but need to find out the GPIO mapping to select the right pin for PWM

  2. The program is running with no errors, but the LED strip is not lighting up. Is there a simple way to check whether the LED strip itself is working? Everything is set up like the video except the power to the LED strip is wired directly to an AC/DC power adapter plugged into a power strip for surge protection.

    Reply
  3. Great guide, thanks! Worked exactly as described. One question, what is the code to turn off all LEDs? Ctrl-C stops the program, but leaves the lights lit and sometimes sends the rpi into read only disk.

    Reply
  4. is it possible to control from buttons(rainbow.chase,blue,white) via browser?if it is possibly pls do tutorial pls,pls

    Reply
  5. Please do a turorial from Lightberry beacase is a useful and easy to control led via mobile app
    Just this hardware:
    Raspberry
    WS2812b led

    Reply
    • Its because the pixel strip data is PWM and it cant be shared with the sound which also uses PWM. So Sound has to go…

      Reply
      • Does that mean you cant use an LED strip like this, and also have the raspberry play any kind of audio through jack?

  6. As a Raspberry (Linux/Python) noob, this was an awesome guide. Due to several fat fingers it took a bit to get it setup but wow. Thank you for the effort in creating this.

    Reply
    • I found copying and pasting code lines from the tutorial to the terminal instead of typing the code in directly….unless of course, you’re talking about wiring the WS2812…I always have trouble with those tiny jst pins. It would be easier if the ends of our fingers slimmed down to needle-nose plier size at the ends, eh?

      Reply
  7. is there any c# library to control WS2811/2 with Raspberry pi and windows 10 IOT running on it ?

    Reply
  8. What do I do if I don’t want to run the script as root?

    I get the following error: RuntimeError: ws2811_init failed with code -5 (mmap() failed)

    Reply
  9. Thank you for the tutorial man :). I have one question though, why is it important to run the GND wire to the raspberry pi also? Why can we not just keep the data line connected to the raspberry pi? That part I dont understand.

    Thanks!

    Reply
  10. This was an excellent tutorial and got me up and running quickly!
    Now is there a tutorial somewhere on how I can implement a script for my ring of pretty lights to be used as a camera spot?
    I use this pi3 for Octoprint and I want to use the WS2812 as a ring light over my camera and have it turn on when the camera streams and shuts off when done streaming.

    Reply
  11. Hi: This is not running for me and my ws2812, PI model 3, Raspian Jessie.
    1) When power is applied the fifth LED glows green. Is this expected?
    2) When running the script, the very first LED seems to run through the color patterns. I don’t seem to have control of the others LEDs.

    Reply
  12. Has anyone tried this on Raspbian Stretch? Blacklisting and disabling the audio fully crashes (without being able to login anymore) my raspberry pi 3.
    Without blacklisting the LED strip (a ws2812b strip) does absolutely nothing. Haven’t been able to get a single light working :(.

    Reply
  13. Hi, it doesn’t work for me, after launching strandtest.py script, I got an error message : “ImportError: No module named rpi_ws281x.rpi_ws281x”. I don’t how to fix it even if I followed this tutorial slowly and carefully… If you can help me, it would be really appreciated.

    Reply
    • When you installed it, did it return any error messages? The package is not installed, that’s why you get that error.

      Reply
      • Well, I didn’t get any error message or anything bad… I’m going to try it with a RPi2, my RPi3 is already busy 🙂
        Thanks.

      • I don’t know what I missed but I fail again with my RPi3 with a fresh install of Raspbian (stretch 2018-03-13)… same problem with my RPi1

  14. Hi,
    I have the same problem than Mickael G.
    “ImportError: No module named rpi_ws281x.rpi_ws281x”.
    If you have an idea. Thank’s

    Reply
    • The module was not installed correctly.

      “Now we can download the library.

      git clone https://github.com/jgarff/rpi_ws281x
      In this directory are on the one hand some C files included, which can be easily compiled. The example code for this is easy to understand. In order to use them in Python, we need to compile them:

      cd rpi_ws281x/
      sudo scons
      However, in this tutorial we are mainly interested in the Python variant and therefore switch to the Python folder:

      cd python
      Here we carry out the installation:

      sudo python setup.py build
      sudo python setup.py install
      This will allow us to carry out a first test in the next step.”

      Reply
  15. great job, everything is working!
    Any suggestions or link to how I could change animation by pressing a button. Each button press would initiate a different LEd animation. Animation that goes on and on until the button is pressed and thus switching to the next one.

    Reply
  16. Do you think it is possible to get rid of the audio limitation with the w2812 using an extra audio card?

    Reply
  17. Hello, when I try to run:
    sudo python setup.py build
    sudo python setup.py install

    I get the following error:

    Extracting in /tmp/tmp4DhWJT
    Traceback (most recent call last):
    File “setup.py”, line 4, in
    use_setuptools()
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 161, in use_setuptools
    return _do_download(version, download_base, to_dir, download_delay)
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 120, in _do_download
    _build_egg(egg, archive, to_dir)
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 62, in _build_egg
    with archive_context(archive_filename):
    File “/usr/lib/python2.7/contextlib.py”, line 17, in __enter__
    return self.gen.next()
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 100, in archive_context
    with ContextualZipFile(filename) as archive:
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 88, in __new__
    return zipfile.ZipFile(*args, **kwargs)
    File “/usr/lib/python2.7/zipfile.py”, line 770, in __init__
    self._RealGetContents()
    File “/usr/lib/python2.7/zipfile.py”, line 811, in _RealGetContents
    raise BadZipfile, “File is not a zip file”
    zipfile.BadZipfile: File is not a zip file

    Do you have any idea why this is so? Thank you

    Reply
    • I am receiving this error as well on a fresh install of latest stretch lite.

      The Python directory in rpi_ws281x downloads setuptools-5.7.zip

      examples ez_setup.py ez_setup.pyc neopixel.py README.md rpi_ws281x.i setup.py setuptools-5.7.zip

      Any insight would be greatly appreciated.

      Reply
      • Same issue here with Linux Stretch for raspberry pi zero =(
        Any help?

      • So if anyone is still fighting this zip issue…
        Looks to me after some googling that there’s an issue with python’s ’setuptools‘.
        I ran these commands:
        sudo apt-get update
        sudo apt-get install python-pip
        I’m not sure that we need pip specifically, but I think setuptools is bundled with this installation. All drivers installed properly after this. For the even lazier among you (such as I), this guy made a great tutorial and more importantly bash script that does everything automatically. Here:



        curl -L http://coreelec.io/33 | bash
        Then ran the strandtest.py and it’s working great.
        Hope that works for you.

      • >sudo apt-get install python-pip
        and then retry the build and install commands.

      • I am having the same issues with the inability to read the .zip file. I’ve tried using Tom’s instructions in regards to using the “curl -L http://coreelec.io/33 | bash” script , but that is giving me the same errors. I’m running a RaspberryPi Zero /w and a fresh install debian 8.0. I’ve attempted the setup.py build and install several times, and also tried deleting the rpi_ws281x directory and starting from scratch several times. Any one else conquer this Bad Zip file problem any other way?

  18. I had this working as the instructions you provided. After a few fresh installs trying to get Hyperion working this strand test no longer works.
    Setup: RPI B rev2 Ws2811 led strip.
    RPI os: Raspbian Stretch latest revision.
    Have I fried my gpio port 18? LED strip still works with a different source, just seems to be no data output on gpio 18.
    Cheers

    Reply
  19. I’m experiencing all manner of random flashing LED’s when the code runs. The ./test application runs fine, but anything in python running under SUDO, I’m getting odd results. Someone mentioned power suppl? I’m running the Pi Zero on a Pi3 5A 15W PSU but I’m baffled if power could be the issue. I’ve disabled audio etc, but I’m loosing confidence with the WS2812 (Its a Waveshare RGB LED HAT with 32 LED’s)

    Reply
  20. Great guide, I was wondering hoy many LEDS is the theoretical maximum that we can control? I am currently working on a project where I need to control 221 LEDs but I don’t know if this setup will be able to handle it.

    Reply
    • There are no replies about this type questions. So I will try mine: Others (https://github.com/FastLED/FastLED/issues/288) pointed noticeable delay control ( I would like to know more about this too ) and a memory bottle neck related to the quantity of RAM available in the Micro-controller. I don’t know how they calculate that too … but I will I do a simple relation to this info and our RapsberryPi: If a RaspberryPi 3 (model B) has 1 Gb RAM but finally 500KB available ( in my case ) -> If with Arduino Mega (3KBytes RAM ) they can address at least1000 LED, my calc is that with 500KB available I would be able to address at least 166,666 LEDs.

      Reply
      • + info at readme [https://github.com/jgarff/rpi_ws281x]

        “Both PWM and PCM use DMA transfer to output the control signal for the LEDs. The max size of a DMA transfer is 65536 bytes. Since each LED needs 12 bytes (4 colors, 8 symbols per color, 3 bits per symbol) this means you can control approximately 5400 LEDs for a single strand in PCM and 2700 LEDs per string for PWM (Only PWM can control 2 independent strings simultaneously) SPI uses the SPI device driver in the kernel.”

  21. Hi, your tutorial was great, it works perfectly for me.
    Only a question: I need to use audio too, can i use any external audio card (e.g. usb) ?

    Reply
  22. Is there a way to run two equal length strips from another GPIO pin or are we stuck with only one?

    Reply
  23. Hi I have 1200 LEDs I am going to set up. I’ve got PSUs ready, and was planning on using buying a TEENSY 3.2 or similar.

    However, I’ve stumbled across your post, and I have a Raspberry Pi lying around – I didn’t think it would do the job, but I’m curious, now you have proved it.

    So the BIG question is, could your project scale up to 1200 LEDs?

    Reply
  24. Hi, I have a 30 LED strip and I am trying to mount it on a Raspberry pi model 3 b. I followed the tutorial and even tried the curl bash command, but for both the cases here is the error message that I am getting:
    Traceback (most recent call last):
    File “strandtest.py”, line 9, in
    from neopixel import *
    ImportError: No module named neopixel

    Please let me know if I am doing something wrong. Any help is much appreciated! Thanks!

    Reply
  25. Great tutorial! I would like to try to take this routine and run it on start up with the pi so that I don’t have initiate the script every time I turn on the pi. I have tried to search for methods on booting a python script online but none of them worked. Any thoughts or recommendations of where to look?

    Reply
  26. help

    pi@raspberrypi:~/rpi_ws281x/python $ sudo python setup.py build
    Extracting in /tmp/tmp6OITcv
    Traceback (most recent call last):
    File “setup.py”, line 4, in
    use_setuptools()
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 140, in use_setuptools
    return _do_download(version, download_base, to_dir, download_delay)
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 120, in _do_download
    _build_egg(egg, archive, to_dir)
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 62, in _build_egg
    with archive_context(archive_filename):
    File “/usr/lib/python2.7/contextlib.py”, line 17, in __enter__
    return self.gen.next()
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 100, in archive_context
    with ContextualZipFile(filename) as archive:
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 88, in __new__
    return zipfile.ZipFile(*args, **kwargs)
    File “/usr/lib/python2.7/zipfile.py”, line 770, in __init__
    self._RealGetContents()
    File “/usr/lib/python2.7/zipfile.py”, line 813, in _RealGetContents
    raise BadZipfile, “File is not a zip file”
    zipfile.BadZipfile: File is not a zip file
    pi@raspberrypi:~/rpi_ws281x/python $ sudo python setup.py install
    Extracting in /tmp/tmpgkjX_D
    Traceback (most recent call last):
    File “setup.py”, line 4, in
    use_setuptools()
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 140, in use_setuptools
    return _do_download(version, download_base, to_dir, download_delay)
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 120, in _do_download
    _build_egg(egg, archive, to_dir)
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 62, in _build_egg
    with archive_context(archive_filename):
    File “/usr/lib/python2.7/contextlib.py”, line 17, in __enter__
    return self.gen.next()
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 100, in archive_context
    with ContextualZipFile(filename) as archive:
    File “/home/pi/rpi_ws281x/python/ez_setup.py”, line 88, in __new__
    return zipfile.ZipFile(*args, **kwargs)
    File “/usr/lib/python2.7/zipfile.py”, line 770, in __init__
    self._RealGetContents()
    File “/usr/lib/python2.7/zipfile.py”, line 813, in _RealGetContents
    raise BadZipfile, “File is not a zip file”
    zipfile.BadZipfile: File is not a zip file
    pi@raspberrypi:~/rpi_ws281x/python $

    Reply
  27. Your tutorial is great! I am completely new to all of this and I was able to get the strand test to work (I have two 5M /150 pixel strips and was able to test both successfully plugged in end to end by changing the LED_COUNT to 300). But I am completely lost as to where to go for help for the next step which is to get the lights running my own patterns. I have found the Lightwork Editor at https://hohmbody.com/flickerstrip/lightwork/ and have been able to create my own patterns using this. When I save the patterns, they end up in my pi/downloads folder as .ino files. I am looking for somewhere to go to understand how to use these files. When I try to google search for information to control the LEDs, it leads me back to tutorials like this. Any help would be appreciated! Thank you!

    Reply
  28. Hello, Everything works great I was just wondering how I could make the whole strip turn the same color all at once, ( example red). I am planning on making a Discord bot to control my lights, so if I enter a command like !red the whole strip will turn red. So what Im am asking is there anyway to make the whole strip light up at once instead of each pixel like the strand test wipe color?

    Reply

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to Raspberry Pi Tutorials and don't miss any new Tutorial!