LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Tue Nov 13, 2012 10:51 pm

Hi ,


I am trying to setup a LPD8806 RGB light strip to run different sequences at differences
I am using a sketch that I found for running a piezo speaker to sound at different distances and different hrz along with the advanced led belt kit.

I have been abe to get both of them working indepently but have not been able to combine them.

Code: Select all

#include <avr/pgmspace.h>
#include "SPI.h"
#include "LPD8806.h"
#include "TimerOne.h"

#if defined(USB_SERIAL) || defined(USB_SERIAL_ADAFRUIT)
// this is for teensyduino support
int dataPin = 2;
int clockPin = 1;
#else
// these are the pins we use for the LED belt kit using
// the Leonardo pinouts
int dataPin = 16;
int clockPin = 15;
#endif

int sonarPin = 0; //pin connected to analog out on maxsonar sensor
int piezoPin = 9; // specifies the pin connected to piezo from Arduino
int inchesAway; // inches away from the maxsonar sensor

// Declare the number of pixels in strand; 32 = 32 pixels in a row.  The
// LED strips have 32 LEDs per meter, but you can extend or cut the strip.
const int numPixels = 32;
// 'const' makes subsequent array declarations possible, otherwise there
// would be a pile of malloc() calls later.

// Instantiate LED strip; arguments are the total number of pixels in strip,
// the data pin number and clock pin number:
LPD8806 strip = LPD8806(numPixels, dataPin, clockPin);

// You can also use hardware SPI for ultra-fast writes by omitting the data
// and clock pin arguments.  This is faster, but the data and clock are then
// fixed to very specific pin numbers: on Arduino 168/328, data = pin 11,
// clock = pin 13.  On Mega, data = pin 51, clock = pin 52.
//LPD8806 strip = LPD8806(numPixels);

// Principle of operation: at any given time, the LEDs depict an image or
// animation effect (referred to as the "back" image throughout this code).
// Periodically, a transition to a new image or animation effect (referred
// to as the "front" image) occurs.  During this transition, a third buffer
// (the "alpha channel") determines how the front and back images are
// combined; it represents the opacity of the front image.  When the
// transition completes, the "front" then becomes the "back," a new front
// is chosen, and the process repeats.
byte imgData[2][numPixels * 3], // Data for 2 strips worth of imagery
     alphaMask[numPixels],      // Alpha channel for compositing images
     backImgIdx = 0,            // Index of 'back' image (always 0 or 1)
     fxIdx[3];                  // Effect # for back & front images + alpha
int  fxVars[3][50],             // Effect instance variables (explained later)
     tCounter   = -1,           // Countdown to next transition
     transitionTime;            // Duration (in frames) of current transition

// function prototypes, leave these be :)
void renderEffect00(byte idx);
void renderEffect01(byte idx);
void renderEffect02(byte idx);
void renderEffect03(byte idx);
void renderAlpha00(void);
void renderAlpha01(void);
void renderAlpha02(void);
void renderAlpha03(void);
void callback();
byte gamma(byte x);
long hsv2rgb(long h, byte s, byte v);
char fixSin(int angle);
char fixCos(int angle);

// List of image effect and alpha channel rendering functions; the code for
// each of these appears later in this file.  Just a few to start with...
// simply append new ones to the appropriate list here:
void (*renderEffect[])(byte) = {
  renderEffect00,
  renderEffect01,
  renderEffect02,
  renderEffect03 },
(*renderAlpha[])(void)  = {
  renderAlpha00,
  renderAlpha01,
  renderAlpha02 };

// ---------------------------------------------------------------------------

void setup() {
pinMode(piezoPin, OUTPUT);
//Serial.begin(9600); // starts serial communication, used for debugging or seeing the values

  // Start up the LED strip.  Note that strip.show() is NOT called here --
  // the callback function will be invoked immediately when attached, and
  // the first thing the calback does is update the strip.
  strip.begin();

  // Initialize random number generator from a floating analog input.
  randomSeed(analogRead(0));
  memset(imgData, 0, sizeof(imgData)); // Clear image data
  fxVars[backImgIdx][0] = 1;           // Mark back image as initialized

  // Timer1 is used so the strip will update at a known fixed frame rate.
  // Each effect rendering function varies in processing complexity, so
  // the timer allows smooth transitions between effects (otherwise the
  // effects and transitions would jump around in speed...not attractive).
  Timer1.initialize();
  Timer1.attachInterrupt(callback, 1000000 / 60); // 60 frames/second
}

void loop() {
}

void callback() {
inchesAway = analogRead(sonarPin) /2; // reads the maxsonar sensor and divides the value by 2
// approximate distance in inches
//Serial.print(inchesAway); // prints the sensor information from the maxsonar to the serial monitor
//Serial.println(" inches from sensor");

if (inchesAway < 24) { // if something is 24 inches away then make a 1khz sound
digitalWrite(piezoPin, HIGH);
delayMicroseconds(500);
digitalWrite(piezoPin, LOW);
delayMicroseconds(500);
}

if (inchesAway < 10) { // if something is 10 inches away then make a 1khz sound
digitalWrite(piezoPin, HIGH);
delayMicroseconds(1000);
digitalWrite(piezoPin, LOW);
delayMicroseconds(1000);


}

}


This is what i have so far.

Once I start adding any of the void functions such as
Code: Select all
void renderEffect00(byte idx) {
  // Only needs to be rendered once, when effect is initialized:
  if(fxVars[idx][0] == 0) {
    byte *ptr = &imgData[idx][0],
      r = random(256), g = random(256), b = random(256);
    for(int i=0; i<numPixels; i++) {
      *ptr++ = r; *ptr++ = g; *ptr++ = b;
    }
    fxVars[idx][0] = 1; // Effect initialized
  }
}


I get an error - a function-definition is not allowed here before '{' token

Please let me know if I can provide any other info that might help aid in answering the question

thanks
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by adafruit_support_bill on Wed Nov 14, 2012 6:08 am

I get an error - a function-definition is not allowed here before '{' token

Hard to say since you only posted part of your code. But it sounds like you are adding it into the middle of another function.
User avatar
adafruit_support_bill
 
Posts: 25556
Joined: Sat Feb 07, 2009 9:11 am

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Wed Nov 14, 2012 3:38 pm

Hi thanks for the quick response.

I got it to work with this code here

Code: Select all
#include "LPD8806.h"
#include "SPI.h"

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

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

// Number of RGB LEDs in strand:
int nLEDs = 32;

// Chose 2 pins for output; can be any valid output pins:
int dataPin  = 2;
int clockPin = 3;

// First parameter is the number of LEDs in the strand.  The LED strips
// are 32 LEDs per meter but you can extend or cut the strip.  Next two
// parameters are SPI data and clock pins:
LPD8806 strip = LPD8806(32, dataPin, clockPin);

int sonarPin = 0; //pin connected to analog out on maxsonar sensor
int inchesAway; // inches away from the maxsonar sensor



void setup() {

  // Start up the LED strip
  strip.begin();

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

void loop() {
inchesAway = analogRead(sonarPin)/2; // reads the maxsonar sensor and divides the value by 2
// approximate distance in inches
if (inchesAway  <2) {// if something is 24 inches away then make a 1khz sound
  rainbowCycle(0);
}

if (inchesAway  <10) { // if something is 24 inches away then make a 1khz sound
  rainbowCycle(0);
}

if (inchesAway  >=20 ) { // if something is 24 inches away then make a 1khz sound
colorWipe(strip.Color(  127, 127,   127), 1);  // Green
}

if (inchesAway >=24) { // if something is 10 inches away then make a 1khz sound
colorWipe(strip.Color(  0, 127,   0), 1);  // Green
}
}

void colorWipe(uint32_t c, uint8_t wait) {
  int i;

  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
 
  }
}


// Slightly different, this one makes the rainbow wheel equally distributed
// along the chain
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
 
  for (j=0; j < 384 * 1; j++) {     // 5 cycles of all 384 colors in the wheel
    for (i=0; i < strip.numPixels(); 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 / strip.numPixels()) + j) % 384) );
    } 
    strip.show();   // write all the pixels out
   
  }
}

/* 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));
}



The issue I am having now is that I want the strip to not complete the sequence if a new distance is detected.
Currently the new led sequence will run to the end then start the other I am trying to get the strip to stop what its running where ever it maybe when a new distance is detected and run that led sequence instead.

let me know if I can clarify

thanks
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by adafruit_support_bill on Wed Nov 14, 2012 5:11 pm

You need to declare a boolean variable and set it to "true" whenever the distance changes significantly. Then you need to test that variable inside the 'for' loops of your rainbowcycle and colorwipe functions. If it is "true", the function should set it to "false"and then return immediately.
User avatar
adafruit_support_bill
 
Posts: 25556
Joined: Sat Feb 07, 2009 9:11 am

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Mon Nov 19, 2012 3:44 pm

Thanks again for the quick response.
Could you show maybe one more example cause I am having a bit of trouble implementing this variable to my code.

I understand setting the variable name but I am not sure how to add it to the if statements to change it from true to false.

thanks

Nick
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by adafruit_support_bill on Tue Nov 20, 2012 7:55 am

Here's a better implementation than my first suggestion:

Add this function definition to your sketch:
Code: Select all
    bool distanceChanged(int threshold)
    {
      return (abs(analogRead(sonarPin)/2 - inchesAway) > threshold);
    }


Then, in the loops of your colorWipe and rainbowCycle functions, call it like this:

Code: Select all
if (distanceChanged(threshold))
  return;


Smaller values of "threshold" will be more sensitive to distance changes. You can adjust this as needed.
User avatar
adafruit_support_bill
 
Posts: 25556
Joined: Sat Feb 07, 2009 9:11 am

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Tue Nov 20, 2012 7:30 pm

Ok cool I will try this thanks !

I will let you know if I have any other questions

thanks again
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Tue Nov 20, 2012 8:16 pm

Okay So I tried to implement what was suggested but I am not sure if I did it right because my code is just causing the 2 sequences to cycle thru in an infinite loop

Here is my code

I probably didn't do it right

thanks again for all your help


Code: Select all
#include "LPD8806.h"
#include "SPI.h"

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

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

// Number of RGB LEDs in strand:
int nLEDs = 32;

// Chose 2 pins for output; can be any valid output pins:
int dataPin  = 2;
int clockPin = 3;

// First parameter is the number of LEDs in the strand.  The LED strips
// are 32 LEDs per meter but you can extend or cut the strip.  Next two
// parameters are SPI data and clock pins:
LPD8806 strip = LPD8806(32, dataPin, clockPin);

int sonarPin = 0; //pin connected to analog out on maxsonar sensor
int inchesAway; // inches away from the maxsonar sensor
int threshold;

bool distanceChanged(int threshold)
    {
      return (abs(analogRead(sonarPin)/2 - inchesAway) > threshold);
    }

void setup() {

  // Start up the LED strip
  strip.begin();

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

void loop() {
inchesAway = analogRead(sonarPin) /2;  // reads the maxsonar sensor and divides the value by 2
// approximate distance in inches

if (distanceChanged(threshold<1>10)){
 rainbowCycle(0);
}

if (distanceChanged(threshold<11>20)) { // if something is 24 inches away then make a 1khz sound
colorWipe(strip.Color(  127, 127, 0), 10);  // Green
}

}

void colorWipe(uint32_t c, uint8_t wait) {
  int i;

  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
 
  }
}


// Slightly different, this one makes the rainbow wheel equally distributed
// along the chain
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
 
  for (j=0; j < 384 * 1; j++) {     // 5 cycles of all 384 colors in the wheel
    for (i=0; i < strip.numPixels(); 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 / strip.numPixels()) + j) % 384) );
    } 
    strip.show();   // write all the pixels out
   
  }
}

/* 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));
}
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by adafruit_support_bill on Tue Nov 20, 2012 8:23 pm

The check for distanceChanged has to go inside the loops of your color wipe and rainbow cycle. For example:

Code: Select all
void colorWipe(uint32_t c, uint8_t wait) {
  int i;

  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();

      if (distanceChanged(3))
         return;
  }
}
User avatar
adafruit_support_bill
 
Posts: 25556
Joined: Sat Feb 07, 2009 9:11 am

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Tue Nov 20, 2012 8:42 pm

Awesome thats great !

Now I am getting some weird overlap of the sequence where they are combining with each other and then at some spots and then when I hit the rainbow sequence it will run the sequence then run single version of the other

so bascially the closest sequence basically runs all three in a loop the middle one runs the 2 sequences in a loop but the furthest one out is stable

I think that have something to do with the inequalities that are establishing the distances

This part -

Code: Select all
void loop() {
inchesAway = analogRead(sonarPin)/2; // reads the maxsonar sensor and divides the value by 2
// approximate distance in inches


if (inchesAway <10) { // if something is 24 inches away then make a 1khz sound
  rainbowCycle(0);
}

if (inchesAway  <21 ) { // if something is 24 inches away then make a 1khz sound
colorWipe(strip.Color(  127, 127,   127), 1);  // Green
}

if (inchesAway <31) { // if something is 10 inches away then make a 1khz sound
colorWipe(strip.Color(  0, 127,   0), 1);  // Green
}
}


Also here is my full code

Code: Select all
#include "LPD8806.h"
#include "SPI.h"

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

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

// Number of RGB LEDs in strand:
int nLEDs = 32;

// Chose 2 pins for output; can be any valid output pins:
int dataPin  = 2;
int clockPin = 3;

// First parameter is the number of LEDs in the strand.  The LED strips
// are 32 LEDs per meter but you can extend or cut the strip.  Next two
// parameters are SPI data and clock pins:
LPD8806 strip = LPD8806(32, dataPin, clockPin);

int sonarPin = 0; //pin connected to analog out on maxsonar sensor
int inchesAway; // inches away from the maxsonar sensor

bool distanceChanged(int threshold)
    {
      return (abs(analogRead(sonarPin)/2 - inchesAway) > threshold);
    }


void setup() {

  // Start up the LED strip
  strip.begin();

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

void loop() {
inchesAway = analogRead(sonarPin)/2; // reads the maxsonar sensor and divides the value by 2
// approximate distance in inches


if (inchesAway <10) { // if something is 24 inches away then make a 1khz sound
  rainbowCycle(0);
}

if (inchesAway  <21 ) { // if something is 24 inches away then make a 1khz sound
colorWipe(strip.Color(  127, 127,   127), 1);  // Green
}

if (inchesAway <31) { // if something is 10 inches away then make a 1khz sound
colorWipe(strip.Color(  0, 127,   0), 1);  // Green
}
}

void colorWipe(uint32_t c, uint8_t wait) {
  int i;

  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
     
      if (distanceChanged(10))
         return;
 
  }
}


// Slightly different, this one makes the rainbow wheel equally distributed
// along the chain
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
 
  for (j=0; j < 384 * 1; j++) {     // 5 cycles of all 384 colors in the wheel
    for (i=0; i < strip.numPixels(); 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 / strip.numPixels()) + j) % 384) );
    } 
    strip.show();   // write all the pixels out
   
    if (distanceChanged(3))
         return;
   
  }
}

/* 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));
}


Thanks again for the help this is awesome !
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by adafruit_support_bill on Tue Nov 20, 2012 9:15 pm

so bascially the closest sequence basically runs all three in a loop the middle one runs the 2 sequences in a loop but the furthest one out is stable

Not sure I understand that. But you probably need to tune the threshold parameter to the distanceChanged function. I noticed that in colorWipe you are passing it '10', while in rainbowCycle you are passing it '3'.
User avatar
adafruit_support_bill
 
Posts: 25556
Joined: Sat Feb 07, 2009 9:11 am

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Tue Nov 20, 2012 10:08 pm

Ok sorry about that.

I can adjust that for sure. What my issue is -

I have 3 led sequences a b c

when the closest distance is detected - the led runs a b c in order and in a loop

when the middle distance is detected - the led runs b c in order and in a loop

when the furthest distance is detected - the led runs c in a loop

I am not sure what part of the code need adjusted so only one sequence runs at a time.

My guess the inequalities that are being used to determine the distances are not functioning properly

I can see why because they are set run 24 in or less so or 10 in or less so when 2 distances are true I get 2 sequences.

I am trying to set it so that I can get a sequence to run inside a set distance so then it would be

sequence a - 0 - 10 in

sequence b - 11 - 20 in

sequence c - 21 - 30 in

sorry about the other unclear post hope that makes more sense

thanks again for all your help
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by adafruit_support_bill on Tue Nov 20, 2012 10:12 pm

The problem is that anything that satisfies the first 'if' will also satisfy the other two:

Code: Select all
    if (inchesAway <10) { // if something is 24 inches away then make a 1khz sound
      rainbowCycle(0);
    }

    if (inchesAway  <21 ) { // if something is 24 inches away then make a 1khz sound
    colorWipe(strip.Color(  127, 127,   127), 1);  // Green
    }

    if (inchesAway <31) { // if something is 10 inches away then make a 1khz sound
    colorWipe(strip.Color(  0, 127,   0), 1);  // Green
    }
    }


This can be fixed by using 'else if'

Code: Select all
    if (inchesAway <10) { // if something is 24 inches away then make a 1khz sound
      rainbowCycle(0);
    }

    else if (inchesAway  <21 ) { // if something is 24 inches away then make a 1khz sound
    colorWipe(strip.Color(  127, 127,   127), 1);  // Green
    }

    else if (inchesAway <31) { // if something is 10 inches away then make a 1khz sound
    colorWipe(strip.Color(  0, 127,   0), 1);  // Green
    }
    }
User avatar
adafruit_support_bill
 
Posts: 25556
Joined: Sat Feb 07, 2009 9:11 am

Re: LPD8806 RGB light strip with Maxbotix - Ultra sonic sensor

by naeluh on Tue Nov 20, 2012 10:18 pm

wow that worked perfectly

you are awesome

I can't thank you enough
naeluh
 
Posts: 33
Joined: Fri Aug 10, 2012 2:33 pm