show different colors in color wipe but without delay function

Hello i am trying to work on a project to be able to switch between patterns on a strand of WS2812B LEDs but i am having a hard time figuring out how to rewrite the example code offered by adafruit so that i can use a push button to switch patterns, Im still pretty much a noob when it comes to programming. I found the code below which lets me do the color wipe pattern without using the delay function but it only does 1 color and then it does nothing. What can i change on the code so that it will do more than one color? Any help you can give me would be greatly appreciated.

#include <Adafruit_NeoPixel.h>
#define NUM_PIXELS 12
unsigned long interval=50; // the time we need to wait
unsigned long previousMillis=0;
uint32_t currentColor;// current Color in case we need it
uint16_t currentPixel = 0;// what pixel are we operating on
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, 6, NEO_GRB + NEO_KHZ800);
void setup() {
currentColor = strip.Color(0,0,255);
currentPixel = 0;
strip.begin();
strip.show(); // Initialize all pixels to 'off'
strip.setBrightness(50);
}
// Basic idea. You could reorg and pass pixel index and color as a function - or you could go through a gradient of colors.
void loop(){
if ((unsigned long)(millis() - previousMillis) >= interval) {
previousMillis = millis();
colorWipe();
}
}
void colorWipe(){
strip.setPixelColor(currentPixel,currentColor);
strip.show();
currentPixel++;
if(currentPixel == NUM_PIXELS){
currentPixel = 0;
}
}

you need to separate this into three problems.

  1. detecting button presses
  2. keeping track of button presses
  3. showing lights.

show us some code for #1, and i can help you.

Here is a great place to start:

https://www.arduino.cc/en/Tutorial/button

kind of like this?

#include <Adafruit_NeoPixel.h>
#define NUM_PIXELS 12
const int BUTTON 9;
int ButtonState = 0;
unsigned long interval=50; // the time we need to wait
unsigned long previousMillis=0;
uint32_t currentColor;// current Color in case we need it
uint16_t currentPixel = 0;// what pixel are we operating on
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, 6, NEO_GRB + NEO_KHZ800);
void setup() {
pinMode(BUTTON, INPUT);
currentColor = strip.Color(0,0,255);
currentPixel = 0;
strip.begin();
strip.show(); // Initialize all pixels to 'off'
strip.setBrightness(50);
}
// Basic idea. You could reorg and pass pixel index and color as a function - or you could go through a gradient of colors.
void loop(){
ButtonState = digitalRead(BUTTON);
if(BUTTON == HIGH) {
if ((unsigned long)(millis() - previousMillis) >= interval) {
previousMillis = millis();
colorWipe();
}
} else {
currentColor = strip.Color(0, 0, 0);
if ((unsigned long)(millis() - previousMillis) >= interval) {
previousMillis = millis();
colorWipe();
}
}
}
void colorWipe(){
strip.setPixelColor(currentPixel,currentColor);
strip.show();
currentPixel++;
if(currentPixel == NUM_PIXELS){
currentPixel = 0;
}
}

I would keep the button function separate.

if(millis() - readTime > debounce){ //debounce button

readTime = millis(); //reset timer
if(digitalRead(button) == HIGH){ //if button pressed
  LEDFunction++; //change led function
   If(LEDFunction > NumLedFunctions){
    LEDFunction = 0; //roll over to first function
 }
}
}

Then use a switch case to display the various led functions.

what would a switch case look like? sorry like i said im still rather new at this, however your code does make sense, and i definitely need to debounce that button.

switch (LEDFunction){
case 1:
// code
break;
case 2: 
// code
break;
:
:
case 99:
// code
break;
} // end switch

Chrisrocks23:
what would a switch case look like? sorry like i said im still rather new at this, however your code does make sense, and i definitely need to debounce that button.

the code

lol @QDeathStar no i should have thought of that, still too early, i have rewritten the code but im not sure if it makes any sense now, this is the code, what am i doing wrong now?

#include <Adafruit_NeoPixel.h>
#define NUM_PIXELS 12
const int BUTTON 9;
int ButtonState = 0;
unsigned long interval=50; // the time we need to wait
unsigned long previousMillis=0;
uint32_t currentColor;// current Color in case we need it
uint16_t currentPixel = 0;// what pixel are we operating on
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, 6, NEO_GRB + NEO_KHZ800);

switch(LEDPattern){
case1:
ColorWipeRed;
break;
case2:
ColorWipeGreen;
break;
case3:
ColorWipeBlue;
break;
} //end switch

void setup() {
pinMode(BUTTON, INPUT);
currentColor = strip.Color(0,0,255);
currentPixel = 0;
strip.begin();
strip.show(); // Initialize all pixels to 'off'
strip.setBrightness(50);
}
// Basic idea. You could reorg and pass pixel index and color as a function - or you could go through a gradient of colors.
void loop(){
ButtonState = digitalRead(BUTTON);
if(millis() - readTime > debounce) {
readTime = millis(); reset timer
if(BUTTON == HIGH) {
LEDPattern++;  //change pattern
if(LEDPattern > 3) {
LEDPattern = 0;
}
}
if (BUTTON == HIGH) {
strip.LEDPattern
}
void ColorWipeRed(){
strip.setPixelColor(currentPixel,strip.Color(255, 0, 0));
strip.show();
currentPixel++;
if(currentPixel == NUM_PIXELS){
currentPixel = 0;
}
}

void ColorWipeGreen(){
strip.setPixelColor(currentPixel,strip.Color(0, 255, 0));
strip.show();
currentPixel++;
if(currentPixel == NUM_PIXELS){
currentPixel = 0;
}
}

void ColorWipeBlue(){
strip.setPixelColor(currentPixel,strip.Color(0, 0, 255));
strip.show();
currentPixel++;
if(currentPixel == NUM_PIXELS){
currentPixel = 0;
}
}

besides missing a closing bracket on the loop i just noticed that, anything else messed up?

I didn't read the code, but You should test to see if the button is working as you expect first.

Eg, right after:

if(digitalRead(button) == high){

Add a

Serial.println(F("Button Pressed"));

Then, in serial monitor when you press that button, you should see that message in serial monitor.

Report back.

I'm not writing copy pasta code...

will do when i get home, thank you so much for your help so far!

hey guys this is gonna be a total noob question here but this is a modified version of Adafruit's code to multitasking the arduino part 3. i keep getting an error telling me that "Color1 was not declared in this scope" however i have no idea how to replace color one with an actual color, like for example 0, 255, 0 any hints on what im not seeng? i have also attached a text file containing the error message

#include <Adafruit_NeoPixel.h>

//pattern types supported:
enum pattern {NONE, RAINBOW_CYCLE, SCANNER };

//pattern directions
enum direction { FORWARD, REVERSE };

class NeoPatterns : public Adafruit_NeoPixel
{
  public:
  
  pattern ActivePattern; //which pattern is active
  direction Direction; //direction to run the pattern

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

  uint16_t TotalSteps; // total number of steps in the pattern
  uint16_t Index; //current step within the pattern

  //Constructor
  NeoPatterns(uint16_t pixels, uint8_t pin, uint8_t type)
  :Adafruit_NeoPixel(pixels, pin, type)
  {
  }

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

  //Increment the index and reset at the end
  void Increment()
  {
    if (Direction == FORWARD)
    {
      Index++;
      if (Index >= TotalSteps)
      {
        Index = 0;
      }
    }
  
  else // Direction == REVERSE
  {
    --Index;
    if (Index <= 0)
    {
      Index = TotalSteps-1;
    }
  }
}

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

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

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

    
NeoPatterns Strip(16, 6, NEO_GRB + NEO_KHZ800);

void setup()
{
  Strip.begin();

  Strip.Scanner(Strip.Color(0, 255, 0), 55);
}

void loop()
{
  if (digitalRead(12) == LOW) // Button pressed
  {
    Strip.ActivePattern = RAINBOW_CYCLE;
    Strip.TotalSteps = 255;
    Strip.Interval = min(10, Strip.Interval);
  }
  else
  {
    Strip.ActivePattern = SCANNER;
    Strip.Color(0, 255, 0), 55);
  }

Error message about Color1.txt (2.3 KB)

what happened to getting your button working?

where is the original code? That error is exactly as it says on the tin, you haven't told the compiler what Color1 is. You need to look at the original code to see how it declares Color1

also

FastLED.io

on the original code it declares Color1 as

// Stick Completion Callback
void StickComplete()
{
    // Random color change for next scan
    Stick.Color1 = Stick.Wheel(random(255));
}

but i dont want there to be a completion callback i just want it to play the scanning pattern over and over again with a single color not a random color. where in the code do i declare Strip.Color1(Color(0, 255, 0));

Hmm, I still don't see the original code.

That function does not declare Color1.

This is the original code. It has 3 strips running and 2 pushbuttons but i only need 1 strip and 1 button

Part 1

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

void Ring1Complete();
void Ring2Complete();
void StickComplete();

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

Had to split it in 2 parts it exceeded the maximum characters allowed

Part 2

// 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();
    Stick.begin();
    
    // Kick off a pattern
    Ring1.TheaterChase(Ring1.Color(255,255,0), Ring1.Color(0,0,50), 100);
    Ring2.RainbowCycle(3);
    Ring2.Color1 = Ring1.Color1;
    Stick.Scanner(Ring1.Color(255,0,0), 55);
}

// Main loop
void loop()
{
    // Update the rings.
    Ring1.Update();
    Ring2.Update();    
    
    // Switch patterns on a button press:
    if (digitalRead(8) == LOW) // Button #1 pressed
    {
        // Switch Ring1 to FASE pattern
        Ring1.ActivePattern = FADE;
        Ring1.Interval = 20;
        // Speed up the rainbow on Ring2
        Ring2.Interval = 0;
        // Set stick to all red
        Stick.ColorSet(Stick.Color(255, 0, 0));
    }
    else if (digitalRead(9) == LOW) // Button #2 pressed
    {
        // Switch to alternating color wipes on Rings1 and 2
        Ring1.ActivePattern = COLOR_WIPE;
        Ring2.ActivePattern = COLOR_WIPE;
        Ring2.TotalSteps = Ring2.numPixels();
        // And update tbe stick
        Stick.Update();
    }
    else // Back to normal operation
    {
        // Restore all pattern parameters to normal values
        Ring1.ActivePattern = THEATER_CHASE;
        Ring1.Interval = 100;
        Ring2.ActivePattern = RAINBOW_CYCLE;
        Ring2.TotalSteps = 255;
        Ring2.Interval = min(10, Ring2.Interval);
        // And update tbe stick
        Stick.Update();
    }    
}

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

// Ring1 Completion Callback
void Ring1Complete()
{
    if (digitalRead(9) == LOW)  // Button #2 pressed
    {
        // Alternate color-wipe patterns with Ring2
        Ring2.Interval = 40;
        Ring1.Color1 = Ring1.Wheel(random(255));
        Ring1.Interval = 20000;
    }
    else  // Retrn to normal
    {
      Ring1.Reverse();
    }
}

// Ring 2 Completion Callback
void Ring2Complete()
{
    if (digitalRead(9) == LOW)  // Button #2 pressed
    {
        // Alternate color-wipe patterns with Ring1
        Ring1.Interval = 20;
        Ring2.Color1 = Ring2.Wheel(random(255));
        Ring2.Interval = 20000;
    }
    else  // Retrn to normal
    {
        Ring2.RainbowCycle(random(0,10));
    }
}

// Stick Completion Callback
void StickComplete()
{
    // Random color change for next scan
    Stick.Color1 = Stick.Wheel(random(255));
}

So, Color1 is a 32 bit representation of a rgb color.

It is declared:

uint32_t Color1;