NeoPixel Ring + Buttons

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.
User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

NeoPixel Ring + Buttons

Post by anderson69s »

Hi everybody how are you? It's a little Hello from France ;-) . Please excuse my poor english...

First I want to thank all the community and Adafruit... Here in France there is no such compagny... Every time I ordered, my components where here in less than week and I always find some help on the forum. So change nothing and keep this way ;-D

I need help with two neopixel ring and two push buttons... I saw this tutorial on the learning part of the site :

https://learn.adafruit.com/multi-taskin ... ino-part-3

I made the circuit using only two neopixel ring. I modified the code to removed the two strip of leds. It work's great... No troubles at all...

What I want to do :

I want nice hat for me and my girlfriend... You can see my first prototype here : http://anderson69s.com/2014/09/27/glowing-hat/ (That my personal website : I'm trying to show what is doable with open-source hardware to french people)

The goal is to :

- remove Two neopixel ring on the first prototype so I can make the same hat for my girlfriend : two neopixel ring per hat.
- keep the two push buttons from the tutorial but they have to change animation.

Right now, I've implented the tutorial code with a counter on the two push button. One push button increase the counter the other decrease it. I made a switch case to change animation. It work great with fixed color but I can't make it work with animation like theater_chase...

I know, I have to implement an anti-rebond on the button... ;-)

Here is my code for fixed color :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern { 
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction { 
  FORWARD, REVERSE };

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns : 
public Adafruit_NeoPixel
{
public:

  // Member Variables:  
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  { 
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

#define valeurMin 0
#define valeurMax 5
int z=0;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  z=0;
  Serial.println(z);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();

  // Kick off a pattern
  // Ring2.TheaterChase(Ring2.Color(155,155,0), Ring2.Color(155,0,155), 500);
  // Ring1.TheaterChase(Ring1.Color(155,155,0), Ring1.Color(155,0,155), 500);

  Serial.println(z);
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();    

  // Switch patterns on a button press:
  if (digitalRead(8) == LOW) // Button #1 pressed
  {

    //Ring1.ActivePattern = RAINBOW_CYCLE;
    //Ring1.TotalSteps = 255;
    // Ring1.Interval = min(10, Ring2.Interval);
    //Ring2.ActivePattern = RAINBOW_CYCLE;
    //Ring2.TotalSteps = 255;
    //Ring2.Interval = min(10, Ring2.Interval);
    if (z<valeurMax) z++;
    while((digitalRead(8)==LOW));



  }
  else if (digitalRead(9) == LOW) // Button #2 pressed
  {
    //Ring1.ColorSet(Ring1.Color(255, 255, 255));
    //Ring2.ColorSet(Ring2.Color(255, 255, 255));
    if (z>valeurMin) z--;
    while((digitalRead(9)==LOW));



  }
  else // Back to normal operation
  {
    //Ring2.ActivePattern = THEATER_CHASE;
    // Ring2.Interval = 500;
    // Ring1.ActivePattern = THEATER_CHASE;
    // Ring1.Interval = 500;

  }    
  switch (z) {
  case 0 :
    Ring2.ColorSet(Ring2.Color(125, 125, 125));
    Ring1.ColorSet(Ring1.Color(125, 125, 125  ));
    break;
  case 1 :
    Ring2.ColorSet(Ring2.Color(255, 0, 255));
    Ring1.ColorSet(Ring1.Color(255, 0, 255));
    break;
  case 2 :
    Ring2.ColorSet(Ring2.Color(255, 0, 0));
    Ring1.ColorSet(Ring1.Color(255, 0, 0));
    break;
  case 3 :
    Ring1.ColorSet(Ring1.Color(0, 0, 255));
    Ring2.ColorSet(Ring2.Color(0, 0, 255));
    break;
  case 4 :
    Ring1.ColorSet(Ring1.Color(0, 255, 0));
    Ring2.ColorSet(Ring2.Color(0, 255, 0));
    break;
  case 5 :
    Ring1.ColorSet(Ring1.Color(255, 255, 255));
    Ring2.ColorSet(Ring2.Color(255, 255, 255));
    break;

  }
}

//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
  if (digitalRead(9) == LOW)  // Button #2 pressed
  {
    //Ring1.ColorSet(Ring1.Color(255, 255, 255));
    //Ring2.ColorSet(Ring2.Color(255, 255, 255));
    if (z>valeurMin) z--;
    while((digitalRead(9)==LOW));


  }
  else  // Retrn to normal
  {
    //Ring1.TheaterChase(Ring1.Color(155,155,0), Ring1.Color(155,0,155), 500);
    //Ring2.TheaterChase(Ring2.Color(155,155,0), Ring2.Color(155,0,155), 500);
     switch (z) {
  case 0 :
    Ring2.ColorSet(Ring2.Color(125, 125, 125));
    Ring1.ColorSet(Ring1.Color(125, 125, 125  ));
    break;
  case 1 :
    Ring2.ColorSet(Ring2.Color(255, 0, 255));
    Ring1.ColorSet(Ring1.Color(255, 0, 255));
    break;
  case 2 :
    Ring2.ColorSet(Ring2.Color(255, 0, 0));
    Ring1.ColorSet(Ring1.Color(255, 0, 0));
    break;
  case 3 :
    Ring1.ColorSet(Ring1.Color(0, 0, 255));
    Ring2.ColorSet(Ring2.Color(0, 0, 255));
    break;
  case 4 :
    Ring1.ColorSet(Ring1.Color(0, 255, 0));
    Ring2.ColorSet(Ring2.Color(0, 255, 0));
    break;
  case 5 :
    Ring1.ColorSet(Ring1.Color(255, 255, 255));
    Ring2.ColorSet(Ring2.Color(255, 255, 255));
    break;
  }
}
}

// Ring 2 Completion Callback
void Ring2Complete()
{
  if (digitalRead(9) == LOW)  // Button #2 pressed
  {
    //Ring1.ColorSet(Ring1.Color(255, 255, 255));
    //Ring2.ColorSet(Ring2.Color(255, 255, 255));
    if (z>valeurMin) z--;
    while((digitalRead(9)==LOW));


  }
  else  // Retrn to normal
  {
     switch (z) {
  case 0 :
    Ring2.ColorSet(Ring2.Color(125, 125, 125));
    Ring1.ColorSet(Ring1.Color(125, 125, 125  ));
    break;
  case 1 :
    Ring2.ColorSet(Ring2.Color(255, 0, 255));
    Ring1.ColorSet(Ring1.Color(255, 0, 255));
    break;
  case 2 :
    Ring2.ColorSet(Ring2.Color(255, 0, 0));
    Ring1.ColorSet(Ring1.Color(255, 0, 0));
    break;
  case 3 :
    Ring1.ColorSet(Ring1.Color(0, 0, 255));
    Ring2.ColorSet(Ring2.Color(0, 0, 255));
    break;
  case 4 :
    Ring1.ColorSet(Ring1.Color(0, 255, 0));
    Ring2.ColorSet(Ring2.Color(0, 255, 0));
    break;
  case 5 :
    Ring1.ColorSet(Ring1.Color(255, 255, 255));
    Ring2.ColorSet(Ring2.Color(255, 255, 255));
    break;
  }
}
}
I'm not even sure to use the right solution to my problem... Any help is appreciate...

Thank's you

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: NeoPixel Ring + Buttons

Post by adafruit_support_bill »

You are testing the buttons in both the loop and the completion callbacks. You should only need to test them in the loop.
It work great with fixed color but I can't make it work with animation like theater_chase...
It appears that you have posted the fixed color code. Please post the code that doesn't work, and tell us precisely what behavior you do not like.

User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

Re: NeoPixel Ring + Buttons

Post by anderson69s »

Hi Bill, How are you?

Thank you for your answer ;-)

I reworked on my code and here is a good version of what I want using your advice ;-D :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();   

  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 9)
        showType=0;
      startShow(showType);
    }
  }
   bool newState2 = digitalRead(9);
  
  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
    case 0:     
            Ring2.ColorSet(Ring2.Color(0, 0, 0));
            Ring1.ColorSet(Ring1.Color(0, 0, 0));
            break;
    case 1: 
            Ring2.ColorSet(Ring2.Color(255, 0, 0));
            Ring1.ColorSet(Ring1.Color(255, 0, 0));
            break;
    case 2: 
            Ring2.ColorSet(Ring2.Color(0, 255, 0));
            Ring1.ColorSet(Ring1.Color(0, 255, 0));
            break;
    case 3: 
            Ring2.ColorSet(Ring2.Color(0, 0, 255));
            Ring1.ColorSet(Ring1.Color(0, 0, 255));
            break;
    case 4: 
            Ring2.ColorSet(Ring2.Color(255, 255, 0));
            Ring1.ColorSet(Ring1.Color(255, 255, 0));
            break;
    case 5: 
            Ring2.ColorSet(Ring2.Color(255, 0, 255));
            Ring1.ColorSet(Ring1.Color(255, 0, 255));
            break;
    case 6: 
            Ring2.ColorSet(Ring2.Color(255, 255, 255));
            Ring1.ColorSet(Ring1.Color(255, 255, 255));
            break;
    case 7: 
            Ring2.TheaterChase(Ring2.Color(255,0,0), Ring2.Color(0,0,255), 100);
            Ring1.TheaterChase(Ring1.Color(255,0,0), Ring1.Color(0,0,255), 100);
            break;
    case 8: 
            Ring2.TheaterChase(Ring2.Color(55,55,55), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(55,55,55), Ring1.Color(0,0,0), 100);
            break;
    case 9: 
            Ring2.RainbowCycle(3);
            Ring1.RainbowCycle(3);
            break;
}
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
   
}


// Ring 2 Completion Callback
void Ring2Complete()
{
    
}

It works, but I can't come back to static color when showType is above 6 (playing an animation). No problem to jump between animation. Also when I use RainbowCycle it looks like showType is not set to 0.

Thank you for your help

User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

Re: NeoPixel Ring + Buttons

Post by anderson69s »

Sorry my bad :

Also when I use RainbowCycle it looks like showType is not set to 0.

should be :

If I increase showType aboce 9 nothing happened. RainbowCycle still playing...

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: NeoPixel Ring + Buttons

Post by adafruit_support_bill »

I can't come back to static color when showType is above 6 (playing an animation).
If I increase showType aboce 9 nothing happened. RainbowCycle still playing...
Patterns will keep running until you change them. Calling colorSet does not change the pattern.
If you don't want patterns to run anymore, you have to change the ring patterns back to NONE.

User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

Re: NeoPixel Ring + Buttons

Post by anderson69s »

Bill, how could I thank you????

Works perfectly :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();   

  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 9)
        showType=0;
      startShow(showType);
    }
  }
   bool newState2 = digitalRead(9);
  
  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
    case 0:     
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(0, 0, 0));
            Ring1.ColorSet(Ring1.Color(0, 0, 0));
            break;
    case 1: 
             Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255, 0, 0));
            Ring1.ColorSet(Ring1.Color(255, 0, 0));
            break;
    case 2: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(0, 255, 0));
            Ring1.ColorSet(Ring1.Color(0, 255, 0));
            break;
    case 3: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(0, 0, 255));
            Ring1.ColorSet(Ring1.Color(0, 0, 255));
            break;
    case 4: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255, 255, 0));
            Ring1.ColorSet(Ring1.Color(255, 255, 0));
            break;
    case 5: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255, 0, 255));
            Ring1.ColorSet(Ring1.Color(255, 0, 255));
            break;
    case 6: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255, 255, 255));
            Ring1.ColorSet(Ring1.Color(255, 255, 255));
            break;
    case 7: 
            Ring2.TheaterChase(Ring2.Color(255,0,0), Ring2.Color(0,0,255), 100);
            Ring1.TheaterChase(Ring1.Color(255,0,0), Ring1.Color(0,0,255), 100);
            break;
    case 8: 
            Ring2.TheaterChase(Ring2.Color(55,55,55), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(55,55,55), Ring1.Color(0,0,0), 100);
            break;
    case 9: 
            Ring2.RainbowCycle(3);
            Ring1.RainbowCycle(3);
            break;
}
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
   
}


// Ring 2 Completion Callback
void Ring2Complete()
{
    
}


User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

Re: NeoPixel Ring + Buttons

Post by anderson69s »

Hummmm , I just have an idea....

Could it be doable to dim the luminosity of led no matter pattern or color using a potentiometer and this code?

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: NeoPixel Ring + Buttons

Post by adafruit_support_bill »

You would have to write some code to read the potentiometer and adjust your color intensity accordingly.

User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

Re: NeoPixel Ring + Buttons

Post by anderson69s »

Thank you Bill but it look's like it will be hard to do that with my knowledge...

I know how to read a potentiometer but I can't even imagine how I could link luminosity with my different animation...

For now, here is the code for my girlfriend hat :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();   

  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 6)
        showType=0;
      startShow(showType);
    }
  }
   bool newState2 = digitalRead(9);
  
  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
    case 0:     
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(0, 0, 0));
            Ring1.ColorSet(Ring1.Color(0, 0, 0));
            break;
    case 1: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255, 255, 255));
            Ring1.ColorSet(Ring1.Color(255, 255, 255));
            break;
    case 2: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255, 0, 255));
            Ring1.ColorSet(Ring1.Color(255, 0, 255));
            break;
    case 3: 
            Ring2.TheaterChase(Ring2.Color(255,0,255), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(255,0,255), Ring1.Color(0,0,0), 100);
            break;
    case 4: 
            Ring2.Scanner(Ring1.Color(255,0,255), 55);
            Ring1.Scanner(Ring1.Color(255,0,255), 55);
            break;
    case 5: 
            Ring2.ActivePattern = FADE;
            Ring2.Interval = 100;
            Ring1.ActivePattern = FADE;
            Ring1.Interval = 100;
            Ring1.Color1 = Ring1.Wheel(200);
            Ring2.Color1 = Ring2.Wheel(250);
            Ring1.Color2 = Ring1.Wheel(250);
            Ring2.Color2 = Ring2.Wheel(200);
            break;
    case 6: 
            Ring2.RainbowCycle(3);
            Ring1.RainbowCycle(3);
            break;
}
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
   
}


// Ring 2 Completion Callback
void Ring2Complete()
{
    
}

Full of purple ;-)

And mine :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();   

  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 11)
        showType=0;
      startShow(showType);
    }
  }
   bool newState2 = digitalRead(9);
  
  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
    case 0:     
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(0, 0, 0));
            Ring1.ColorSet(Ring1.Color(0, 0, 0));
            break;
    case 1: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255, 255, 255));
            Ring1.ColorSet(Ring1.Color(255, 255, 255));
            break;
    case 2: 
            Ring2.TheaterChase(Ring2.Color(255,0,0), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(255,0,0), Ring1.Color(0,0,0), 100);
            break;
    case 3: 
            Ring2.TheaterChase(Ring2.Color(0,255,0), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(0,255,0), Ring1.Color(0,0,0), 100);
            break;
    case 4: 
            Ring2.TheaterChase(Ring2.Color(0,0,255), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(0,0,255), Ring1.Color(0,0,0), 100);
            break;
    case 5:             
            Ring2.TheaterChase(Ring2.Color(255,255,255), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(255,255,255), Ring1.Color(0,0,0), 100);
            break;
    case 6: 
            Ring2.Scanner(Ring1.Color(255,0,0), 55);
            Ring1.Scanner(Ring1.Color(255,0,0), 55);
            break;
    case 7: 
            Ring2.Scanner(Ring1.Color(0,255,0), 55);
            Ring1.Scanner(Ring1.Color(0,255,0), 55);
            break;
    case 8: 
            Ring2.Scanner(Ring1.Color(0,0,255), 55);
            Ring1.Scanner(Ring1.Color(0,0,255), 55);
            break;
    case 9: 
            Ring2.Scanner(Ring1.Color(255,255,255), 55);
            Ring1.Scanner(Ring1.Color(255,255,255), 55);
            break;
    case 10: 
            Ring2.ActivePattern = FADE;
            Ring2.Interval = 100;
            Ring1.ActivePattern = FADE;
            Ring1.Interval = 100;
            Ring1.Color1 = (Ring1.Color(255,0,0));
            Ring2.Color1 = (Ring2.Color(255,0,0));
            Ring1.Color2 = (Ring1.Color(0,0,255));
            Ring2.Color2 = (Ring2.Color(0,255,0));
            break;
    case 11: 
            Ring2.RainbowCycle(3);
            Ring1.RainbowCycle(3);
            break;
}
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
   
}


// Ring 2 Completion Callback
void Ring2Complete()
{
    
}

See you

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: NeoPixel Ring + Buttons

Post by adafruit_support_bill »

You need to turn the pot reading into a brightness factor as follows:

Code: Select all

float brightness = analogRead(potPin) / 1024.0;  // Convert to a value between 0.0 and 1.0.
Then you can use that to scale all of your red, green and blue values to the pot setting:

Code: Select all

Ring1.ColorSet(Ring1.Color(redValue * brightness , greenValue * brightness, blueValue * brightness));

User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

Re: NeoPixel Ring + Buttons

Post by anderson69s »

Hi Bill, how are you?

Your solution is so simple and perfect that I can't help thinking that I wouldn't found it...

Code is working great :

Boy :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;
int pin = A0;
float potard;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();   
  potard = (analogRead(pin) / 1024.0);
  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 11)
        showType=0;
      startShow(showType);
    }
  }
   bool newState2 = digitalRead(9);
  
  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=11;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
    case 0:     
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(0, 0, 0));
            Ring1.ColorSet(Ring1.Color(0, 0, 0));
            break;
    case 1: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255 * potard, 255 * potard, 255 * potard));
            Ring1.ColorSet(Ring1.Color(255 * potard, 255 * potard, 255 * potard));
            break;
    case 2: 
            Ring2.TheaterChase(Ring2.Color(255 * potard,0,0), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(255 * potard,0,0), Ring1.Color(0,0,0), 100);
            break;
    case 3: 
            Ring2.TheaterChase(Ring2.Color(0,255 * potard,0), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(0,255 * potard,0), Ring1.Color(0,0,0), 100);
            break;
    case 4: 
            Ring2.TheaterChase(Ring2.Color(0,0,255 * potard), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(0,0,255 * potard), Ring1.Color(0,0,0), 100);
            break;
    case 5:             
            Ring2.TheaterChase(Ring2.Color(255 * potard,255 * potard,255 * potard), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(255 * potard,255 * potard,255 * potard), Ring1.Color(0,0,0), 100);
            break;
    case 6: 
            Ring2.Scanner(Ring1.Color(255 * potard,0,0), 55);
            Ring1.Scanner(Ring1.Color(255 * potard,0,0), 55);
            break;
    case 7: 
            Ring2.Scanner(Ring1.Color(0,255 * potard,0), 55);
            Ring1.Scanner(Ring1.Color(0,255 * potard,0), 55);
            break;
    case 8: 
            Ring2.Scanner(Ring1.Color(0,0,255 * potard), 55);
            Ring1.Scanner(Ring1.Color(0,0,255 * potard), 55);
            break;
    case 9: 
            Ring2.Scanner(Ring1.Color(255 * potard,255 * potard,255 * potard), 55);
            Ring1.Scanner(Ring1.Color(255 * potard,255 * potard,255 * potard), 55);
            break;
    case 10: 
            Ring2.ActivePattern = FADE;
            Ring2.Interval = 50;
            Ring1.ActivePattern = FADE;
            Ring1.Interval = 50;
            Ring1.Color1 = (Ring1.Color(255 * potard,0,0));
            Ring2.Color1 = (Ring2.Color(255 * potard,0,0));
            Ring1.Color2 = (Ring1.Color(0,0,255 * potard));
            Ring2.Color2 = (Ring2.Color(0,255 * potard,0));
            break;
    case 11: 
            Ring2.RainbowCycle(10);
            Ring1.RainbowCycle(10);
            break;
}
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
   
}


// Ring 2 Completion Callback
void Ring2Complete()
{
    
}

Girl :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };  

// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      setPixelColor(i, Wheel(((i * 256 / numPixels()) + Index) & 255));
    }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;
int pin = A0;
float potard;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();
  potard = (analogRead(pin) / 1024.0);
  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 6)
        showType=0;
      startShow(showType);
    }
  }
  bool newState2 = digitalRead(9);

  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=6;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
  case 0:     
    Ring1.ActivePattern = NONE;
    Ring2.ActivePattern = NONE;
    Ring2.ColorSet(Ring2.Color(0, 0, 0));
    Ring1.ColorSet(Ring1.Color(0, 0, 0));
    break;
  case 1: 
    Ring1.ActivePattern = NONE;
    Ring2.ActivePattern = NONE;
    Ring2.ColorSet(Ring2.Color(255 * potard, 255 * potard, 255 * potard));
    Ring1.ColorSet(Ring1.Color(255 * potard, 255 * potard, 255 * potard));
    break;
  case 2: 
    Ring1.ActivePattern = NONE;
    Ring2.ActivePattern = NONE;
    Ring2.ColorSet(Ring2.Color(255 * potard, 0, 255 * potard));
    Ring1.ColorSet(Ring1.Color(255 * potard, 0, 255 * potard));
    break;
  case 3: 
    Ring2.TheaterChase(Ring2.Color(255 * potard,0,255 * potard), Ring2.Color(0,0,0), 100);
    Ring1.TheaterChase(Ring1.Color(255 * potard,0,255 * potard), Ring1.Color(0,0,0), 100);
    break;
  case 4: 
    Ring2.Scanner(Ring1.Color(255 * potard,0,255 * potard), 55);
    Ring1.Scanner(Ring1.Color(255 * potard,0,255 * potard), 55);
    break;
  case 5: 
    Ring2.ActivePattern = FADE;
    Ring2.Interval = 50;
    Ring1.ActivePattern = FADE;
    Ring1.Interval = 50;
    Ring1.Color1 = Ring1.Color(255 * potard,0,0);
    Ring2.Color1 = Ring2.Color(0,0,255 * potard);
    Ring1.Color2 = Ring1.Color(0,0,255 * potard);
    Ring2.Color2 = Ring2.Color(255 * potard,0,0);
    break;
  case 6: 
    Ring2.RainbowCycle(10);
    Ring1.RainbowCycle(10);
    break;
  }
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{

}


// Ring 2 Completion Callback
void Ring2Complete()
{

}
The only animation that I can't dim with this technique is rainbowcycle... Do you have an other amazing idea?

Once again, thank you for your help

++

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: NeoPixel Ring + Buttons

Post by adafruit_support_bill »

You can use the Red, Green and Blue functions to pull apart the wheel color, then apply the brightness to it something like this:

Code: Select all

      // Update the Rainbow Cycle Pattern
      void RainbowCycleUpdate()
      {
        for(int i=0; i< numPixels(); i++)
        {
		  uint32_t wheelColor = Wheel(((i * 256 / numPixels()) + Index) & 255);
          setPixelColor(i, (Red(wheelColor) * brightness), (Green(wheelColor) * brightness), (Blue(wheelColor) * brightness));
        }
        show();
        Increment();
      }

User avatar
anderson69s
 
Posts: 8
Joined: Mon Oct 28, 2013 2:01 pm

Re: NeoPixel Ring + Buttons

Post by anderson69s »

Hi Bill, how are you today?

I test your solution and it's works great ;-)

I just had to move pin (potpin) and potard (brightness) at the beginning of the sketch...

Thank you ;-D

Here is the code if it can help someone :

Boy :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };
int pin = A0;
float potard;
// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
    for(int i=0; i< numPixels(); i++)
        {
        uint32_t wheelColor = Wheel(((i * 256 / numPixels()) + Index) & 255);
          setPixelColor(i, (Red(wheelColor) * potard), (Green(wheelColor) * potard), (Blue(wheelColor) * potard));
        }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();   
  potard = (analogRead(pin) / 1024.0);
  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 11)
        showType=0;
      startShow(showType);
    }
  }
   bool newState2 = digitalRead(9);
  
  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=11;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
    case 0:     
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(0, 0, 0));
            Ring1.ColorSet(Ring1.Color(0, 0, 0));
            break;
    case 1: 
            Ring1.ActivePattern = NONE;
            Ring2.ActivePattern = NONE;
            Ring2.ColorSet(Ring2.Color(255 * potard, 255 * potard, 255 * potard));
            Ring1.ColorSet(Ring1.Color(255 * potard, 255 * potard, 255 * potard));
            break;
    case 2: 
            Ring2.TheaterChase(Ring2.Color(255 * potard,0,0), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(255 * potard,0,0), Ring1.Color(0,0,0), 100);
            break;
    case 3: 
            Ring2.TheaterChase(Ring2.Color(0,255 * potard,0), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(0,255 * potard,0), Ring1.Color(0,0,0), 100);
            break;
    case 4: 
            Ring2.TheaterChase(Ring2.Color(0,0,255 * potard), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(0,0,255 * potard), Ring1.Color(0,0,0), 100);
            break;
    case 5:             
            Ring2.TheaterChase(Ring2.Color(255 * potard,255 * potard,255 * potard), Ring2.Color(0,0,0), 100);
            Ring1.TheaterChase(Ring1.Color(255 * potard,255 * potard,255 * potard), Ring1.Color(0,0,0), 100);
            break;
    case 6: 
            Ring2.Scanner(Ring1.Color(255 * potard,0,0), 55);
            Ring1.Scanner(Ring1.Color(255 * potard,0,0), 55);
            break;
    case 7: 
            Ring2.Scanner(Ring1.Color(0,255 * potard,0), 55);
            Ring1.Scanner(Ring1.Color(0,255 * potard,0), 55);
            break;
    case 8: 
            Ring2.Scanner(Ring1.Color(0,0,255 * potard), 55);
            Ring1.Scanner(Ring1.Color(0,0,255 * potard), 55);
            break;
    case 9: 
            Ring2.Scanner(Ring1.Color(255 * potard,255 * potard,255 * potard), 55);
            Ring1.Scanner(Ring1.Color(255 * potard,255 * potard,255 * potard), 55);
            break;
    case 10: 
            Ring2.ActivePattern = FADE;
            Ring2.Interval = 50;
            Ring1.ActivePattern = FADE;
            Ring1.Interval = 50;
            Ring1.Color1 = (Ring1.Color(255 * potard,0,0));
            Ring2.Color1 = (Ring2.Color(255 * potard,0,0));
            Ring1.Color2 = (Ring1.Color(0,0,255 * potard));
            Ring2.Color2 = (Ring2.Color(0,255 * potard,0));
            break;
    case 11: 
            Ring2.RainbowCycle(10);
            Ring1.RainbowCycle(10);
            break;
}
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{
   
}


// Ring 2 Completion Callback
void Ring2Complete()
{
    
}

Girl :

Code: Select all

#include <Adafruit_NeoPixel.h>

// Pattern types supported:
enum  pattern {
  NONE, RAINBOW_CYCLE, THEATER_CHASE, COLOR_WIPE, SCANNER, FADE };
// Patern directions supported:
enum  direction {
  FORWARD, REVERSE };  
int pin = A0;
float potard;
// NeoPattern Class - derived from the Adafruit_NeoPixel class
class NeoPatterns :
public Adafruit_NeoPixel
{
public:

  // Member Variables: 
  pattern  ActivePattern;  // which pattern is running
  direction Direction;     // direction to run the pattern

    unsigned long Interval;   // milliseconds between updates
  unsigned long lastUpdate; // last update of position

  uint32_t Color1, Color2;  // What colors are in use
  uint16_t TotalSteps;  // total number of steps in the pattern
  uint16_t Index;  // current step within the pattern

  void (*OnComplete)();  // Callback on completion of pattern

  // Constructor - calls base-class constructor to initialize strip
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type, void (*callback)())
:
    Adafruit_NeoPixel(pixels, pin, type)
    {
      OnComplete = callback;
    }

  // Update the pattern
  void Update()
  {
    if((millis() - lastUpdate) > Interval) // time to update
    {
      lastUpdate = millis();
      switch(ActivePattern)
      {
      case RAINBOW_CYCLE:
        RainbowCycleUpdate();
        break;
      case THEATER_CHASE:
        TheaterChaseUpdate();
        break;
      case COLOR_WIPE:
        ColorWipeUpdate();
        break;
      case SCANNER:
        ScannerUpdate();
        break;
      case FADE:
        FadeUpdate();
        break;
      default:
        break;
      }
    }
  }

  // Increment the Index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
    else // Direction == REVERSE
    {
      --Index;
      if (Index <= 0)
      {
        Index = TotalSteps-1;
        if (OnComplete != NULL)
        {
          OnComplete(); // call the comlpetion callback
        }
      }
    }
  }

  // Reverse pattern direction
  void Reverse()
  {
    if (Direction == FORWARD)
    {
      Direction = REVERSE;
      Index = TotalSteps-1;
    }
    else
    {
      Direction = FORWARD;
      Index = 0;
    }
  }

  // Initialize for a RainbowCycle
  void RainbowCycle(uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = RAINBOW_CYCLE;
    Interval = interval;
    TotalSteps = 255;
    Index = 0;
    Direction = dir;
  }

  // Update the Rainbow Cycle Pattern
  void RainbowCycleUpdate()
  {
        for(int i=0; i< numPixels(); i++)
        {
        uint32_t wheelColor = Wheel(((i * 256 / numPixels()) + Index) & 255);
          setPixelColor(i, (Red(wheelColor) * potard), (Green(wheelColor) * potard), (Blue(wheelColor) * potard));
        }
    show();
    Increment();
  }

  // Initialize for a Theater Chase
  void TheaterChase(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = THEATER_CHASE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Theater Chase Pattern
  void TheaterChaseUpdate()
  {
    for(int i=0; i< numPixels(); i++)
    {
      if ((i + Index) % 3 == 0)
      {
        setPixelColor(i, Color1);
      }
      else
      {
        setPixelColor(i, Color2);
      }
    }
    show();
    Increment();
  }

  // Initialize for a ColorWipe
  void ColorWipe(uint32_t color, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = COLOR_WIPE;
    Interval = interval;
    TotalSteps = numPixels();
    Color1 = color;
    Index = 0;
    Direction = dir;
  }

  // Update the Color Wipe Pattern
  void ColorWipeUpdate()
  {
    setPixelColor(Index, Color1);
    show();
    Increment();
  }

  // Initialize for a SCANNNER
  void Scanner(uint32_t color1, uint8_t interval)
  {
    ActivePattern = SCANNER;
    Interval = interval;
    TotalSteps = (numPixels() - 1) * 2;
    Color1 = color1;
    Index = 0;
  }

  // Update the Scanner Pattern
  void ScannerUpdate()
  {
    for (int i = 0; i < numPixels(); i++)
    {
      if (i == Index)  // Scan Pixel to the right
      {
        setPixelColor(i, Color1);
      }
      else if (i == TotalSteps - Index) // Scan Pixel to the left
      {
        setPixelColor(i, Color1);
      }
      else // Fading tail
      {
        setPixelColor(i, DimColor(getPixelColor(i)));
      }
    }
    show();
    Increment();
  }

  // Initialize for a Fade
  void Fade(uint32_t color1, uint32_t color2, uint16_t steps, uint8_t interval, direction dir = FORWARD)
  {
    ActivePattern = FADE;
    Interval = interval;
    TotalSteps = steps;
    Color1 = color1;
    Color2 = color2;
    Index = 0;
    Direction = dir;
  }

  // Update the Fade Pattern
  void FadeUpdate()
  {
    // Calculate linear interpolation between Color1 and Color2
    // Optimise order of operations to minimize truncation error
    uint8_t red = ((Red(Color1) * (TotalSteps - Index)) + (Red(Color2) * Index)) / TotalSteps;
    uint8_t green = ((Green(Color1) * (TotalSteps - Index)) + (Green(Color2) * Index)) / TotalSteps;
    uint8_t blue = ((Blue(Color1) * (TotalSteps - Index)) + (Blue(Color2) * Index)) / TotalSteps;

    ColorSet(Color(red, green, blue));
    show();
    Increment();
  }

  // Calculate 50% dimmed version of a color (used by ScannerUpdate)
  uint32_t DimColor(uint32_t color)
  {
    // Shift R, G and B components one bit to the right
    uint32_t dimColor = Color(Red(color) >> 1, Green(color) >> 1, Blue(color) >> 1);
    return dimColor;
  }

  // Set all pixels to a color (synchronously)
  void ColorSet(uint32_t color)
  {
    for (int i = 0; i < numPixels(); i++)
    {
      setPixelColor(i, color);
    }
    show();
  }

  // Returns the Red component of a 32-bit color
  uint8_t Red(uint32_t color)
  {
    return (color >> 16) & 0xFF;
  }

  // Returns the Green component of a 32-bit color
  uint8_t Green(uint32_t color)
  {
    return (color >> 8) & 0xFF;
  }

  // Returns the Blue component of a 32-bit color
  uint8_t Blue(uint32_t color)
  {
    return color & 0xFF;
  }

  // Input a value 0 to 255 to get a color value.
  // The colours are a transition r - g - b - back to r.
  uint32_t Wheel(byte WheelPos)
  {
    WheelPos = 255 - WheelPos;
    if(WheelPos < 85)
    {
      return Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    else if(WheelPos < 170)
    {
      WheelPos -= 85;
      return Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    else
    {
      WheelPos -= 170;
      return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
  }
};

// Define some NeoPatterns for the two rings and the stick
//  as well as some completion routines
NeoPatterns Ring1(16, 5, NEO_GRB + NEO_KHZ800, &Ring1Complete);
NeoPatterns Ring2(16, 6, NEO_GRB + NEO_KHZ800, &Ring2Complete);

bool oldState = HIGH;
bool oldState2 = HIGH;
int showType = 0;

// Initialize everything and prepare to start
void setup()
{
  Serial.begin(115200);

  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);

  // Initialize all the pixelStrips
  Ring1.begin();
  Ring2.begin();
}

// Main loop
void loop()
{
  // Update the rings.
  Ring1.Update();
  Ring2.Update();
  potard = (analogRead(pin) / 1024.0);
  bool newState = digitalRead(8);
  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(8);
    if (newState == LOW) {
      showType++;
      if (showType > 6)
        showType=0;
      startShow(showType);
    }
  }
  bool newState2 = digitalRead(9);

  // Check if state changed from high to low (button press).
  if (newState2 == LOW && oldState2 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState2 = digitalRead(9);
    if (newState2 == LOW) {
      showType--;
      if (showType < 0)
        showType=6;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
  oldState2 = newState2;
}

void startShow(int i) {
  switch(i){
  case 0:     
    Ring1.ActivePattern = NONE;
    Ring2.ActivePattern = NONE;
    Ring2.ColorSet(Ring2.Color(0, 0, 0));
    Ring1.ColorSet(Ring1.Color(0, 0, 0));
    break;
  case 1: 
    Ring1.ActivePattern = NONE;
    Ring2.ActivePattern = NONE;
    Ring2.ColorSet(Ring2.Color(255 * potard, 255 * potard, 255 * potard));
    Ring1.ColorSet(Ring1.Color(255 * potard, 255 * potard, 255 * potard));
    break;
  case 2: 
    Ring1.ActivePattern = NONE;
    Ring2.ActivePattern = NONE;
    Ring2.ColorSet(Ring2.Color(255 * potard, 0, 255 * potard));
    Ring1.ColorSet(Ring1.Color(255 * potard, 0, 255 * potard));
    break;
  case 3: 
    Ring2.TheaterChase(Ring2.Color(255 * potard,0,255 * potard), Ring2.Color(0,0,0), 100);
    Ring1.TheaterChase(Ring1.Color(255 * potard,0,255 * potard), Ring1.Color(0,0,0), 100);
    break;
  case 4: 
    Ring2.Scanner(Ring1.Color(255 * potard,0,255 * potard), 55);
    Ring1.Scanner(Ring1.Color(255 * potard,0,255 * potard), 55);
    break;
  case 5: 
    Ring2.ActivePattern = FADE;
    Ring2.Interval = 50;
    Ring1.ActivePattern = FADE;
    Ring1.Interval = 50;
    Ring1.Color1 = Ring1.Color(255 * potard,0,0);
    Ring2.Color1 = Ring2.Color(0,0,255 * potard);
    Ring1.Color2 = Ring1.Color(0,0,255 * potard);
    Ring2.Color2 = Ring2.Color(255 * potard,0,0);
    break;
  case 6: 
    Ring2.RainbowCycle(10);
    Ring1.RainbowCycle(10);
    break;
  }
}
//------------------------------------------------------------
//Completion Routines - get called on completion of a pattern
//------------------------------------------------------------

// Ring1 Completion Callback
void Ring1Complete()
{

}


// Ring 2 Completion Callback
void Ring2Complete()
{

}

User avatar
adafruit_support_bill
 
Posts: 88154
Joined: Sat Feb 07, 2009 10:11 am

Re: NeoPixel Ring + Buttons

Post by adafruit_support_bill »

Glad that worked for you. Thanks for posting your results.

User avatar
Jd42
 
Posts: 9
Joined: Mon Jul 21, 2014 3:29 pm

Re: NeoPixel Ring + Buttons

Post by Jd42 »

[quote="adafruit_support_bill"]You need to turn the pot reading into a brightness factor as follows:

Code: Select all

float brightness = analogRead(potPin) / 1024.0;  // Convert to a value between 0.0 and 1.0.
Bill, this suggestion appears to be relevant to my project of controlling brightness and speed of the color cycle with pots in this code below. However, I am unsure how to apply this. Could you point me off into the right direction?

Code: Select all

// Arduino code for basic slow cycling rainbow in Neopixel WS2811 LED strip, with variable brightness, speed, and amount of rainbow shown at one time.
/*************************************************************************************/

#include "FastSPI_LED2.h" // library here: http://code.google.com/p/fastspi/

#define NUM_LEDS 8 //length of LED strip

struct CRGB leds[NUM_LEDS];

// "Mood light" color cycling
int colorval = 0; // Variable to hold the changing "mood light" strip color.
const int mooddelay = .15; // Increase this to slow down the color cycling.
int moodcounter = 0; // just a counter...

void setup() {
    	LEDS.setBrightness(75); // set total brightness, from 1 to 255.
   LEDS.addLeds<WS2811, 6>(leds, NUM_LEDS); // set the data pin.
}


void loop() {
   rainbow(leds, colorval);
   delay(10); 
  LEDS.show();   // write all the pixels out 

  //Cycle through colorval with variable delay.
  if(moodcounter < mooddelay) moodcounter++;
  else 
    {
      colorval++;
      moodcounter = 0;
    }
  if(colorval>384) colorval=0;
}

 //Fill the strip with rainbow starting from color c
void rainbow(struct CRGB *leds, uint32_t c) {
  uint16_t i;
  //rainbowquant controls the "amount" of rainbow displayed at one time. higher number = more different colors at once.
  int rainbowquant = 400;
    for (i=0; i < NUM_LEDS; i++) {
      leds[i] = RGBWheel(((i * rainbowquant / NUM_LEDS) + c) % 384); 
    }
}

/* RGB Color Wheel Helper function */
//Input a value 0 to 384 to get a color value. 
CRGB RGBWheel(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(CRGB(g, r, b));    
}

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

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