One of the many Raspberry Pi projects is the lighting of rooms or objects. LED strips are particularly suitable for this purpose, because many individual LEDs are aligned and each individual LED can display all RGB colors. Thus, some projects such as room lighting, Ambilight or e.g. a Christmas tree lighting can be realized. The effects of the colorful lights are impressive.
This article shows the general usage of the WS2801B on the Raspberry Pi. In doing so, we create an example in which LEDs of the strip are set (rainbow colors) and the brightness is dimmed. In the video at the end of the tutorial you can see the whole thing in action.
NLSF595 Serial (SPI) Tri-Color LED Driver The NLSF595 is advanced CMOS shift register with open drain outputs fabricated with 0.6 m silicon gate CMOS technology. This device is used in conjunction with a microcontroller, with only one. • Standard Serial (SPI) Interface. SPI Decoder is designed to receive SPI (595 shift register data) signal from a DMX-SPI Decoder or Arduino/other micro-controllers and decode it into an analog signal to control our RGB Flex Strips, it allows user to control up to 24 output channel (up to 8 RGB), with 128-level brightness control. Adafruit NeoPixel Digital RGB LED strips come to us in 4 or 5 meter reels with a 2 or 3-pin JST SM connector on each end and separated power/ground wires as shown in the pic below. If you order a full 4 or 5 meters, you get the full reel with both connectors installed (like the pic below).
Equipment
The RGB LED strips require an input voltage of 5V. The most favorable variant with 32 LEDs per meter has a distance between the LEDs of only 2.5 cm:
- WS2801B LED strip with 32 LEDs per meter (US / UK)
There are also versions available that are dust and water-resistant (IP67). Each of the individual LEDs has a current consumption of about 60 mA. At one meter this is almost 2A. This is quite more than the GPIOs of Raspberry Pi can deliver. We therefore need an external current source that supplies power to the RGB stripe. Depending on how long your strip is, the maximum current must be higher. The power supply should therefore be able to supply 10A at 5 meters.
You have the choice between two possibilities:
You have the choice between two possibilities:
With a plug adapter and power supply, the plus and minus poles can be easily connected to the LED strips.
- For beginners: Power adapter (US / UK) + plug-in connector (US / UK) (c.f. picture on the right)
- For experienced: Switching power supply (US / UK) + power cord (US / UK)
The difference is that a power cable has to be disconnected and then connected to the switching power supply. Since working with high voltage is dangerous, this is not recommended for beginners. For a power supply (similar to the laptop chargers) you only need an additional Power Jack adapter, so that you can detach the two voltage poles.
Last but not least jumper cables and a breadboard (US | UK) are required.
WS2801B vs. WS2812B
The WS2812 LED strips are often found on the Internet, which are also somewhat cheaper than the WS2801 models. However, these are not all too good for the Raspberry Pi, since the onboard audio output of the Raspberry Pi can not be used anymore. However, I will write another tutorialon how to use the WS2812 LED strips.
WS2801B strips have two data lines (data and clock), whereby individual LEDs can be addressed via the integrated SPI bus of the Raspberry Pi. This is different for the WS2812B models. These strips have only a single data pin, which is why before sending a lot more has to be calculated. For this reason the WS2801B RGB LED strips are preferable to the WS2812 for use on the Raspberry Pi, despite their supposedly smaller “serial number”.
Connect the switching power supply to the WS2801
Before we start, we have to connect the current source (only for the plug-in power supply). If you have selected the first variant – a charger-like power supply – you can jump to the next point. You only need to clamp the plug adapter to the power supply and loosen the screws.
Ensure that the power cord is compatible with 10A.
First of all: Working with 230V voltage can be deadly! While you make changes, all connections to the socket must be disconnected! Be careful and only work with it if you are sure of your cause. If this is not the case, I recommend the first power supply.
We start by cutting the power cord (e.g. old PC power cable). There are two or three cables inside. These must be carefully separated by about 1cm from the insulation, so that only the wire is visible in the cables. The switching power supply has three connections on the left side. On the one hand, “L” (phase / outer conductor) and “N” (neutral conductor), which are marked with AC (alternating current) and a grounding symbol. If your cable only contains two smaller cables, they will be connected to the AC connectors. If there are three, you must also identify the earth cable and connect it to the earthing symbol / “PE” connector.
Since the colors of the inner cables differ with older power cables, here is a brief overview, what color comes:
- The black or brown cable comes to the outer conductor “L“.
- The blue cable is connected to the neutral conductor “N“.
- The green-yellow cable is connected to the protective conductor “PE” or grounding symbol.
Cut-out two-core power cable with separated insulation.
Rgb Led Driver Arduino
For connecting the cables, the screws of the power supply must be loosened. Then place the wires under the screws. Make sure that they are well screwed and that the cables can not come loose. Normally, these devices still have a small protective flap, so that you don’t touch them accidentally. If you want to be safe, you can also wrap insulation tape around the sensitive spots.
On the other side, there are outgoing 5V voltage (+V) and the ground connections (-V or COM). As a test, you can use a Multimeter to measure the voltage as shown here:
The output voltage of the switching power supply should be about 5V.
Wiring between Raspberry Pi, WS2801 and current source
Normally, the LED strips come with soldered plugs, which are intended for connecting several WS2801 strips. In addition, there is usually also a plug, which can be put on a Breadboard (4 connected cables). Furthermore, two additional cables for the external power connection from the LED Strip (red and black) are often used.
Since the color of the cable does not necessarily correspond to the standards, you should pay attention exactly which cable leads to which connection on the strip. Incorrect wiring on the Raspberry Pi could result in overheating or a short-circuit.
The LEDs on one meter are numbered (1 – 32). The WS2801 RGB LED strip has 2 data pins (here: CK and SI) as well as the 5V connector and GND.
If you are aware of which cable leads to which connection, we can connect it. The Raspberry Pi should be switched off and the switching power supply should not be connected to the socket. The cables are connected as follows:
WS2801 LED Stripe | Raspberry Pi | (Switching-) Power Supply |
---|---|---|
5V | -- | +V |
CK / CI | Pin 23 (SCKL) | -- |
SI / DI | Pin 19 (MOSI) | -- |
GND | Pin 6 (GND) | -V or COM |
For the connection to the switching power supply you can also use the two additional cables (if available). It is important that GND / ground is connected to both the Raspberry Pi and the external power supply. The structure now looks as follows:
Installing the Raspberry Pi WS2801 RGB LED Library
To control the LED strip we use a Python library from Adafruit. This special Raspberry Pi WS2801 library includes some functions for controlling the individual LEDs. The good thing is that each LED can be addressed individually and any RGB color is possible.
The library requires the SPI bus, which we have to activate (if not already done). We call the following:
Under “Advanced Option” there is a point for “SPI”. We enable it and exit the configuration menu.
The installation now works quite simply via the Python package manager from the normal console / terminal. Preventively, we are first updating the package sources and installing PIP (this is not included on the Raspbian Lite versions by default):
If you have a lite version or SpiDev is not installed on your system, please follow this guide to install and activate it. On newer Raspbian versions, however, it should already be pre-installed.
Spi Rgb Led Drivers For Mac
Since the given example of the developers apparently does not work on all (fresh) Raspbian versions, I have changed that and expanded.
Sample code for brightness dimming of the WS2801 LEDs
The following example can be used and extended for your own projects. Here, a few colors (rainbows) are first switched in series, whereupon the brightness of the individual colors is dimmed. For this, it must be said that the brightness of a color can also be defined with the RGB value (see RGB Color Picker for this).
So let’s create a file:
The following content should be inserted:
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 | # Simple demo of of the WS2801/SPI-like addressable RGB LED lights. importRPi.GPIO asGPIO # Import the WS2801 module. importAdafruit_GPIO.SPI asSPI PIXEL_COUNT=32 # Alternatively specify a hardware SPI connection on /dev/spidev0.0: SPI_DEVICE=0 pixels=Adafruit_WS2801.WS2801Pixels(PIXEL_COUNT,spi=SPI.SpiDev(SPI_PORT,SPI_DEVICE),gpio=GPIO) # Define the wheel function to interpolate between different hues. ifpos<85: returnAdafruit_WS2801.RGB_to_color(pos*3,255-pos*3,0) pos-=85 returnAdafruit_WS2801.RGB_to_color(255-pos*3,0,pos*3) pos-=170 returnAdafruit_WS2801.RGB_to_color(0,pos*3,255-pos*3) # Define rainbow cycle function to do a cycle of all hues. foriinrange(pixels.count()): # tricky math! we use each pixel as a fraction of the full 96-color wheel # Then add in j which makes the colors go around per pixel pixels.set_pixel(i,wheel(((i*256//pixels.count()))%256)) ifwait>0: forjinrange(256):# one cycle of all 256 colors in the wheel pixels.set_pixel(i,wheel(((i*256//pixels.count())+j)%256)) ifwait>0: forjinrange(256):# one cycle of all 256 colors in the wheel pixels.set_pixel(i,wheel(((256//pixels.count()+j))%256)) ifwait>0: forjinrange(int(256//step)): r,g,b=pixels.get_pixel_rgb(i) g=int(max(0,g-step)) pixels.set_pixel(i,Adafruit_WS2801.RGB_to_color(r,g,b)) ifwait>0: defblink_color(pixels,blink_times=5,wait=0.5,color=(255,0,0)): # blink two times, then wait forjinrange(2): pixels.set_pixel(k,Adafruit_WS2801.RGB_to_color(color[0],color[1],color[2])) time.sleep(0.08) pixels.show() time.sleep(wait) defappear_from_back(pixels,color=(255,0,0)): foriinrange(pixels.count()): pixels.clear() forkinrange(i): pixels.set_pixel(k,Adafruit_WS2801.RGB_to_color(color[0],color[1],color[2])) pixels.set_pixel(j,Adafruit_WS2801.RGB_to_color(color[0],color[1],color[2])) time.sleep(0.02) # Clear all the pixels to turn them off. pixels.show()# Make sure to call show() after changing any pixels! rainbow_cycle_successive(pixels,wait=0.1) blink_color(pixels,blink_times=1,color=(255,0,0)) blink_color(pixels,blink_times=1,color=(0,0,255)) rainbow_colors(pixels) brightness_decrease(pixels) |
In line 11 you have to specify the number of LEDs that are on the connected strip. This should be 32 meters. You can save the file with CTRL + O and close the editor with CTRL + X.
Here is the promised video with the different effects from the file:
I would be interested in what projects do you plan to do (Advent lighting, Christmas tree decoration, spice up rooms, “Infinite Mirror Table”, etc.)? Are there any requests for specific tutorials related to the Raspberry Pi WS2801B controller? I already have some ideas, but would also like to hear your opinion ?
A library for driving self-timed digital RGB/RGBW LEDs (WS2812, SK6812, NeoPixel, WS2813, etc.) using the Espressif ESP32 microcontroller's RMT output peripheral
Based upon the ESP32 WS2812 driver work by Chris Osborn
Notes
The RMT peripheral of the ESP32 is used for controlling up to 8 LED 'strands' (in whatever form factor the serially-chained LEDs are placed). These strands are independently controlled and buffered.
There are working demos for Espressif's IoT Development Framework (esp-idf) and Arduino-ESP32 core. Some demos are ONLY for the ESP IDF (demonstrating C-only techniques). Otherwise, a given demo should be exactly the same on either framework.
This library currently works well with WS2812-type and NeoPixel RGB LEDs (3 bytes of data per LED) - SK6812 RGB LEDs should work equally well. This also works fine with WS2813 (the backup channel is not used currently - tie
Backup In
to Data In
for now).This also works well with SK6812 RGBW LEDs (4 bytes of data per LED). These are similar to the WS2812 LEDs, but with a white LED present as well - keep in mind that RGBW LEDs draw a fair amount of extra power versus the usual RGB LEDs due to the added white LED element present.
Timings for a given LED type can vary even within that line: use the version variant that works best for you (see
ledParamsAll
for details).ESP-IDF build notes - Important!
The ESP-IDF demos are WIP right now (not currently buildable) and may be that way indefinitely
The ESP-IDF varies so regularly and so significantly it's more difficult to keep up with it, versus the abstracted Arduino-ESP32 interfaces. As time permits, I'm working on making it buildable with v3.2.2 and later sub-versions but it's slow going.
While the Arduino-ESP32 side is my main focus, the ESP-IDF build ought to be very similar (demo*.ino --> main.cpp, and the header and source libs aren't in their canonical locations by default). Beyond convenience, there was no real value in maintaining duplicate copies of the code and libraries as I did previously so those duplicates were removed. Also, symlinks in the repo are specifically disallowed in Arduino so that's not happening.
Please see the
sdkconfig.defaults
file for details of the defaults I use. If you run make menuconfig
or make sdkconfig
this file will be parsed for initial settings ONLY if sdkconfig
doesn't exist. However, this file will be processed every time you run make defconfig
.TODO
- API (current):
- init --> initStrands (all strands)
- setColors --> update --> updatePixels (per strand)
- (n/a) --> reset --> resetPixels (per strand)
- Future additional (class-driven):
- (n/a) --> updateTimings (for fine-tuning, debugging, or marginal/odd devices)
- (n/a) --> updateType (for fine-tuning, debugging, or marginal/odd devices)
- (n/a) --> addStrand/deleteStrand? (maybe not...)
- Other:
- Make the whole library a proper class - more robust and extensible!
- ledParams - refine and clarify
- ledParams - lower bounds? Currently bit timing constants are pre-padded +50ns
- ledParams - add a small constant string as a mapping to the name?
- Nope! C99 designator 'name' outside aggregate initializer
- ledParams - instead of bytesPerPixel, specify color format (GRBW, RGB, etc.)?
- Would have the same problem as naming...
- WS2813 - handle backup channel
- Resolve open TODOs in code
- Add more interleaved demos, and more demos in general
- Make Arduino side a true Arduino library? May not be practical.
- APA102/DotStar support?