Please be aware of all shipping deadlines before placing your order - we cannot guarantee orders will arrive before Christmas!

LPD 8806 Apple style "Breathing" effect
Moderators: adafruit_support_bill, adafruit

LPD 8806 Apple style "Breathing" effect

by ourob0r05 on Thu Nov 08, 2012 8:07 pm

Hey!
Looking for a little help getting my LPD8806 strip to have the "breathing"-type effect that MacBooks have when sleeping. I've found some stuff on make a single LED do it but I'm not sure how to adapt the code to make it work with my strip.
If anyone could point me in the right direction, it'd be greatly appreciated.

Thanks!
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

Re: LPD 8806 Apple style "Breathing" effect

by ourob0r05 on Thu Nov 08, 2012 8:08 pm

By the way - I'm using Arduino - it'd probably help to note that. =)
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

Re: LPD 8806 Apple style "Breathing" effect

by pburgess on Fri Nov 09, 2012 1:37 am

Hard to say exactly without seeing the original code in question. Most likely it's either reading from a table or calculating a sort of sine wave, and then using PWM to drive the single LED.

If you're using our LPD8806 library, this should be a relatively straightforward translation. For example, in the original code, there might be a line that sets the PWM brightness like this (or something similar):
Code: Select all | TOGGLE FULL SIZE
ORC2A = table[x];

In your own code, after declaring the LPD8806 strip object and such, somewhere in your loop() function, you could make the first LED breathe white with something like this:
Code: Select all | TOGGLE FULL SIZE
strip.setPixelColor(0, table[x], table[x], table[x]);
strip.show();
User avatar
pburgess
 
Posts: 2760
Joined: Sun Oct 26, 2008 2:29 am

Re: LPD 8806 Apple style "Breathing" effect

by ourob0r05 on Sat Nov 10, 2012 10:13 am

Thanks for the quick response!

Well, the original code is here: http://www.thecustomgeek.com/files/Sleep_LED.pde

They have an LED on analog pin 11 so I imagine that this is the part I'd have to change. Probably exchange the analogWrite function for one of the functions from the LPD8806 library. Not sure exactly which one and how. I'm still looking through the LPD8806 examples to try to figure it out.
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

Re: LPD 8806 Apple style "Breathing" effect

by tldr on Sat Nov 10, 2012 1:29 pm

do you want the whole strip to breathe a single color. a rippling effect might be kind of cool, but maybe a pain to code.

for a single color it's probably easier to code this without the library.

this might work.

Code: Select all | TOGGLE FULL SIZE
#include "SPI.h"

#define NUMLEDS 32  // maybe you've just got 1 meter of leds
#define RED  0xff      // this might give something pinkish
#define GREEN 0xd0
#define BLUE 0xff

int i = 0;
int direction = 1;

void setup() { // bring the LED up nicely from being off
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPDR = 0;
  i = 15;
  delay (1);
}

void loop()
{
  while (1)
  {
    for (int j = 0; j < NUMLEDS; j++) {
      while(!(SPSR & (1<<SPIF)));
      SPDR = GREEN;
      while(!(SPSR & (1<<SPIF)));
      SPDR = RED;
      while(!(SPSR & (1<<SPIF)));
      SPDR = BLUE;
    }
    while(!(SPSR & (1<<SPIF)));
    SPDR = 0;
    i += direction;
    if (i >= 255) direction = -1;
    else if (i <= 15) direction = 1;
    if (i > 150) {
      delay(4);
    }
    if ((i > 125) && (i < 151)) {
      delay(5);
    }
    if (( i > 100) && (i < 126)) {
      delay(7);
    }
    if (( i > 75) && (i < 101)) {
      delay(10);
    }
    if (( i > 50) && (i < 76)) {
      delay(14);
    }
    if (( i > 25) && (i < 51)) {
      delay(18);
    }
    if (( i > 1) && (i < 26)) {
      delay(19);
    }
  }
}
"If I had known it was harmless, I would have killed it myself." - Phillip K. Dick, A Scanner Darkly
User avatar
tldr
 
Posts: 466
Joined: Thu Aug 30, 2012 1:34 am

Re: LPD 8806 Apple style "Breathing" effect

by adafruit_support_rick on Sat Nov 10, 2012 4:47 pm

Try this. It uses a lookup table for the breathing intensities.

The breathing function is exp(sin(x)). I already had the lookup table from a different project, so I threw this together around it. If I make the table bigger, the breathing ought to get a little smoother. I've also got a function for generating an arbitrary-length table - maybe I'll see about doing something with that…

BreatheRightStrip.ino:
Code: Select all | TOGGLE FULL SIZE
#include "LPD8806.h"
#include "SPI.h"

// Example to control LPD8806-based RGB LED Modules in a strip

/*****************************************************************************/

// Choose which 2 pins you will use for output.
// Can be any valid output pins.
int dataPin = 2;   
int clockPin = 3;

// Set the first variable to the NUMBER of pixels. 32 = 32 pixels in a row
// The LED strips are 32 LEDs per meter but you can extend/cut the strip
LPD8806 strip = LPD8806(32, dataPin, clockPin);

// you can also use hardware SPI, for ultra fast writes by leaving out the
// data and clock pin arguments. This will 'fix' the pins to the following:
// on Arduino 168/328 thats data = 11, and clock = pin 13
// on Megas thats data = 51, and clock = 52
//LPD8806 strip = LPD8806(32);


uint8_t LED_Breathe_Table[]  = {   80,  87,  95, 103, 112, 121, 131, 141, 151, 161, 172, 182, 192, 202, 211, 220,
              228, 236, 242, 247, 251, 254, 255, 255, 254, 251, 247, 242, 236, 228, 220, 211,
              202, 192, 182, 172, 161, 151, 141, 131, 121, 112, 103,  95,  87,  80,  73,  66,
               60,  55,  50,  45,  41,  38,  34,  31,  28,  26,  24,  22,  20,  20,  20,  20,
               20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,
               20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  20,  22,  24,  26,  28,
               31,  34,  38,  41,  45,  50,  55,  60,  66,  73 };


#define BREATHE_TABLE_SIZE (sizeof(LED_Breathe_Table))
#define BREATHE_CYCLE    6000      /*breathe cycle in milliseconds*/
#define BREATHE_UPDATE    (BREATHE_CYCLE / BREATHE_TABLE_SIZE)


void setup() {
  // Start up the LED strip
  strip.begin();

  // Update the strip, to start they are all 'off'
  strip.show();
}


void loop() {
  int cycle;
  for (cycle=0; cycle < 4; cycle++) {
    uniformBreathe(LED_Breathe_Table, BREATHE_TABLE_SIZE, BREATHE_UPDATE, 127, 127, 127);
  }
  for (cycle=0; cycle < 4; cycle++) {
    sequencedBreathe(LED_Breathe_Table, BREATHE_TABLE_SIZE, BREATHE_UPDATE, 127, 127, 127);
  }
}

void uniformBreathe(uint8_t* breatheTable, uint8_t breatheTableSize, uint16_t updatePeriod, uint16_t r, uint16_t g, uint16_t b)
{
  int i;
  uint8_t breatheIndex = 0;
  uint8_t breatheRed;
  uint8_t breatheGrn;
  uint8_t breatheBlu;
 
  for (breatheIndex = 0; breatheIndex < breatheTableSize; breatheIndex++) {
    for (i=0; i < strip.numPixels(); i++) {
      breatheRed = (r * breatheTable[breatheIndex]) / 256;
      breatheGrn = (g * breatheTable[breatheIndex]) / 256;
      breatheBlu = (b * breatheTable[breatheIndex]) / 256;
      strip.setPixelColor(i, breatheRed, breatheGrn, breatheBlu);
    }
    strip.show();   // write all the pixels out
    delay(updatePeriod);
  }
}

void sequencedBreathe(uint8_t* breatheTable, uint8_t breatheTableSize, uint16_t updatePeriod, uint16_t r, uint16_t g, uint16_t b)
{
  int i;
  uint8_t breatheIndex = 0;
  uint8_t breatheRed;
  uint8_t breatheGrn;
  uint8_t breatheBlu;
  uint8_t sequenceIndex;
 
  for (breatheIndex = 0; breatheIndex < breatheTableSize; breatheIndex++) {
    for (i=0; i < strip.numPixels(); i++) {
      sequenceIndex = (breatheIndex + (i*4)) % breatheTableSize;
      breatheRed = (r * breatheTable[sequenceIndex]) / 256;
      breatheGrn = (g * breatheTable[sequenceIndex]) / 256;
      breatheBlu = (b * breatheTable[sequenceIndex]) / 256;
      strip.setPixelColor(i, breatheRed, breatheGrn, breatheBlu);
    }
    strip.show();   // write all the pixels out
    delay(updatePeriod);
  }
}

adafruit_support_rick
 
Posts: 14541
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: LPD 8806 Apple style "Breathing" effect

by ourob0r05 on Wed Nov 14, 2012 1:01 pm

Thanks for the help guys! It is very fortunate for noobs like me that there is such a helpful community for these kinds of things.

@tldr - this code won't compile for some reason... I keep getting an error when I try it.

@driverblock - exactly what I was looking for! It's pretty smooth too even for my 4m (128 pixel) strip. Now to try combining this with the rainbowCycle function from the strandtest example...
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

Re: LPD 8806 Apple style "Breathing" effect

by cloudwalking on Sun Aug 04, 2013 2:59 am

I used a similar lookup table to create a breathing effect for my LPD 8806. Feel free to use my code.
Video: http://www.youtube.com/watch?v=pzt8l3EhPOU
Code: https://github.com/cloudwalking/Breathe
cloudwalking
 
Posts: 17
Joined: Sat Jul 13, 2013 2:03 am

Re: LPD 8806 Apple style "Breathing" effect

by pburgess on Sun Aug 04, 2013 5:04 pm

adafruit_support_rick wrote:BreatheRightStrip.ino


Your horrible pun has not gone unnoticed. Go sit in the corner! :mrgreen:
User avatar
pburgess
 
Posts: 2760
Joined: Sun Oct 26, 2008 2:29 am

Re: LPD 8806 Apple style "Breathing" effect

by adafruit_support_rick on Mon Aug 05, 2013 10:49 am

Awww….! :(

adafruit_support_rick
 
Posts: 14541
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY