On the software front, we started with “Occidentalis,” the Adafruit Raspberry Pi Educational Linux Distro. This has a few features baked in that make this project a lot simpler, including hardware SPI support…it’s super fast and easy, with no bitbang kludges required. Alternatively you can install SPI support yourself
Our light painting script relies on the Python Image module, which is not installed by default. With your Raspberry Pi connected to the internet, log in and type:
sudo apt-get install python-imaging
Occidentalis also has sshd built in, making it easy to get images from a desktop machine to the Raspberry Pi. For example, in a Terminal window on my Mac I could type:
scp image.png [email protected]:
Or use a secure FTP client:
#!/usr/bin/python # Light painting / POV demo for Raspberry Pi using # Adafruit Digital Addressable RGB LED flex strip. # ----> http://adafruit.com/products/306 import RPi.GPIO as GPIO, Image, time # Configurable values filename = "hello.png" dev = "/dev/spidev0.0" # Open SPI device, load image in RGB format and get dimensions: spidev = file(dev, "wb") print "Loading..." img = Image.open(filename).convert("RGB") pixels = img.load() width = img.size[0] height = img.size[1] print "%dx%d pixels" % img.size # To do: add resize here if image is not desired height # Calculate gamma correction table. This includes # LPD8806-specific conversion (7-bit color w/high bit set). gamma = bytearray(256) for i in range(256): gamma[i] = 0x80 | int(pow(float(i) / 255.0, 2.5) * 127.0 + 0.5) # Create list of bytearrays, one for each column of image. # R, G, B byte per pixel, plus extra '0' byte at end for latch. print "Allocating..." column = [0 for x in range(width)] for x in range(width): column[x] = bytearray(height * 3 + 1) # Convert 8-bit RGB image into column-wise GRB bytearray list. print "Converting..." for x in range(width): for y in range(height): value = pixels[x, y] y3 = y * 3 column[x][y3] = gamma[value[1]] column[x][y3 + 1] = gamma[value[0]] column[x][y3 + 2] = gamma[value[2]] # Then it's a trivial matter of writing each column to the SPI port. print "Displaying..." while True: for x in range(width): spidev.write(column[x]) spidev.flush() time.sleep(0.001) time.sleep(0.5)
The script needs to be run as “root” because it accesses the GPIO hardware, i.e.:
sudo python lightpaint.py
After opening the SPI device (for communicating with the LED strip), the script then loads an image using the Python Image module, converting it to RGB format if necessary. As an interpreted language, Python isn’t always the quickest thing…rather than repeatedly process each row or column of an image on the fly, the entire image is pre-processed once from the native RGB format into the hardware-specific format required of the LED strip, held in a list of bytearrays. We can then quickly dump each of these arrays directly to the SPI port without any further work. Decoding and holding all this intermediate data would be inconceivable on Arduino!
The software is smart enough that it will use the height of the image as the number of pixels to address. So if you have 64 pixels, make sure your images are 64 pixels tall, etc!
This runs in an infinite loop. Hit CTRL+C or locate and kill the process to make it stop.
Common causes, in decreasing order of likelihood:
- The clock and data lines might be switched. Try the other way, and if no difference, put them back and double-check against the wiring diagram and the pin labels on the strip.
- Might’ve accidentally connected to the output end of the strip rather than the input. Make sure you soldered to “CI” and “DI,” not “CO” and “DO.” Some strips may have arrows showing the data direction from in to out.
- Did you remember the ground wire between the LED strip and Raspberry Pi?
- You might need a logic-level shifter, explained a bit on the “Hardware” page.
Text editor powered by tinymce.