1

I am looking to take the analogRead Value of the x, y and z axis (at pins 0, 2 and 4) and if it's a motion state, perform a rainbow, cylone and cascade LED sequences using Adafruit Neopixel library.

Using serial connection, I saw that x,y,z axis are read at values of approximately 300.

When I run the code it executed the three Neopixel sequences (redPin at pin 3, GreenPin at pin 5 and BluePin at pin 6) and then continues, even if there is no change of the accelerometer position.

What am I doing wrong? I am using Arduino Trinket Pro 5V and working with the x-axis and RGB strip at pin 3 only to start.

Thank you for your help.

#include <Adafruit_NeoPixel.h>
#include "WS2812_Definitions.h"

#define PIN1 3
#define LED_COUNT1 5
#define PIN2 5
#define LED_COUNT2 5
#define PIN3 6
#define LED_COUNT3 5

// Create an instance of the Adafruit_NeoPixel class called "leds".
// That'll be what we refer to from here on...
Adafruit_NeoPixel RedPin = Adafruit_NeoPixel(LED_COUNT1, PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel GreenPin = Adafruit_NeoPixel(LED_COUNT2, PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel BluePin = Adafruit_NeoPixel(LED_COUNT3, PIN3, NEO_GRB + NEO_KHZ800);

const int sensorPinRed = A0;
const int sensorPinGreen = A2;
const int sensorPinBlue = A4;

int analogValue = 0;

void setup()
{

  RedPin.begin();  // Call this to start up the LED strip.
  //GreenPin.begin();
  //BluePin.begin();
  clearLEDs();   // This function, defined below, turns all LEDs off...
  RedPin.show();   // ...but the LEDs don't actually update until you call this.
  //GreenPin.show();
  //BluePin.show()}

void loop()
{
  do{
   analogValue = analogRead(sensorPinRed);
  // Ride the Rainbow Road
  for (int i=0; i<LED_COUNT1*10; i++)
  {
    rainbow(i);
    delay(100);  // Delay between rainbow slides
  }

  // Indigo cylon
  // Do a cylon (larson scanner) cycle 10 times
  for (int i=0; i<10; i++)
  {
    // cylon function: first param is color, second is time (in ms) between cycles
    cylon(INDIGO, 500);  // Indigo cylon eye!
  }

  // A light shower of spring green rain
  // This will run the cascade from top->bottom 20 times
  for (int i=0; i<20; i++)
  {
    // First parameter is the color, second is direction, third is ms between falls
    cascade(MEDIUMSPRINGGREEN, TOP_DOWN, 100); 
  }
  } while (analogValue>300);
}

// Implements a little larson "cylon" sanner.
// This'll run one full cycle, down one way and back the other
void cylon(unsigned long color, byte wait)
{
  // weight determines how much lighter the outer "eye" colors are
  const byte weight = 4;  
  // It'll be easier to decrement each of these colors individually
  // so we'll split them out of the 24-bit color value
  byte red = (color & 0xFF0000) >> 16;
  byte green = (color & 0x00FF00) >> 8;
  byte blue = (color & 0x0000FF);

  // Start at closest LED, and move to the outside
  for (int i=0; i<=LED_COUNT1-1; i++)
  {
    clearLEDs();
    RedPin.setPixelColor(i, red, green, blue);  // Set the bright middle eye
    // Now set two eyes to each side to get progressively dimmer
    for (int j=1; j<3; j++)
    {
      if (i-j >= 0)
        RedPin.setPixelColor(i-j, red/(weight*j), green/(weight*j), blue/(weight*j));
      if (i-j <= LED_COUNT1)
        RedPin.setPixelColor(i+j, red/(weight*j), green/(weight*j), blue/(weight*j));
    }
    RedPin.show();  // Turn the LEDs on
    delay(wait);  // Delay for visibility
  }

  // Now we go back to where we came. Do the same thing.
  for (int i=LED_COUNT1-2; i>=1; i--)
  {
    clearLEDs();
    RedPin.setPixelColor(i, red, green, blue);
    for (int j=1; j<3; j++)
    {
      if (i-j >= 0)
        RedPin.setPixelColor(i-j, red/(weight*j), green/(weight*j), blue/(weight*j));
      if (i-j <= LED_COUNT1)
        RedPin.setPixelColor(i+j, red/(weight*j), green/(weight*j), blue/(weight*j));
      }

    RedPin.show();
    delay(wait);
  }
}

// Cascades a single direction. One time.
void cascade(unsigned long color, byte direction, byte wait)
{
  if (direction == TOP_DOWN)
  {
    for (int i=0; i<LED_COUNT1; i++)
    {
      clearLEDs();  // Turn off all LEDs
      RedPin.setPixelColor(i, color);  // Set just this one
      RedPin.show();
      delay(wait);
    }
  }
  else
  {
    for (int i=LED_COUNT1-1; i>=0; i--)
    {
      clearLEDs();
      RedPin.setPixelColor(i, color);
      RedPin.show();
      delay(wait);
    }
  }
}

// Sets all LEDs to off, but DOES NOT update the display;
// call leds.show() to actually turn them off after this.
void clearLEDs()
{
  for (int i=0; i<LED_COUNT1; i++)
  {
    RedPin.setPixelColor(i, 0);
  }
}

// Prints a rainbow on the ENTIRE LED strip.
//  The rainbow begins at a specified position. 
// ROY G BIV!
void rainbow(byte startPosition) 
{
  // Need to scale our rainbow. We want a variety of colors, even if there
  // are just 10 or so pixels.
  int rainbowScale = 192 / LED_COUNT1;

  // Next we setup each pixel with the right color
  for (int i=0; i<LED_COUNT1; i++)
  {
    // There are 192 total colors we can get out of the rainbowOrder function.
    // It'll return a color between red->orange->green->...->violet for 0-191.
    RedPin.setPixelColor(i, rainbowOrder((rainbowScale * (i + startPosition)) % 192));
  }
  // Finally, actually turn the LEDs on:
  RedPin.show();
}
1
  • Have you tried printing analogValue in your loop to verify that it is behaving the way you expect?
    – uint128_t
    Commented Mar 13, 2016 at 18:26

2 Answers 2

1

It seems to me that you are coding to always display something on the LEDs:

  void loop()
  {
    do {
      analogValue = analogRead(sensorPinRed);
      // display stuff
    } while (analogValue > 300);
  }

Assuming that you want the LEDs off when analogValue is <= 300, you have the test in the wrong place. That always does the loop at least once. How about:

  void loop()
    {
    analogValue = analogRead(sensorPinRed);
    if (analogValue > 300) 
      {
      // display stuff
      }
    else
      {
      clearLEDs();   // Turn all LEDs off...
      RedPin.show(); 
      BluePin.show(); 
      GreenPin.show(); 
      }
    }
1

Thanks to @nick-gammon for debugging my code.

I cleaned it up so below is the working sample. X-axis of the accelerometer is related to PWM pin 3 RGB LED strip, Y axis of pin 5 and Z axis to pin 6.

The LED sequence cascades once in spring green color in response to the tilt in direction.

#include <Adafruit_NeoPixel.h>
#include "WS2812_Definitions.h"

#define PIN1 3
#define LED_COUNT1 5
#define PIN2 5
#define LED_COUNT2 5
#define PIN3 6
#define LED_COUNT3 5

// Create an instance of the Adafruit_NeoPixel class called "XPin", "YPin" and "ZPin".
// That'll be what we refer to from here on...
Adafruit_NeoPixel XPin = Adafruit_NeoPixel(LED_COUNT1, PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel YPin = Adafruit_NeoPixel(LED_COUNT2, PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel ZPin = Adafruit_NeoPixel(LED_COUNT3, PIN3, NEO_GRB + NEO_KHZ800);

const int sensorPinX = A0;
const int sensorPinY = A2;
const int sensorPinZ = A4;

int analogValueX = 0;
int analogValueY = 0;
int analogValueZ = 0;

void setup()
{

  XPin.begin();  // Call this to start up the LED strip.
  YPin.begin();
  ZPin.begin();
  clearLEDs();   // This function, defined below, turns all LEDs off...

}

void loop()
{
   analogValueX = analogRead(sensorPinX);
   analogValueY = analogRead(sensorPinY);
   analogValueZ = analogRead(sensorPinZ);
   if ((analogValueX > 400) || (analogValueY > 400) || (analogValueZ > 400) )
   {

  // A light shower of spring green rain
  // This will run the cascade from top->bottom i times
  for (int i=0; i<1; i++)
  {
    // First parameter is the color, second is direction, third is ms between falls
    cascade(MEDIUMSPRINGGREEN, TOP_DOWN, 100); 
  }
   }
   else
   {
     clearLEDs(); // Turn all LEDs off
   }
}

// Cascades a single direction. One time.
void cascade(unsigned long color, byte direction, byte wait)
{
  if (direction == TOP_DOWN)
  {
    for (int i=0; i<LED_COUNT1; i++)
    {
      clearLEDs();  // Turn off all LEDs
      XPin.setPixelColor(i, color);  // Set just this one
      XPin.show();
      delay(wait);
    }

    for (int i=0; i<LED_COUNT2; i++)
    {
      clearLEDs();  // Turn off all LEDs
      YPin.setPixelColor(i, color);  // Set just this one
      YPin.show();
      delay(wait);
    }
    for (int i=0; i<LED_COUNT3; i++)
    {
      clearLEDs();  // Turn off all LEDs
      ZPin.setPixelColor(i, color);  // Set just this one
      ZPin.show();
      delay(wait);
    }
  }
  else
  {
    for (int i=LED_COUNT1-1; i>=0; i--)
    {
      clearLEDs();
      XPin.setPixelColor(i, color);
      XPin.show();
      delay(wait);
    }

    for (int i=LED_COUNT2-1; i>=0; i--)
    {
      clearLEDs();
      YPin.setPixelColor(i, color);
      YPin.show();
      delay(wait);
    }

    for (int i=LED_COUNT3-1; i>=0; i--)
    {
      clearLEDs();
      ZPin.setPixelColor(i, color);
      ZPin.show();
      delay(wait);
    }
  }
}

// Sets all LEDs to off, but DOES NOT update the display;
// call leds.show() to actually turn them off after this.
void clearLEDs()
{
  for (int i=0; i<LED_COUNT1; i++)
  {
    XPin.setPixelColor(i, 0);
  }
  for (int i=0; i<LED_COUNT2; i++)
  {
    YPin.setPixelColor(i, 0);
  }
  for (int i=0; i<LED_COUNT3; i++)
  {
    ZPin.setPixelColor(i, 0);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.