LPD 8806 Apple style "Breathing" effect

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

LPD 8806 Apple style "Breathing" effect

Post by ourob0r05 »

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!

User avatar
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

Re: LPD 8806 Apple style "Breathing" effect

Post by ourob0r05 »

By the way - I'm using Arduino - it'd probably help to note that. =)

User avatar
pburgess
 
Posts: 4161
Joined: Sun Oct 26, 2008 2:29 am

Re: LPD 8806 Apple style "Breathing" effect

Post by pburgess »

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

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

strip.setPixelColor(0, table[x], table[x], table[x]);
strip.show();

User avatar
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

Re: LPD 8806 Apple style "Breathing" effect

Post by ourob0r05 »

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.

tldr
 
Posts: 466
Joined: Thu Aug 30, 2012 1:34 am

Re: LPD 8806 Apple style "Breathing" effect

Post by tldr »

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

#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);
    }
  }
}

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: LPD 8806 Apple style "Breathing" effect

Post by adafruit_support_rick »

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

#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);
  }
}

User avatar
ourob0r05
 
Posts: 14
Joined: Sat Mar 10, 2012 2:13 am

Re: LPD 8806 Apple style "Breathing" effect

Post by ourob0r05 »

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...

cloudwalking
 
Posts: 17
Joined: Sat Jul 13, 2013 2:03 am

Re: LPD 8806 Apple style "Breathing" effect

Post by cloudwalking »

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

User avatar
pburgess
 
Posts: 4161
Joined: Sun Oct 26, 2008 2:29 am

Re: LPD 8806 Apple style "Breathing" effect

Post by pburgess »

adafruit_support_rick wrote:BreatheRightStrip.ino
Your horrible pun has not gone unnoticed. Go sit in the corner! :mrgreen:

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: LPD 8806 Apple style "Breathing" effect

Post by adafruit_support_rick »

Awww….! :(

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”