0

Multiple NeoPixel Strips
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Multiple NeoPixel Strips

by joshuakane on Wed Aug 09, 2017 9:04 am

Hello,

I am following the guide on multitasking with the arduino for LED Strips

I have one strip using the scanner function, and I am trying to get a second one to light up the pixles on the strip with a delay between each of them, then extinguish them in the reverse order, kind of like counting up and then counting down. I created two functions for this and can do it with a single strip, but I am having trouble wrapping my head around how to incorporate it into the "PATTERN" and "UPDATE" logic of the example code.

Here are the two functions I created, based on ColorWipe

Color Wipe
Code: Select all | TOGGLE FULL SIZE
void colorWipe(uint32_t c, uint8_t wait)
{
    for (uint16_t i = 0; i < strip.numPixels(); i++)
    {
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
    }
}


Reverse ColorWipe
Code: Select all | TOGGLE FULL SIZE
void ReverseColorWipe(uint32_t c, uint8_t wait)
{
    for (int i = (strip.numPixels() - 1); i >= 0; i--)
    {
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
    }
}



Is it as simple as doing something like this?

Code: Select all | TOGGLE FULL SIZE
    // Initialize for a Count Up/Down
    void CountUpDown(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = COUNT_UPDOWN;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = color1;
        Color2 = color2;
        Index = 0;
        Direction = dir;
   }
   
    // Update the CountUpDown Pattern
    void CountUpDownUpdate()
    {
        for (int i=0; i < numPixels(); i++)
        {
           setPixelColor(i, Color1);
          delay(120);
          }
            else (int i=0; i < numPixels(); i--)
           {
                setPixelColor(i, Color2);
                delay(120);
            }
        }
        show();
        Increment();
    }

joshuakane
 
Posts: 266
Joined: Sat Apr 13, 2013 4:40 pm

Re: Multiple NeoPixel Strips

by adafruit_support_bill on Wed Aug 09, 2017 9:17 am

If you start from the first tutorial in the series, it explains that the first thing that you need to do is eliminate all calls to delay in all parts of your code. Everything stops during a delay, so multitasking is impossible. You need to do all of your timing using millis().

https://learn.adafruit.com/multi-taskin ... -the-delay

adafruit_support_bill
 
Posts: 63408
Joined: Sat Feb 07, 2009 10:11 am

Re: Multiple NeoPixel Strips

by joshuakane on Wed Aug 09, 2017 10:22 am

I went with this, but I can't get the strip to light up.


Code: Select all | TOGGLE FULL SIZE
// Initialize for a Count Up/Down
    void CountUpDown(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = COUNT_UPDOWN;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = color1;
        Color2 = color2;
        Index = 0;
        Direction = dir;
   }
   
    // Update the CountUpDown Pattern
  void CountUpDownUpdate()
  {
   int i = 0;
   if((Forward = true) && (currentMillis - previousMillis >= WaitTime))
          {
             setPixelColor(i, Color1);
             i++;
             if (i == 15){
               Forward = false;
             }         
          }
         
    if((Forward = false) && (currentMillis - previousMillis >= WaitTime))
          {
             setPixelColor(i, Color1);
             i--;
             if (i == 0){
               Forward = true;
             }         
          } 
  }

joshuakane
 
Posts: 266
Joined: Sat Apr 13, 2013 4:40 pm

Re: Multiple NeoPixel Strips

by adafruit_support_bill on Wed Aug 09, 2017 11:17 am

I can't get the strip to light up.

Your Update function does not call show() or Increment().

adafruit_support_bill
 
Posts: 63408
Joined: Sat Feb 07, 2009 10:11 am

Re: Multiple NeoPixel Strips

by joshuakane on Wed Aug 09, 2017 2:02 pm

I realized that and as I was coming back to edit the code, I saw you replied. I added them, and have tried them in several places in the loop and still have not met with success. Any assistance would be greatly appreciated.

Code: Select all | TOGGLE FULL SIZE
    // Update the CountUpDown Pattern
// Initialize for a Count Up/Down
    void CountUpDown(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = COUNT_UPDOWN;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = color1;
        Color2 = color2;
        Index = 0;
        Direction = dir;
   }

  void CountUpDownUpdate()
  {
   int i = 0;
    unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;   
   if((UpDown = true) && (currentMillis - previousMillis >= WaitTime))
          {
             setPixelColor(i, Color1);
             if (i == 15){
               UpDown = false;
           }         
          }   
           if((UpDown = false) && (currentMillis - previousMillis >= WaitTime))
          {
             setPixelColor(i, Color2);
             i--;
             if (i == 0){
               UpDown = true;
             }         
          }
  }
     show();
     Increment();
  } 

joshuakane
 
Posts: 266
Joined: Sat Apr 13, 2013 4:40 pm

Re: Multiple NeoPixel Strips

by adafruit_support_bill on Wed Aug 09, 2017 2:14 pm

Where is UpDown defined? Please post the whole code.

adafruit_support_bill
 
Posts: 63408
Joined: Sat Feb 07, 2009 10:11 am

Re: Multiple NeoPixel Strips

by joshuakane on Wed Aug 09, 2017 2:19 pm

Here you go Bill,

This is the complete file

Code: Select all | TOGGLE FULL SIZE
#include <Adafruit_NeoPixel.h>


//---------------------------------BEGIN Yondu LIGHTING SECTION--------------------------------------------------------//
// Pattern types
enum  pattern { NONE, RAINBOW_CYCLE, SCANNER, COUNT_UPDOWN};
// Patern directions


enum  direction { FORWARD, REVERSE };


class YonduPatterns : 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

    bool red, green, blue;
   
    unsigned long previousMillis = 0;        // will store last time LED Strip was updated
    long WaitTime = 120          ;           // milliseconds of Wait Time
    long interval = 1000;
    // check to see if it's time to change the state of the LED
    unsigned long currentMillis = millis();
    bool UpDown = true;
   

   
    // Constructor
    YonduPatterns(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;
               case COUNT_UPDOWN:
                    CountUpDownUpdate();
                    break;                   
                default:
                    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();
    }

    // Update the CountUpDown Pattern
// Initialize for a Count Up/Down
    void CountUpDown(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = COUNT_UPDOWN;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = color1;
        Color2 = color2;
        Index = 0;
        Direction = dir;
   }

  void CountUpDownUpdate()
  {
   int i = 0;
    unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;   
   if((UpDown = true) && (currentMillis - previousMillis >= WaitTime))
          {
             setPixelColor(i, Color1);
             if (i == 15){
               UpDown = false;
           }         
          }   
           if((UpDown = false) && (currentMillis - previousMillis >= WaitTime))
          {
             setPixelColor(i, Color2);
             i--;
             if (i == 0){
               UpDown = true;
             }         
          }
  }
     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, 255,0,0);
            }
        }
        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) >> 2, Green(color) >> 2, Blue(color) >> 2);
        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);
        }
    }
};


//---------------------------------- END Yondu Lighting SECTION ------------------------------------

#define UP 0
#define DOWN 1



// Define some YonduPatterns for the Radar, Jolo Projector, Side lights and PSI
YonduPatterns Radar(11, 5, NEO_GRB + NEO_KHZ800); //radar has 7 LEDs in it and will be controlled on pin 5
YonduPatterns Side(15, 9, NEO_GRB + NEO_KHZ800);  //Side sections  have 15 LEDs in it and will be controlled on pin 9


// Initialize everything and prepare to start
void setup()
{
    //initialize all our LED sections
    Radar.begin();
    Side.begin();
    Radar.setPixelColor(0, 255,0,0);
    Radar.setPixelColor(1, 255,0,0);
    Radar.setPixelColor(2, 255,0,0);
    Radar.setPixelColor(3, 255,0,0);
    Radar.setPixelColor(4, 255,0,0);
    Radar.setPixelColor(5, 255,0,0);
    Radar.setPixelColor(6, 255,0,0);
    Radar.setPixelColor(7, 255,0,0);
    Radar.setPixelColor(8, 255,0,0);
    Radar.setPixelColor(9, 255,0,0);
    Radar.setPixelColor(10, 255,0,0);
    Radar.setPixelColor(11, 255,0,0);
    Radar.Update();
    Radar.show();
    delay(3000);
    // Kick off a pattern

    Radar.Scanner(Radar.Color(255, 255, 0), 50); // Radar scans Cylon style red with 100ms interval;
    Side.CountUpDown(Side.Color(255, 0, 0), Side.Color(255, 0, 0),0 ,FORWARD); //Count up and down in red
   
}

// Main loop
void loop()
{
Radar.Update();
Side.Update();
}


joshuakane
 
Posts: 266
Joined: Sat Apr 13, 2013 4:40 pm

Re: Multiple NeoPixel Strips

by adafruit_support_bill on Wed Aug 09, 2017 2:56 pm

A couple of examples of a very common C/C++ programming error:

if((UpDown = true) && (currentMillis - previousMillis >= WaitTime))

if((UpDown = false) && (currentMillis - previousMillis >= WaitTime))

The "=" operator is the assignment operator. What you want here is the "==" comparison operator.

adafruit_support_bill
 
Posts: 63408
Joined: Sat Feb 07, 2009 10:11 am

Re: Multiple NeoPixel Strips

by joshuakane on Thu Aug 10, 2017 2:14 pm

Thank you Bill,

I did some more reading, and found a way to make it functional for my needs. Here was the final code I used.


Code: Select all | TOGGLE FULL SIZE
// Initialize for a Count Up/Down
    void CountUpDown(uint32_t color1, uint32_t color2, uint8_t interval, direction dir = FORWARD)
    {
        ActivePattern = COUNT_UPDOWN;
        Interval = interval;
        TotalSteps = numPixels();
        Color1 = color1;
        Color2 = color2;
        Index = 0;
        Direction = dir;
   }

  void CountUpDownUpdate()
  {
    if ((unsigned long)(millis() - previousMillis) >= interval) {
    previousMillis = millis();
        if((UpDown == true))
          {
            setPixelColor(i, Color1);
            Serial.print ("the vlaue of i is ");
            Serial.println (i);
            i++;
            show();
            Increment(); 
             if (i == 15){
               UpDown = false;
           }
          }           
           if((UpDown == false))
          {
             setPixelColor(i, Color2);
             i--;
             show();
             Increment(); 
             if (i == 0){
               UpDown = true;
             }         
          }

}
    } 

joshuakane
 
Posts: 266
Joined: Sat Apr 13, 2013 4:40 pm

Re: Multiple NeoPixel Strips

by adafruit_support_bill on Thu Aug 10, 2017 2:28 pm

Good to hear it is working. Thanks for the follow-up.

adafruit_support_bill
 
Posts: 63408
Joined: Sat Feb 07, 2009 10:11 am

Please be positive and constructive with your questions and comments.