jazzycamel / ws28128-rpi

A C++ library for driving WS2812 RGB LED's (known as 'NeoPixels' by Adafruit) directly from a Raspberry Pi with accompanying Python wrapper.
82 stars 29 forks source link

Getting the 800kbps right #1

Closed Laberbear closed 9 years ago

Laberbear commented 9 years ago

Hey Jazzycamel, I'm currenlty developing a new project which uses the WS2812b LED Strip and the Raspberry Pi. However I read pretty much everywhere, that it is not feasible to use the RasPi in this scenario since you need a very precise data clock (at 800kbps) which the Linux kernel can't guarantee.

Did you have any problems with that? And if how did you solve it in your project?

Thanks in advance, Laberbear

jazzycamel commented 9 years ago

Hi Laberbear,

You're right, if you try to bit bang the protocol using the RPi's GPIO you won't get an accurate clock, however, the Raspberry Pi has a PWM capability that can be manipulated using direct memory access (DMA) and this is how I (and others) have solved the problem. As you can see from this video (https://www.youtube.com/watch?v=_eN7SYFK4vI) it works perfectly.

Hopefully I've done the hard work for you so feel free to use this library (within the terms of the GPL) in your project. If you're doing it with C++ then you just need to include the ws2812-rpi.h header and instantiate the NeoPixel class with the numbers of LED's you want to use:

#include "ws2812-rpi.h"
int main(int argc, char **argv){
    NeoPixel *n=new NeoPixel(24);
...

You can then set individual pixel colours by calling setPixelColor():

n->setPixelColor(0, 255, 0, 0);
n->show()

This would set pixel 0 to red. You can also set the brightness of all the leds using setBrightness() to some number between 0.0 and 1.0.

If you're doing this from python then its arguably even easier. Just put the NeoPixel.so object in your project directory and the above can be done as follows:

from NeoPixel import NeoPixel
if __name__=="__main__":
    n=NeoPixel(24)
    n.setBrightness(0.5)
    n.setPixelColor(0, 255, 0, 0)
    n.show()

You'll need to run any application using this library (C++ or python) as sudo otherwise you don't have permission to access the necessary registers.

Hope this helps, good luck with your project and, if you use this code, give me a back link ;)

Laberbear commented 9 years ago

Hey, thanks for the fast reply! That solves this mystery! However this (if I understood it correctly) means that I can only output two data signals simultaneously (2 PWM Pins on the RasPiA+). I will be using 3 to 4 meters of LED Strip, do you think two or even one connection will be fast enough for a matrix (e.g. 30x6 LEDs)? Or would you use in this case a different LED Controller (like the WS2801) with a dedicated clock input?

(I realize that this question is somewhat unrelated to this rep, but I'd appreciate the help)

jazzycamel commented 9 years ago

You can run up to 450 LED's on one pin (GPIO18, Physical pin 12) using this library so you should be golden :)