Skip to content

fishkingsin/elinux-lpd8806

Repository files navigation

Total Control Lighting (p9813) Embedded Linux Library

Copyright 2012 Christopher De Vries

www.idolstarastronomer.com

LPD8806 Embedded Linux Library

Copyright 2013 James Kong

www.fishkingsin.com

INTRODUCTION

This library is modified from elinux-tcl and designed to help you get started using the LPD8806 LED Strip on your Raspberry Pi. This library should work on any linux platform in which the spidev kernel module has been included.

BACKGROUND

Thanks to Adafruit Reversed Enginnering and their LPD8806 Python Library They provide very good explaination of how the LPD8806 chip is doing and the protocol

The-LPD8806-protocol-for-Adafruit-RGB-LED-Strips provide and explaination of the protocol

  • When it receives a zero byte, it resets its byteCount to 0, and writes a zero byte on the output.
  • When it receives a byte with the high bit set (ie ORed with 0x80) and its byteCount < 6, it uses the lower 7 bits of the byte to set the output of one of the PWM outputs. It then increments byteCount to move to the next PWM output.
  • If byteCount == 6, it just sends the byte to the output.

When these chips are chained together, with the inputs of the second chip connected to the output of the first chip, they are quite easy to use. You just send a total of 3 bytes per LED, and bytes 1-3 go to the first one, 4-6 to the second, and so on. The byte order is not GRB instead of RGB, which is presumably done so that the PCB layout is simpler.

The color value is 7 bits per color, for 128 * 128 * 128 = 2,097,152 colors.

finally set 4 zero byte and the end of the buffer which mean length_of_led x 3 + 4 is the length of your total buffer size

HARDWARE

The LPD8806 strands, sold by http://www.adafruit.com/products/306, have 4 wires running from pixel to pixel. These wires are color coded in the following way:

GND: Ground DI: Data CI: Clock +5V: Vcc (+5 to +6.5 V)

Each pixel has an input set of wires and an output set. Usually there is an arrow indicating the direction on the casing of the LED/chip unit.

The wire coloring on the connector is slightly different:

GND: Ground DO: Data CO: Clock +5V: Vcc (+5 to +6.5 V)

It is useful, though not required, to purchase the "T-connectors" sold at coolneon.com. The T-connectors pass through the Data and Clock lines, but splice the Vcc and Ground lines to a 2.5mm center positive barrel connector. We typically find that we provide power by using a T-connector every 100 pixels or so (depending on the application).

RASPBERRY PI CONNECTIONS

On the Raspberry PI the following pins are configured for SPI:

Pin 19: Data out (SP10 MOSI) Pin 23: Clock out (SP10 SCLK)

You should also hook up a ground wire from the pixels and the power supply for the pixels and connect it to Pin 6 so the Raspberry Pi and the pixels share a common ground. A typical wiring diagram is shown below:

+-----------------------------+
|                         5 V +---------+
| Pixel Power Source          |         |
|                         GND +----+    |
+-----------------------------+    |    |
+-----------------------------+    |    |     +-----------------------------+
+                      Pin 4  +----|----+-----+ 5V+                          |
+                      Pin 6  +----+----------+ GND        lpd8806 Pixel     |
+ Raspberry Pi         Pin 19 +---------------+ Clock                        |
+                      Pin 23 +---------------+ Data                         |
+-----------------------------+               +-----------------------------+

LIBRARY

This library is written in ANSI C, and I will demonstrate how to use it by creating a simple program below. To use the C library, you first need to include several header files, including "lpd8806led.h" for this library, and "fcntl.h" and "unistd.h" for low level I/O. To run the examples below you will also need to include "stdio.h". Include all the header files like so:

#include "lpd8806led.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

Within the program, you will want to open the spidev device using low-level I/O, and initiate the SPI bus. In this example I use "/dev/spidev2.0" as the device, which is typical on the BeagleBone. For the Raspberry Pi this is typically "/dev/spidev0.0". Initialization can be accomplished using the code below.

int fd;  /* SPI device file descriptor */

/* Open SPI device */
fd = open("/dev/spidev2.0",O_WRONLY);
if(fd<0) {
    /* Open failed */
    fprintf(stderr, "Error: SPI device open failed.\n");
    exit(1);
}

/* Initialize SPI bus for lpd8806 pixels */
if(spi_init(fd)<0) {
    /* Initialization failed */
    fprintf(stderr, "Unable to initialize SPI bus.\n");
    exit(1);
}

Next create a buffer for your pixel color and flag values. I will assume there are 50 LEDs in our Total Control Lighting strand for the example below.

const int leds = 50; /* 50 LEDs in the strand */
lpd8806_buffer buf;      /* Memory buffer for pixel values */

/* Allocate memory for the pixel buffer and initialize it */
if(lpd8806_init(&buf,leds)<0) {
    /* Memory allocation failed */
    fprintf(stderr, "Insufficient memory for pixel buffer.\n");
    exit(1);
}

for LPD8806 you only use "write_gamma_color" to write to gamma corrected buffer to set you color to 128-255 value "write_color" dosent work for LPD8806 ,because it only read 7bits from 128-255 to represent each color

set_gamma(2.5,2.5,2.5);
write_gamma_color(&buf.pixels[24],0,127,0);

Finally, you must send the data over the SPI bus to the pixels. To do this you use the function "send_buffer", which takes two arguments. The file descriptor and a pointer to the lpd8806_buffer structure. The send_buffer function will always either send all the data in the buffer (and return the number of bytes sent) or return a negative integer when an error occurs. Sending the data can in the lpd8806_buffer buf can be accomplished with the code below.

/* Send the data to the lpd8806 lighting strand */
if(send_buffer(fd,&buf)<0) {
    fprintf(stderr, "Error sending data.\n");
    exit(1);
}

When you are finished using the pixels you should free up the allocated memory in the lpd8806_buffer structure and close the file description. This can be accomplished with the code below.

/* Free the pixel buffer */
lpd8806_free(&buf);

/* Close the SPI device */
close(fd);

COMPILING

The code compiles with the gcc compiler available on each platform. Note that you must include the math library ( -lm ) when compiling because the gamma correction subroutine makes use of it. Feel free to look at the included Makefile for information about compiling the code. You must compile the following files along with your source code:

lpd8806led.h - The library header file. lpd8806led.c - The library source code.

ADDITIONAL RESOURCES

Additional documentation for the individual functions can be found in the lpd8806led.h header file. There are also a few sample programs:

  1. simple_example.c - This runs through a simple example setting the lights to be red, green, and blue and cycling through those colors with one color change a second.

  2. blink_test.c - This is a code which blinks random gamma corrected colors at random intervals all along the strand.

  3. lpd8806_speedtest.c - This sample program sends 10,000 images (of a single blue moving along a strand) to a strand of 1,250 pixels as fast as it can. It measures the time elapsed and calculates the number of frames per second.

Version history

Version 0.1 (Date):20130321

Bitdeli Badge

Releases

No releases published

Packages

 
 
 

Languages