Thursday, August 16, 2012

Raspberry Pi and the WS2801

Update (October 29th):
Big update here:

Update (August 19th):
 - Pixel Invaders support provided in the 1.3.0-Beta4 release of pixel controller (Here:
- Tested and working with the latest checked in version of PixelPi
- Run it like this: " sudo python --chip WS2801 --mode all_off "
- It works by sending the pixel data to the pixelPi software using a UDP network connection.  So in pixelcontroller you must setup a UDP output device with the IP set to the IP address of your Raspberry Pi board  (Keep the port set at 6803)
- The PixelPi software receives the packet and sets the pixels accordingly.

Update (august 17th):
- Just added preliminary support for pixel invaders; Neophob (from just added UDP support so the pixelcontroller software can talk to the Raspberry Pi (  Its still a work in progress but should be functional(ish)

What it does so far:
- Supports POV LED Strip (Like the original Adafruit Software)
- Now Support matrix displays (2D Panels)
- Added some test modes (fade and chase modes)
- Supports pixel remapping (by using a CSV file with the location of your pixels in the array)
- Adjustable refresh rate / chase rate
- All options selectable by command line args (no python tweaking required (hopefully))
What's up next.
 - panning on large images across the pixel array.  Ideally I was thinking it would be cool to pass in some images from and have it pan around them.
- animation support (maybe animated GIF)
- TCP/IP support (support sending display data from another PC)


Grab the python file:
git clone git://

Install Python Image library:
sudo aptitude install python-imaging-tk

pi@raspberrypi ~/git/PixelPi $ sudo python  --help
usage: [-h] [-v] [--chip {WS2801,LDP8806}] --filename FILENAME
                  --mode {strip,array,fade,chase} [--verbose]
                  [--array_width ARRAY_WIDTH] [--array_height ARRAY_HEIGHT]
                  [--spi_dev SPI_DEV_NAME] [--refresh_rate REFRESH_RATE]

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  --chip {WS2801,LDP8806}
                        Specify chip type LDP8806 or WS2801
  --filename FILENAME   Specify the image file eg: hello.png
  --mode {strip,array,fade,chase}
                        Choose the display mode, either POV strip or 2D array,
                        color, chase
  --verbose             enable verbose mode
  --array_width ARRAY_WIDTH
                        Set the X dimension of your pixel array (width)
  --array_height ARRAY_HEIGHT
                        Set the Y dimension of your pixel array (height)
  --spi_dev SPI_DEV_NAME
                        Set the SPI device descriptor
  --refresh_rate REFRESH_RATE
                        Set the refresh rate in ms (default 500ms)

Test with a fade:
sudo python  --chip WS2801 --mode fade --refresh_rate 1

Test with a chase:
sudo python  --chip WS2801 --mode chase--refresh_rate 1

Display an image (POV mode):
sudo python  --chip WS2801 --mode strip --filename test.png --refresh_rate 1

Display an image (Array mode):
sudo python  --chip WS2801 --mode array --filename test.png --refresh_rate 1

Wire up the RGB LED string:
I did something similar to this:

My starting point:


Unknown said...

This looks cool - could you explain how this can receive data from pixel invaders? Thanks!

Scott Gibson said...

I've updated the article with a description of the how the pixel invaders support works. I just tested it out and it working well.

Lorenzo said...

does it work with artnet?
sending pixelmapping packets via artnet to R-pi and display them to ws2801 would be wonderful!

LED Strip said...

Thanks for including how the pixel invaders work.

Unknown said...


I tried out Pixel Invaders and Pixel Pi today and confirmed it works.

I used latest source for both pixelinvaders and pixel pi and ran it from my hackintosh.

When pixelpi runs any mode it seems to not quite get things right as if i connect 100 LEDs up they don't all work unless I use num_leds 104 (e.g. in chase mode).

It appears there's some kind of bug somewhere. Also when using num_leds 1 in chase mode it alternates between 2 leds.

Unknown said...

Oops lol. Turns out I ordered 2x 50 LED chains but there were actually 52 LEDs in each chain and I hadn't actually counted them.

However, having 52-LEDs chains works well as when you connect 2 chains together you get a number of leds that's divisible by 8. so in pixel invaders, after a bit of faffing around in the configs I got it working with a 8 x 13 grid.

My non-default settings ( for PixelController are as follows:


#flip each second scanline

#send to this address

Anonymous said...

sudo python --mode all_off


NameError: name 'send_data_to_spi' is not defined

how come?! have i missed some steps?!

Scott Gibson said...

Regarding the NameError: name 'send_data_to_spi' is not defined error:

It looks like you may be using an old version of the software be sure to grab the latest version. They syntax has been updated:

sudo python all_on --chip WS2801 --num_leds 50

sudo python all_off --chip WS2801 --num_leds 50

Matt Bum said...

I can't seem to get the PixelInvaders part to work. Everything else works fine, but as soon as I start PixelController I get the first frame of the animation and that's it... If I quickly turn the power off and on to the LPD8806 strip it seems like the animation is playing.

Rax said...

Hey, that's cool project.
I'd like to know, if it can support multiple LED strips, if they are not chained together but are in different locations. It probably needs multiple output pins and I don't know how many RPi have. But I already have a RPi and some WS2801 LEDs and I'd like, if they can work in different locations far from eachother, on different pins.

Unknown said...

You could use i2c to spi bridge chips.

Rax said...

PixelPi outputs I2C?
Maybe there are chips that take SPI and output it to different outputs that I can configure?

All pixels to 1 input.
1-67 pixels to output 1
68-103 pixels to output 2
104-250 pixels to output 3 etc

So if I have multiple LED strips far away from eachother, I can use them in one system.

Jeremy said...

This is terrific software!! Thank you for providing it.

I made some fixes to the LPD8806 support in your latest revision (Sep 25, 2012). I don't know the first thing about using git, so I'll just post them here and you can incorporate them if you wish:

1) New users should not that the "--mode" argument has been removed. You now use the mode you want as an argument all by itself (e.g. sudo chase). This is not noted anywhere on this site or "--h" that I could find.

2) The --chip argument (line 423) was listening for LDP8806 instead of LPD8806.

3) write_stream needs to send an empty blank byte for LPD8806 such as (starting at line 177):

elif args.chip_type == "LPD8806":

4) The "all_off" function needs to send "black" colors to the LEDs. I just added a BLACK color to your color list at the top, and reused your code for "all_on" using BLACK instead of WHITE.

5) Finally some LPD8806 strips swap the blue and green colors, so I commented out the LPD8806 section of "filter_pixel" and included this version:

output_pixel[0] = gamma[input_pixel[2]]
output_pixel[1] = gamma[input_pixel[0]]
output_pixel[2] = gamma[input_pixel[1]]

Hope this is legible. I can send you the .py file if you'd like. One last note: I found the strip sometimes didn't respond after a cold RPi boot, but if I ran the chase test everything started working okay.

Scott Gibson said...

Thanks Jeremy; I'll add your changes shortly.

Anonymous said...

Scott, really nice job, i love it. I have a question scott, is posible that you can adapt glediator software as you did with pixelinvader. The gladiator software already has artnet UDP transmition, but I have tryed to connected with your pixelpi and I got some error. Well the only thing I did was sudo python pixelinvaders --chip WS2801 --refresh_rate 200 --udp-ip --udp-port 6454 .
anyhelp will be great because this software accept gif pics, thank and great job

Anonymous said...

the Glediator you can find it right here

Scott Gibson said...

So I need a bit more information on the glediator software; just need to know the protocol the remote control software uses; its probably just a little different than pixel invaders.

Luis said...

yes, well, we need to know how artnet works, Its an standard UDP protocol for multiples LED matrix

Unknown said...

Hi Jeremy.

Thanks for contributing!

It would if best if you forked the code on github. Then created branch that included the changes, ideally one branch for each feature or fix and then made a pull request for them.

This allows us all to keep track of the code changes and avoids duplication of effort.

Start your fork from here:

Github and other sites have tutorials on how to fork it and how to make pull requests.

It's a very useful skill to have as it will allow you to contribute better to any project on github, not just PixelPi

The chip name fix should be done already as I did that and made a pull request a while ago.

Unknown said...

Here you can see the chipname fix:

Here is a list of other, completed, pull requests:

Jeremy said...

Dominic: I'm afraid if I try to mess with git I'll mess something up. I'll learn it eventually but for now you guys can incorporate my fixes if you want (otherwise, at least they're here for others to follow).

As for the chipname, it is currently fixed everywhere except in line 423 (where the argument is declared). I assume you fixed this too, but maybe it was overwritten accidentally.

Unknown said...

Jerermy, it's impossible to mess anyone else's stuff up when you use git. The only thing that might happen is you mess your own git repo up. but because of the way it works you'd have one copy on github and another on your machine. Plus you can back up your own copy too.

Give it a go, you've got nothing to loose and everything to gain.

Luis said...

If someone wants to use glediator this is what I did and it works so far, I know its not the best solution. but for what I see the artnet packet send 18 extras at the start of the package, so I just took the first 18, and then I added 18 characters at the end of the package so its doesnt get alter. and it works

def pixelinvaders():
print ("Start PixelInvaders listener "+args.UDP_IP+":"+str(args.UDP_PORT))
sock = socket.socket( socket.AF_INET, # Internet
socket.SOCK_DGRAM ) # UDP
sock.bind( (args.UDP_IP,args.UDP_PORT) )
while True:
data, addr = sock.recvfrom( UDP_BUFFER_SIZE ) # blocking call

pixels_in_buffer = len(data) / PIXEL_SIZE
pixels = bytearray(pixels_in_buffer * PIXEL_SIZE)


for pixel_index in range(pixels_in_buffer):
pixel_to_adjust = bytearray(d[(pixel_index * PIXEL_SIZE):((pixel_index * PIXEL_SIZE) + PIXEL_SIZE)])

pixel_to_filter = correct_pixel_brightness(pixel_to_adjust)

pixels[((pixel_index)*PIXEL_SIZE):] = filter_pixel(pixel_to_filter[:], 1)


and this is the cmd


Scott Gibson said...

Hey all; I've added full support of artnet; E1.31 (ACN); ESP; Sandnet; Shownet using the OLA framework. See here:

Also for issues; feature requests; anything at all really add a request here:

Jeremy said...

As cool as the PixelInvaders/glediator are, I quite like the direction the original PixelPi was headed in being self-sufficient. Before everyone heads off to the new branch, could someone help me extent PixelPi to play animations? Maybe a kind of extended "array" mode that takes multiple .png arguments and loops playback using a refresh_rate? I've been trying to do this for many hours and have gotten nowhere.

Scott Gibson said...

Hey Jeremy; I would be happy to help; I don't have my pixels setup in an array so I can't test; but have you been able to use PixelPi to get a simple image displayed?

How quick to you need to change the image?

Send me a mail if you want and we can get it working scottgibson at

Jeremy said...

Email sent! Thanks, Scott.

luis said...

Hello, Jeremy I think you can do what you want with glediator but image has to be .gif, you can put any secuense and how fast you want them to change.

Jeremy said...

Thanks, Luis, but Scott added animation support to the old PixelPi branch that works great. You can see the changes on github. For my purposes I didn't want a client/server setup, but prefer to have the RPi run independently.

Anonymous said...

Hello. I made a matrix 41*17, when I tried the chase mode works perfectly, but when I try the fade mode it doesnt work properly, also with pixel invader it doesnt work properlly niether, its like the firt 8 *41 works good but the rest its randomly, I dont know it has something to do with 1024 bites. Any help will be great. thank you

Scott Gibson said...

Hey; so a 41x17 matrix (is awesome!) but will take 2091 bytes which is more than can fit in a UDP packet.

Fade should work but I haven't tested it with more than 50 pixels myself (I need to buy more)...

Does it matter what speed you try to fade at?

Perhaps you could try to add some prints in the fade function to see how much data is attempting to be send over the spi bus. Perhaps print all the bytes before they go to see what is going on.

I'll work on adding some additional debugging prints to the software so these bugs can be traced down easier....

luis said...

I have done a lot of test, and this is what happens, in the fade mode when is getting bright the problem start and when is desvaneshig it show all 697 pixels, If you have an email I can send you a little video so you can see whats going on. I will do what you said about the debug.

luis said...

I think could be a problem of voltage, I will try later today to apply more V. How can I fix the UDP transmition?

Luis said...

Well, yes Apply V to each 50 LEd Strips and it work. I am working with glediator, and it work fine, but the is a big delay between what it shows on glediator and what is happening in the LED, its like 5 seconds delay. and also it doesnt look like continues. if I just do like 200 LED its perfect, but with 615 LED show the delays. Scott, do you know if its something to do with raspberry Speed or its something that can be fixed? thank you Scott, great job.

Anonymous said...

thanks for sharing.

luis said...

Here I am posting 2 videos. the first one is a 20 by 10. the second one is 41 by 15. as you can noticed the 20*10 its smooth, the movement are continues, but the 41*15 are not. Also in the 41*15 as I said before has like 5 second delay for what it shows at the glediator and what is happening in the LED. Any suggestions will be great, I will like to fix this and put it at front of my store by December, lol. Also I am using a Power supply of 5 V 60 amps. and its apply 5V to every 100 LED (2 strip of 50 LED) note(the power supply cost $35 from aliexpress.

this is the link for the power supply

Scott Gibson said...

Hey Luis; Awesome builds. For the lag;what is likely happening is once the packet gets over 1500bytes it is fragmented. Its a tricky situation; the lag could be on the glediator side; or upon reassembly on the raspberry pi. At what frequency does glediator send the packets? Could it be flooding the link? You could experiment with different numbers of pixels to see if its a fragmentation problem (happens at once if packet size is above 1500) or if it happens at a different size.

In an effort to resolve it could you try pixelInvaders to compare the performance?

luis said...

Scott, I just did what you mentioned, so with 170 LED works perfect, with 256 LED, works ok, not perfect because sometimes has 1 sec delay. After that starts the bigs delays. I did all these test with pixelinvader. I tried with 170 LED because will send less than 512 bytes, so I think after that has some problem, for some reason the artnet protocol package just allow 170 LED per universe, may be it because of something like this, I am just guessing. Let me know if you find out something, thank you Scott.

Scott Gibson said...

Right; so Artnet is a DMX512 container essentially; each pixel takes 3 DMX channels (RGB) so the most it will put in a packet is 512/3 = 170 pixels. However pixelinvaders mode doesn't use artnet; it just packs the pixel data into a UDP packet and pixelPi receives it. I have it installed at home so I'll take a wireshark capture and see where it leads.

l;uis said...

Any news Scott?

Scott Gibson said...

I havn't had a chance to investigate; perhaps this evening.

Scott Gibson said...

Hey Luis; try increasing the UDP buffer size; not sure if it will help or not but give it a try; try changing it from 1024 to 4096

luis said...

I already did, thats how I could do the 41*15 LED, With the buffer size of 1024 its just display 341 LED. right now I have it 2048. As soon as the package go over 512 the delays start incresing. I read a lot about the UDP, and I think we can not go over 512, after that problems start, as delays and lost packages, I was thinking doing it with 4 raspberry pi, each one with 153 LED, but will increase the cost. there has to be another better way of doing it.

luis said...

I dont know if this is true. But I think the problem is with the speed of the raspberry pi processing this part or its Python that is so slow. The UDP package got in time, but as soon as goes to this part of the program start the delay. I dont know if its possible to do this pixelpi in C and I can do the test.

for pixel_index in range(pixels_in_buffer):
pixel_to_adjust = bytearray(data[(pixel_index * PIXEL_SIZE):((pixel_index * PIXEL_SIZE) + PIXEL_SIZE)])

pixel_to_filter = correct_pixel_brightness(pixel_to_adjust)



Scott Gibson said...

Yeah that array manipulation is expensive; especially in python. Though I'm not sure if its the array manipulation or the actual writing to the bus. It would be interesting to know what the RaspberryPi SPI bus is clocked at by default; maybe it could be sped up. I read here that overclocking the Pi affects the SPI bus clock so it may be worth trying if you havn't already:

You could try removing the filterPixel call; if you're using a WS2801 pixel you don't need to remap the RGB so you would just be loosing gamma correction. May be worth a try. The more I think about it though; for bit arrays writting a C version of this would be best; using ioctl on the spi bus you can set the frequency; and the code could be greatly optimized. Perhaps we should start a C implementation of the UDP Receiver / SPI bus writter.

luis said...

Scott I followed all your advices and it works. I overclocked the pi to 1000, and the performance was way better, like 1 sec delay and after I did the removing the filterPixel and it was perfect, no delay at all. but the colors we rent great. well I dont know if I did exactly what you told me in the filterpixel, this is what I did. but really great your advices, genius.

for pixel_index in range(pixels_in_buffer):
pixels[((pixel_index)*PIXEL_SIZE):] = pixel_to_adjust

Scott Gibson said...

Hey Luis; Glad its working better; seems that I should start a C version of this. Shouldn't take long I don't think.

luis said...

That will be great, because its still some delays. Amazing job with the ola, this week I will play with that. thank you

luis said...

if someone want to use glediator, this is the modified code to optimize the python code and also the RPI is overclocked to 1000. Still has one second delay from what it shows from glediator and what it shows in the matrix. This work just with ws2801 and no more than 682 pixels.
This is the CMD

python glediator --udp-ip --udp-port 6454

import sys
import RPi.GPIO as GPIO
import Image
import time
import argparse
import csv
import socket
import gc

def glediator():
spidev = file(args.spi_dev_name, "wb")
print ("Start glediator listener "+args.UDP_IP+":"+str(args.UDP_PORT))
sock = socket.socket( socket.AF_INET, # Internet
socket.SOCK_DGRAM ) # UDP
sock.bind( (args.UDP_IP,args.UDP_PORT) )
while True:
data, addr = sock.recvfrom(2048)
pixels = bytearray(len(data))
for pixel_index in range(len(data) / 3):
pixels[((pixel_index)*3):]=bytearray(d[(pixel_index * 3):((pixel_index * 3) + 3)])

gamma = bytearray(256)

parser = argparse.ArgumentParser(add_help=True,version='1.0', prog='')
subparsers = parser.add_subparsers(help='sub command help?')
common_parser = argparse.ArgumentParser(add_help=False)
common_parser.add_argument('--chip', action='store', dest='chip_type', default='WS2801', choices=['WS2801', 'LDP8806', 'LPD6803'], help='Specify chip type LPD6803, LDP8806 or WS2801')
common_parser.add_argument('--verbose', action='store_true', dest='verbose', default=True, help='enable verbose mode')
common_parser.add_argument('--spi_dev', action='store', dest='spi_dev_name', required=False, default='/dev/spidev0.0', help='Set the SPI device descriptor')
common_parser.add_argument('--refresh_rate', action='store', dest='refresh_rate', required=False, default=500, type=int, help='Set the refresh rate in ms (default 500ms)')
parser_glediator = subparsers.add_parser('glediator', parents=[common_parser], help='glediator Mode - setup pixelpi as a glediator slave')
parser_glediator.add_argument('--udp-ip', action='store', dest='UDP_IP', required=True, help='Used for glediator mode, listening address')
parser_glediator.add_argument('--udp-port', action='store', dest='UDP_PORT', required=True, default=6454, type=int, help='Used for glediator mode, listening port')

args = parser.parse_args()

heidrogen said...

I'm curious, how many of these "led pixels" can you drive per Pi?

Unknown said...

luis I wonder if you could provide more details as to how you configured glediator to work. I was able to use pixelinvader however when I run glediator the output does not appear to be the intended content (mostly off pixels with some patterns updating infrequently).

Unknown said...

my problem could be that I have not correctly configured the Artnet & TPM2.Net Patcher in Glediator, I have not yet made sense of the interface.

Anonymous said...

The best I can get with the script is random weird flashing. I can't even get all the lights to turn off. Any ideas?

Eric from ledlightinghut said...

Tested it out with the latest version of pixelPi and its working great. ( ).

Unknown said...

Does it work with Glediator?

luis said...

Hey. It has to be glediotor V1.0.6
and this is the artnet config for 41*15 Led. You have to use the code above for glediator. Let me know if it work
#Select how many artnet nodes you use for you matrix

artnet.mumber_of_nodes = 1

artnet.ip_node_0 =

artnet.number_of_universes_per_node = 1

artnet.first_universe_id_per_node = 0

artnet.number_of_pixels_per_universe = 615

artnet.pixel_mapping = 40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,286,285,284,283,282,281,280,279,278,277,276,275,274,273,272,271,270,269,268,267,266,265,264,263,262,261,260,259,258,257,256,255,254,253,252,251,250,249,248,247,246,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,368,367,366,365,364,363,362,361,360,359,358,357,356,355,354,353,352,351,350,349,348,347,346,345,344,343,342,341,340,339,338,337,336,335,334,333,332,331,330,329,328,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,450,449,448,447,446,445,444,443,442,441,440,439,438,437,436,435,434,433,432,431,430,429,428,427,426,425,424,423,422,421,420,419,418,417,416,415,414,413,412,411,410,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,532,531,530,529,528,527,526,525,524,523,522,521,520,519,518,517,516,515,514,513,512,511,510,509,508,507,506,505,504,503,502,501,500,499,498,497,496,495,494,493,492,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,614,613,612,611,610,609,608,607,606,605,604,603,602,601,600,599,598,597,596,595,594,593,592,591,590,589,588,587,586,585,584,583,582,581,580,579,578,577,576,575,574

Anonymous said...

Your forgot to mention to install cwiid
sydo apt-get install python-cwiid

Unknown said...


It seems to do not work for me.
I cloned you git repo and used
sudo python all_on --chip WS2801 --num_leds 25
to turn all leds on, but unfortunately it just turns the first led on with blue.
When I try to do fade, it just turns the first 8 leds on and not the rest.
Do you have any idea why? I use an 5v 4a power supply.

luis said...

follow this

may be the error is the command

sudo python glediator --udp-ip --udp-port 6454

Unknown said...

I run Glediator v1.0.6.
My pixel array is x = 19/y = 14 and starts at the lower left.
I am not sure how to map the pixels. Any hints would be awesome :)

Anonymous said...

so far I have all the function in PixelPi work except for pan and array; the main reason i want to use PixelPi.

When i tell it to run array or pan it says it's displaying but non of my pixels are on, even using the test.png.

is there an extra program that i need to install to get this to work?

Anonymous said...

Hi there, Could someone please explain how I could edit the chase part of the script so it turned on each LED one by one and left them lit?

Xydrail said...

Hey, i have some problems setting your program up.

sudo python all_off --chip LPD6803 --num_leds 36

Traceback (most recent call last):
File "", line 12, in
import Image
ImportError: No module named Image

I guessed it has something to do with PIL, so i set up Pillow via pip install and changed the code in line 11 to

"from PIL import Image"

Now i get

sudo python all_off --chip LPD6803 --num_leds 36
Turning all LEDs Off

but they are still white.

I connected them via sclk and mosi on the raspberry

Unknown said...

Thanks Xydrail, I was stuck with the same error... I edited and change into from PIL import Image, and now it doesn't crash anymore

Sharkyenergy said...

Hello! Thank you for providing this... Unfortunately it is not working for me. Only the first 5 leds leds light up and they are displaying something random... They just show messy things. (With any test command). I am on a raspberry pi 1 and using ws2801 leds

Could you please tell me what is going on?