Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 1768 → Rev 1769

/Digital_RGB_LED_Stripes/tags/Strip_Test/Sequences.ino
0,0 → 1,507
//*******************************************************************
// Definition of color pattern and sequences
//*******************************************************************
void flashingCircle( uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
uint8_t ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8;
for (uint8_t j=0; j< riggerSize ; j++){
strip.setPixelColor(j, r, g, b, 1, 1, 1, 1, 1, 1, 1, 1);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1);
strip.show();
delay ( wait/2 );
}
}
 
void flashingCircleRev( uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
uint8_t ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8;
for (uint8_t j = riggerSize; j > 0 ; j--){
strip.setPixelColor(j-1, r, g, b, 1, 1, 1, 1, 1, 1, 1, 1);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1);
strip.show();
delay ( wait/2 );
}
}
 
void spiral( uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
uint8_t ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8;
for (uint8_t j=0; j< riggerSize ; j++){
for (uint8_t i=1; i<= rigger ; i++){
if (i == 1){
strip.setPixelColor(j, r, g, b, 1, 0, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 2){
strip.setPixelColor(j, r, g, b, 0, 1, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 3){
strip.setPixelColor(j, r, g, b, 0, 0, 1, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 4){
strip.setPixelColor(j, r, g, b, 0, 0, 0, 1, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 5){
strip.setPixelColor(j, r, g, b, 0, 0, 0, 0, 1, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 6){
strip.setPixelColor(j, r, g, b, 0, 0, 0, 0, 0, 1, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
strip.show();
delay ( wait );
}
if (i == 7){
strip.setPixelColor(j, r, g, b, 0, 0, 0, 0, 0, 0, 1, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
strip.show();
delay ( wait );
}
if (i == 8){
strip.setPixelColor(j, r, g, b, 0, 0, 0, 0, 0, 0, 0, 1);
strip.show();
delay ( wait );
strip.setPixelColor(j, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
strip.show();
delay ( wait );
}
}
}
}
 
void spiralRev( uint8_t r, uint8_t g, uint8_t b, uint8_t wait) {
uint8_t ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8;
for (uint8_t j = riggerSize; j > 0 ; j--){
for (uint8_t i = 1 ; i <= rigger ; i++){
if (i == 1){
strip.setPixelColor(j-1, r, g, b, 1, 0, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 2){
strip.setPixelColor(j-1, r, g, b, 0, 1, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 3){
strip.setPixelColor(j-1, r, g, b, 0, 0, 1, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 4){
strip.setPixelColor(j-1, r, g, b, 0, 0, 0, 1, 0, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 5){
strip.setPixelColor(j-1, r, g, b, 0, 0, 0, 0, 1, 0, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
strip.show();
delay ( wait );
}
if (i == 6){
strip.setPixelColor(j-1, r, g, b, 0, 0, 0, 0, 0, 1, 0, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
strip.show();
delay ( wait );
}
if (i == 7){
strip.setPixelColor(j-1, r, g, b, 0, 0, 0, 0, 0, 0, 1, 0);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
strip.show();
delay ( wait );
}
if (i == 8){
strip.setPixelColor(j-1, r, g, b, 0, 0, 0, 0, 0, 0, 0, 1);
strip.show();
delay ( wait );
strip.setPixelColor(j-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
strip.show();
delay ( wait );
}
}
}
}
 
 
// Fade In
void fadein( uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
 
uint8_t r2, g2, b2;
 
for (uint8_t j = 127; j > 10; j--){
uint8_t rh = r-(j*r/127);
if((r || rh) && rh <= r) r2 = rh;
if(rh > r) r2 = r;
if(r == 0) r2 = 0;
uint8_t gh = g-(j*g/127);
if((g || gh) && gh <= g) g2 = gh;
if(gh > g) g2 = g;
if(g == 0) g2 = 0;
uint8_t bh = b-(j*b/127);
if((b || bh) && bh <= b) b2 = bh;
if(bh > b) b2 = b;
if(b == 0) b2 = 0;
for(uint8_t i=0; i<riggerSize; i++) {
strip.setPixelColor(i, r2, g2, b2, ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
}
}
 
// Fade Out
void fadeout(uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
 
uint8_t r2, g2, b2;
 
for (uint8_t j = 10; j < 127; j++){
uint8_t rh = r-(j*r/127);
if((r || 0) && rh < r) r2 = rh;
if(r == 0) r2 = 0;
uint8_t gh = g-(j*g/127);
if((g || 0) && gh < g) g2 = gh;
if(g == 0) g2 = 0;
uint8_t bh = b-(j*b/127);
if((b || 0) && bh < b) b2 = bh;
if(b == 0) b2 = 0;
for(int i=0; i<riggerSize; i++) {
strip.setPixelColor(i, r2, g2, b2,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
}
for(int i=0; i<riggerSize; i++) {
strip.setPixelColor(i, 0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
}
 
// Flashing Light
void flashLight(uint8_t wait, uint8_t cyl, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
 
for (int j=0; j < cyl; j++) {
for (int x = 0; x<2; x++){
for (int i = 0; i < riggerSize; i++){
strip.setPixelColor(i, 0, 127,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
for (int i = 0; i < riggerSize; i++){
strip.setPixelColor(i, 0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
}
}
}
 
// Two colors flashing on left and right.
void police(uint8_t wait, uint8_t cyl, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
 
for (int j=0; j < cyl; j++) {
for (int x = 0; x<2; x++){
for (int i = 0; i < (riggerSize/2); i++){
strip.setPixelColor(i, 127,0,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
for (int i = 0; i < (riggerSize/2); i++){
strip.setPixelColor(i, 0, 0,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
}
for (int x = 0; x<2; x++){
for (int i = (riggerSize/2); i < riggerSize; i++){
strip.setPixelColor(i, 0, 0,127,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
for (int i = (riggerSize/2); i < riggerSize; i++){
strip.setPixelColor(i, 0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
}
}
}
 
// Cycle through two colors, equally spaced around the Strip
void circlinglights(uint8_t wait, uint8_t cyl, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
uint16_t b=0;
uint16_t r=riggerSize-1;
 
for (int j=0; j < stripSize * cyl; j++) {
strip.setPixelColor(b%riggerSize,0,2,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor((b+1)%riggerSize,1,16,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor((b+2)%riggerSize,0,55,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor((b+3)%riggerSize,0,127,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor(r%riggerSize,2,1,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor((r+riggerSize-1)%riggerSize,16,3,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor((r+riggerSize-2)%riggerSize,55,15,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor((r+riggerSize-3)%riggerSize,127,20,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.show();
delay(wait);
strip.setPixelColor(b%riggerSize,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor(r%riggerSize,0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.show();
if (b++==riggerSize) b=0;
if (r--==0) r=riggerSize;
strip.show(); // write all the pixels out
}
clearstrip ();
}
 
 
// fill strip dots by dot with selected color
void colorWipe( uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
int i;
 
for (i=0; i < riggerSize; i++) {
strip.setPixelColor(i , r, g, b ,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.show();
delay(wait);
}
}
 
// Chase a dot down the strip
// good for testing purposes
void colorChase( uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
int pix;
 
clearstrip ();
 
for (pix=0; pix < riggerSize; pix++) {
strip.setPixelColor(pix , r, g, b ,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8); // set one pixel
strip.show(); // refresh strip display
delay(wait); // hold image for a moment
strip.setPixelColor(pix,0,0, 0, ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8); // erase pixel (but don't refresh yet)
}
strip.show(); // for last erased pixel
}
 
// Chase a dot reverse up the strip
// good for testing purposes
void colorChaseRev( uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
int i;
 
clearstrip ();
 
for (i=riggerSize-1; i >= 0; i--) {
strip.setPixelColor(i, r, g, b ,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8); // set one pixel
strip.show(); // refresh strip display
delay(wait); // hold image for a moment
strip.setPixelColor(i,0,0, 0,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8); // erase pixel (but don't refresh yet)
}
strip.show(); // for last erased pixel
}
 
// An "ordered dither" fills every pixel in a sequence that looks
// sparkly and almost random, but actually follows a specific order.
void dither(uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
 
// Determine highest bit needed to represent pixel index
int hiBit = 0;
int n = (riggerSize/3)+1;
for(int bit=1; bit < 0x8000; bit <<= 1) {
if(n & bit) hiBit = bit;
}
 
int bit, reverse;
for(int i=0; i<(hiBit << 1); i++) {
// Reverse the bits in i to create ordered dither:
reverse = 0;
for(bit=1; bit <= hiBit; bit <<= 1) {
reverse <<= 1;
if(i & bit) reverse |= 1;
}
strip.setPixelColor(reverse, r,g,b,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.show();
delay(wait);
}
delay(250); // Hold image for 1/4 sec
}
 
// "Larson scanner" = Cylon/KITT bouncing light effect
void scanner(uint8_t r, uint8_t g, uint8_t b, uint8_t wait, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
int i, j, pos, dir;
 
pos = 1;
dir = 1;
 
for(i=1; i<(riggerSize)*8; i++) {
strip.setPixelColor(pos - 1, strip.Color(r/8, g/8, b/8),ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor(pos, strip.Color(r, g, b),ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
strip.setPixelColor(pos + 1, strip.Color(r/8, g/8, b/8),ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
 
strip.show();
delay(wait);
// If we wanted to be sneaky we could erase just the tail end
// pixel, but it's much easier just to erase the whole thing
// and draw a new one next time.
for(j=-1; j<= 1; j++) strip.setPixelColor(pos+j, strip.Color(0,0,0),ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8); // Bounce off ends of strip
 
pos += dir;
if(pos < 1) {
pos = 1;
dir = -dir;
} else if(pos >= riggerSize-2) {
pos = riggerSize - 2;
dir = -dir;
}
}
}
 
// Sine wave effect
#define PI 3.14159265
void wave( uint8_t r, uint8_t g, uint8_t b, uint8_t wait, int stp, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
float y;
uint8_t r2, g2, b2;
 
for(int x=0; x<(riggerSize*5); x++)
{
for(int i=0; i<riggerSize; i++) {
y = sin(PI * (float)stp * (float)(x + i) / (float)riggerSize);
if(y >= 0.0) {
// Peaks of sine wave are white
y = 1.0 - y; // Translate Y to 0.0 (top) to 1.0 (center)
r2 = 127 - (byte)((float)(127 - r) * y);
g2 = 127 - (byte)((float)(127 - g) * y);
b2 = 127 - (byte)((float)(127 - b) * y);
} else {
// Troughs of sine wave are black
y += 1.0; // Translate Y to 0.0 (bottom) to 1.0 (center)
r2 = (byte)((float)r * y);
g2 = (byte)((float)g * y);
b2 = (byte)((float)b * y);
}
strip.setPixelColor(i, r2, g2, b2,ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show();
delay(wait);
}
}
 
void rainbowCycle(uint8_t wait, uint8_t cyl, uint8_t ri1, uint8_t ri2, uint8_t ri3, uint8_t ri4, uint8_t ri5, uint8_t ri6, uint8_t ri7, uint8_t ri8) {
uint16_t i, j;
 
for (j=0; j < 384 * cyl; j++) { // 5 cycles of all 384 colors in the wheel
for (i=0; i < riggerSize; i++) {
// tricky math! we use each pixel as a fraction of the full 384-color
// wheel (thats the i / strip.numPixels() part)
// Then add in j which makes the colors go around per pixel
// the % 384 is to make the wheel cycle around
strip.setPixelColor(i, Wheel(((i * 384 / riggerSize) + j) % 384),ri1, ri2, ri3, ri4, ri5, ri6, ri7, ri8);
}
strip.show(); // write all the pixels out
delay(wait);
}
}
/* Helper functions */
 
//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g - b - back to r
 
uint32_t Wheel(uint16_t WheelPos)
{
byte r, g, b;
switch(WheelPos / 128)
{
case 0:
r = 127 - WheelPos % 128; // red down
g = WheelPos % 128; // green up
b = 0; // blue off
break;
case 1:
g = 127 - WheelPos % 128; // green down
b = WheelPos % 128; // blue up
r = 0; // red off
break;
case 2:
b = 127 - WheelPos % 128; // blue down
r = WheelPos % 128; // red up
g = 0; // green off
break;
}
return(strip.Color(r,g,b));
}
 
// Clear strip
void clearstrip (){
for (int i=0; i < stripSize; i++) {
strip.setPixelColor(i, 0);
}
}
 
// Set single LED
void setLED(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t r1, uint8_t r2, uint8_t r3, uint8_t r4, uint8_t r5, uint8_t r6, uint8_t r7, uint8_t r8){
n=n-1;
strip.setPixelColor(n, strip.Color(r, g, b), r1, r2, r3, r4, r5, r6, r7, r8);
}
 
/Digital_RGB_LED_Stripes/tags/Strip_Test/Strip_Test.ino
0,0 → 1,70
#include "LPD8806_kopterlight.h"
#include "SPI.h"
 
/*****************************************************************************/
// Kopter light control on LPD8806-based RGB LED Modules in a strip!
/*****************************************************************************/
 
/*****************************************************************************/
// To be changed according to your setup
// The LED strips are 40 LEDs per meter but you can extend/cut the strip
 
#define rigger 1 // number of rigger (default: 4)
#define riggerSize 201 // Pixels / LEDs per rigger (default: 10)
 
#define stripSize (riggerSize*rigger)
 
// Use only if Hardware SPI is not possible
// int dataPin = 3; // Software SPI Data Pin
// int clockPin = 2; // Software SPI Clock Pin
// Soft SPI
// LPD8806 strip = LPD8806(stripSize, dataPin, clockPin, rigger);
 
// HW SPI
// on Arduino 168/328 thats data = 11, and clock = pin 13
LPD8806 strip = LPD8806(stripSize, rigger);
 
/*****************************************************************************/
//Do not change or remove these!
void setup() {
// Start up the LED strip
strip.begin();
// Update the strip, to start they are all 'off'
strip.show();
}
 
/*****************************************************************************/
// Space for your light effects:
/*****************************************************************************/
// Only inside Void Loop() you are allowed to design your light effects !!
// ( If you like to program a new pattern or sequences, refer to sequences.ino)
/*****************************************************************************/
// Parameter: Colors are defined by the additive RGB color model.
// n = LED No on rigger
// r = red ( max. 127)
// g = green ( max. 127)
// b = blue ( max. 127)
// dly = delay ( typical: 10 - 50 )
// cyl = cyles ( how many times this sequence will repeat )
// riX = rigger to set pixel / to show sequence on x= number of rigger
/*****************************************************************************/
void loop() {
 
clearstrip ();
fadein(90,0,0,6,1,0,0,0,0,0,0,0); // red
fadeout(90,0,0,6,1,0,0,0,0,0,0,0); // red
fadein(0,90,0,6,1,0,0,0,0,0,0,0); // green
fadeout(0,90,0,6,1,0,0,0,0,0,0,0); // green
fadein(0,0,90,6,1,0,0,0,0,0,0,0); // blue
fadeout(0,0,90,6,1,0,0,0,0,0,0,0); // blue
colorChaseRev(127,0,0,50,1,0,0,0,0,0,0,0); // red
colorChase(0,127,0,50,1,0,0,0,0,0,0,0); // green
colorChaseRev(0,0,127,50,1,0,0,0,0,0,0,0); // blue
 
}
/*****************************************************************************/
 
 
 
 
/Digital_RGB_LED_Stripes/tags/Strip_Test/Strip_Test.zip
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/Digital_RGB_LED_Stripes/tags/Strip_Test/lib/LPD8806_kopterlight.cpp
0,0 → 1,311
#include "SPI.h"
#include "LPD8806_kopterlight.h"
 
// Arduino library to control LPD8806-based RGB LED Strips
// (c) Adafruit industries
// MIT license
 
/*****************************************************************************/
// This library has been modified to fix the red and green issue with the stripes
// used by "MikroKopter-Forum" Users, because the design of these stripes is
// different and red and green are inverted !!
// Additionally this library has been modified and extended to provide light
// sequence requirements on multikopter.
// Magomora
/*****************************************************************************/
 
// Constructor for use with hardware SPI (specific clock/data pins):
LPD8806::LPD8806(uint16_t n, uint8_t rig) {
pixels = NULL;
begun = false;
updateLength(n);
updatePins();
rigger = rig;
}
 
// Constructor for use with arbitrary clock/data pins:
LPD8806::LPD8806(uint16_t n, uint8_t dpin, uint8_t cpin, uint8_t rig) {
pixels = NULL;
begun = false;
updateLength(n);
updatePins(dpin, cpin);
rigger = rig;
}
 
// via Michael Vogt/neophob: empty constructor is used when strip length
// isn't known at compile-time; situations where program config might be
// read from internal flash memory or an SD card, or arrive via serial
// command. If using this constructor, MUST follow up with updateLength()
// and updatePins() to establish the strip length and output pins!
LPD8806::LPD8806(void) {
numLEDs = 0;
pixels = NULL;
begun = false;
updatePins(); // Must assume hardware SPI until pins are set
}
 
// Activate hard/soft SPI as appropriate:
void LPD8806::begin(void) {
if(hardwareSPI == true) startSPI();
else startBitbang();
begun = true;
}
 
// Change pin assignments post-constructor, switching to hardware SPI:
void LPD8806::updatePins(void) {
hardwareSPI = true;
datapin = clkpin = 0;
// If begin() was previously invoked, init the SPI hardware now:
if(begun == true) startSPI();
// Otherwise, SPI is NOT initted until begin() is explicitly called.
 
// Note: any prior clock/data pin directions are left as-is and are
// NOT restored as inputs!
}
 
// Change pin assignments post-constructor, using arbitrary pins:
void LPD8806::updatePins(uint8_t dpin, uint8_t cpin) {
 
datapin = dpin;
clkpin = cpin;
clkport = portOutputRegister(digitalPinToPort(cpin));
clkpinmask = digitalPinToBitMask(cpin);
dataport = portOutputRegister(digitalPinToPort(dpin));
datapinmask = digitalPinToBitMask(dpin);
 
if(begun == true) { // If begin() was previously invoked...
// If previously using hardware SPI, turn that off:
if(hardwareSPI == true) SPI.end();
startBitbang(); // Regardless, now enable 'soft' SPI outputs
} // Otherwise, pins are not set to outputs until begin() is called.
 
// Note: any prior clock/data pin directions are left as-is and are
// NOT restored as inputs!
 
hardwareSPI = false;
}
 
// Enable SPI hardware and set up protocol details:
void LPD8806::startSPI(void) {
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
// SPI.setClockDivider(SPI_CLOCK_DIV8); // 2 MHz
SPI.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz
// SPI bus is run at 2MHz. Although the LPD8806 should, in theory,
// work up to 20MHz, the unshielded wiring from the Arduino is more
// susceptible to interference. Experiment and see what you get.
 
SPDR = 0; // 'Prime' the SPI bus with initial latch (no wait)
}
 
// Enable software SPI pins and issue initial latch:
void LPD8806::startBitbang() {
pinMode(datapin, OUTPUT);
pinMode(clkpin , OUTPUT);
*dataport &= ~datapinmask; // Data is held low throughout (latch = 0)
for(uint8_t i = 8; i>0; i--) {
*clkport |= clkpinmask;
*clkport &= ~clkpinmask;
}
}
 
// Change strip length (see notes with empty constructor, above):
void LPD8806::updateLength(uint16_t n) {
if(pixels != NULL) free(pixels); // Free existing data (if any)
numLEDs = n;
n *= 3; // 3 bytes per pixel
if(NULL != (pixels = (uint8_t *)malloc(n + 1))) { // Alloc new data
memset(pixels, 0x80, n); // Init to RGB 'off' state
pixels[n] = 0; // Last byte is always zero for latch
} else numLEDs = 0; // else malloc failed
// 'begun' state does not change -- pins retain prior modes
}
 
uint16_t LPD8806::numPixels(void) {
return numLEDs;
}
 
// This is how data is pushed to the strip. Unfortunately, the company
// that makes the chip didnt release the protocol document or you need
// to sign an NDA or something stupid like that, but we reverse engineered
// this from a strip controller and it seems to work very nicely!
void LPD8806::show(void) {
uint16_t i, n3 = numLEDs * 3 + 1; // 3 bytes per LED + 2 for latch
// write 24 bits per pixel
if (hardwareSPI) {
for (i=0; i<n3; i++ ) {
while(!(SPSR & (1<<SPIF))); // Wait for prior byte out
SPDR = pixels[i]; // Issue new byte
}
while(!(SPSR & (1<<SPIF))); // Wait for prior byte out
SPDR = 0; // Issue new byte
} else {
for (i=0; i<n3; i++ ) {
for (uint8_t bit=0x80; bit; bit >>= 1) {
if(pixels[i] & bit) *dataport |= datapinmask;
else *dataport &= ~datapinmask;
*clkport |= clkpinmask;
*clkport &= ~clkpinmask;
}
}
for (uint8_t bit=0x80; bit; bit >>= 1) {
if(pixels[i] & bit) *dataport |= datapinmask;
else *dataport &= ~datapinmask;
*clkport |= clkpinmask;
*clkport &= ~clkpinmask;
}
}
}
 
// Convert separate R,G,B into combined 32-bit GRB color:
uint32_t LPD8806::Color(byte g, byte r, byte b) {
return 0x808080 | ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b;
}
 
// Set pixel color from separate 7-bit R, G, B components:
// All rigger in parallel
void LPD8806::setPixelColor(uint16_t n, uint8_t g, uint8_t r, uint8_t b) {
uint8_t i;
for (i=1; i<rigger; i++){
if(n < numLEDs) { // Arrays are 0-indexed, thus NOT '<='
uint8_t *p = &pixels[n * 3];
*p++ = g | 0x80; // LPD8806 color order is GRB,
*p++ = r | 0x80; // not the more common RGB,
*p++ = b | 0x80; // so the order here is intentional; don't "fix"
}
n = n+(numLEDs/rigger);
}
}
 
// Set pixel color from separate 7-bit R, G, B components:
// Only on selected rigger
void LPD8806::setPixelColor(uint16_t n, uint8_t g, uint8_t r, uint8_t b, uint8_t r1, uint8_t r2, uint8_t r3, uint8_t r4, uint8_t r5, uint8_t r6, uint8_t r7, uint8_t r8) {
int i;
int pix;
uint16_t z;
 
// Select rigger to set LEDs
for (i=1; i<=rigger; i++){
if (i == 1 && r1 == 1){
z = ((numLEDs/rigger)*1)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 2 && r2 == 1){
z = ((numLEDs/rigger)*2)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 3 && r3 == 1){
z = ((numLEDs/rigger)*3)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 4 && r4 == 1){
z = ((numLEDs/rigger)*4)+(n-(numLEDs/rigger));
pix = 1;
}
if (i == 5 && r5 == 1){
z = ((numLEDs/rigger)*5)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 6 && r6 == 1){
z = ((numLEDs/rigger)*6)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 7 && r7 == 1){
z = ((numLEDs/rigger)*7)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 8 && r8 == 1){
z = ((numLEDs/rigger)*8)+n-(numLEDs/rigger);
pix = 1;
}
if((pix == 1) && (z < numLEDs)) { // Arrays are 0-indexed, thus NOT '<='
uint8_t *p = &pixels[z * 3];
*p++ = g | 0x80; // LPD8806 color order is GRB,
*p++ = r | 0x80; // not the more common RGB,
*p++ = b | 0x80; // so the order here is intentional; don't "fix"
}
pix = 0;
}
}
 
// Set pixel color from 'packed' 32-bit RGB value:
// All rigger in parallel
void LPD8806::setPixelColor(uint16_t n, uint32_t c) {
uint8_t i;
for (i=0; i<rigger; i++){
if(n < numLEDs) { // Arrays are 0-indexed, thus NOT '<='
uint8_t *p = &pixels[n * 3];
*p++ = (c >> 16) | 0x80;
*p++ = (c >> 8) | 0x80;
*p++ = c | 0x80;
}
n = n+(numLEDs/rigger);
}
}
 
// Set pixel color from 'packed' 32-bit RGB value:
// Only on selected rigger's
void LPD8806::setPixelColor(uint16_t n, uint32_t c, uint8_t r1, uint8_t r2, uint8_t r3, uint8_t r4, uint8_t r5, uint8_t r6, uint8_t r7, uint8_t r8) {
int i;
int pix;
uint16_t z;
 
// Select rigger to set LEDs
for (i=1; i<=rigger; i++){
if (i == 1 && r1 == 1){
z = ((numLEDs/rigger)*1)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 2 && r2 == 1){
z = ((numLEDs/rigger)*2)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 3 && r3 == 1){
z = ((numLEDs/rigger)*3)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 4 && r4 == 1){
z = ((numLEDs/rigger)*4)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 5 && r5 == 1){
z = ((numLEDs/rigger)*5)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 6 && r6 == 1){
z = ((numLEDs/rigger)*6)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 7 && r7 == 1){
z = ((numLEDs/rigger)*7)+n-(numLEDs/rigger);
pix = 1;
}
if (i == 8 && r8 == 1){
z = ((numLEDs/rigger)*8)+n-(numLEDs/rigger);
pix = 1;
}
if((pix == 1) && (z < numLEDs)) { // Arrays are 0-indexed, thus NOT '<='
uint8_t *p = &pixels[z * 3];
*p++ = (c >> 16) | 0x80;
*p++ = (c >> 8) | 0x80;
*p++ = c | 0x80;
}
pix = 0;
}
 
}
 
// Query color from previously-set pixel (returns packed 32-bit GRB value)
uint32_t LPD8806::getPixelColor(uint16_t n) {
if(n < numLEDs) {
uint16_t ofs = n * 3;
return ((uint32_t)((uint32_t)pixels[ofs ] << 16) |
(uint32_t)((uint32_t)pixels[ofs + 1] << 8) |
(uint32_t)pixels[ofs + 2]) & 0x7f7f7f;
}
 
return 0; // Pixel # is out of bounds
}
/Digital_RGB_LED_Stripes/tags/Strip_Test/lib/LPD8806_kopterlight.h
0,0 → 1,48
#if (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#include <pins_arduino.h>
#endif
 
class LPD8806 {
 
public:
 
LPD8806(uint16_t n, uint8_t dpin, uint8_t cpin, uint8_t rig); // Configurable pins
LPD8806(uint16_t n, uint8_t rig); // Use SPI hardware; specific pins only
LPD8806(void); // Empty constructor; init pins/strip length later
void
begin(void),
show(void),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t r1, uint8_t r2, uint8_t r3, uint8_t r4, uint8_t r5, uint8_t r6, uint8_t r7, uint8_t r8),
setPixelColor(uint16_t n, uint32_t c),
setPixelColor(uint16_t n, uint32_t c, uint8_t r1, uint8_t r2, uint8_t r3, uint8_t r4, uint8_t r5, uint8_t r6, uint8_t r7, uint8_t r8),
updatePins(uint8_t dpin, uint8_t cpin), // Change pins, configurable
updatePins(void), // Change pins, hardware SPI
updateLength(uint16_t n); // Change strip length
uint16_t
numPixels(void);
uint32_t
Color(byte, byte, byte),
getPixelColor(uint16_t n);
 
private:
 
uint16_t
numLEDs; // Number of RGB LEDs in strip
uint8_t
*pixels, // Holds LED color values (3 bytes each)
clkpin , datapin, // Clock & data pin numbers
clkpinmask, datapinmask, // Clock & data PORT bitmasks
rigger, r1;
volatile uint8_t
*clkport , *dataport; // Clock & data PORT registers
void
startBitbang(void),
startSPI(void);
boolean
hardwareSPI, // If 'true', using hardware SPI
begun; // If 'true', begin() method was previously invoked
};