0

Two Buttons, Two NeoPixel Strips, Two Actions - Code Help
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Two Buttons, Two NeoPixel Strips, Two Actions - Code Help

by gavinchilly on Wed Aug 07, 2019 3:43 am

Hi ALL! Hope you can help me with my coding issue!

I'm by no means a coder, but know enough to tinker.
I took code that works for ONE button, for ONE Neopixel strip and just duplicated everything, thinking that would work:
BUTTON_PIN is now BUTTON_PIN1 & BUTTON_PIN2
strip is now strip1 & strip2
...etc.

Well, its not working - it compiles and verifies, but..
Pretty much strip1 and strip2 are doing the same thing..running through 'startShow1'

If ANYONE can help me out, I would be forever in your debt and will give credit where credit is due!

Here is the code
Code: Select all | TOGGLE FULL SIZE
//PROBLEM the code is not seeing NeoPixelStrip 1 seperate from Strip 2
#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN1   3     
#define PIXEL_PIN1    1   
#define PIXEL_COUNT1 5

#define BUTTON_PIN2   4     
#define PIXEL_PIN2    2   
#define PIXEL_COUNT2 4


Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(PIXEL_COUNT1, PIXEL_PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(PIXEL_COUNT2, PIXEL_PIN2, NEO_GRB + NEO_KHZ800);

bool oldState1 = HIGH;
bool oldState2 = HIGH;
int showType1 = 0;
int showType2 = 0;

//Neopixel strip 1 on pin 1
void setup() {
  pinMode(BUTTON_PIN1, INPUT_PULLUP);
  strip1.begin();
  strip1.show(); // Initialize all pixels in strip1 to 'green'
  colorWipe(0, 1, strip1.Color(0, 255, 0), 10 ); //  green
  delay(200);
  colorWipe(0, 2, strip1.Color(0, 255, 0), 10 ); //  green
  delay(400);
  colorWipe(0, 3, strip1.Color(0, 255, 0), 10 ); //  green
  delay(600);
  colorWipe(0, 4, strip1.Color(0, 255, 0), 10 ); //  green
  delay(1000);
  colorWipe(0, 5, strip1.Color(0, 255, 0), 10 ); //  green



  pinMode(BUTTON_PIN2, INPUT_PULLUP);
  strip2.begin();
  strip2.show(); // Initialize all pixels in strip 2 to 'red'
  colorWipe(0, 1, strip2.Color(255, 0, 0), 10 ); //  red
  delay(200);
  colorWipe(0, 2, strip2.Color(255, 0, 0), 10 ); //  red
  delay(400);
  colorWipe(0, 3, strip2.Color(255, 0, 0), 10 ); //  red
  delay(600);
  colorWipe(0, 4, strip2.Color(255, 0, 0), 10 ); //  red
  delay(1000);
  colorWipe(0, 5, strip2.Color(255, 0, 0), 10 ); //  red

 
}


void loop() {
  // Get current button state.
  bool newState1 = digitalRead(BUTTON_PIN1);
 
  // Check if state changed from high to low (button press).
  if (newState1 == LOW && oldState1 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState1 = digitalRead(BUTTON_PIN1);
    if (newState1 == LOW) {
      showType1++;
      if (showType1 > 6)
        showType1=0;
      startShow1(showType1);
    }
  }

 // Get current button state.
  bool newState2 = digitalRead(BUTTON_PIN2);
 
  // 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(BUTTON_PIN2);
    if (newState2 == LOW) {
      showType2++;
      if (showType2 > 2)
        showType2=0;
      startShow2(showType2);
    }
  }
  // Set the last button state to the old state.
  oldState1 = newState1;
  oldState2 = newState2;
}

void startShow1(int i) {
  switch(i){
   
       case 0:
              //sub-name(starting LED, ending LED, color, wait??)
              colorWipe(0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              colorWipe(0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(0, 5, strip1.Color(0, 255, 0), 10 ); //  green
              colorWipe(0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(0, 5, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 1:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(0, 4, strip1.Color(0, 255, 0), 10 ); //     green
              break;
       case 2:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(0, 3, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 3:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(0, 2, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 4:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(0, 1, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 5:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              break;
       case 6:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              colorWipe(0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              colorWipe(0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              break;
       
      }
}

void startShow2(int i) {
  switch(i){
   
       case 0:
              //sub-name(starting LED, ending LED, color, wait??)
              colorWipe(0, 4, strip2.Color(255, 0, 255), 10 ); //  purple
              colorWipe(0, 4, strip2.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(0, 4, strip2.Color(255, 0, 255), 10 ); //  purple
              colorWipe(0, 4, strip2.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(0, 4, strip2.Color(255, 0, 255), 10 ); //  purple
              break;
       case 1:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 4, strip2.Color(255, 255, 0), 10 ); // yellow
              colorWipe(0, 4, strip2.Color(255, 0, 255), 10 ); //  purple
              break;
       case 2:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(0, 4, strip2.Color(255, 255, 0), 10 ); // yellow
              colorWipe(0, 3, strip2.Color(0, 255, 0), 10 ); //  green
              break;
       
      }
}


// Fill the dots one after the other with a color
void colorWipe(int start, int end, uint32_t c, uint8_t wait)
{
  for(uint16_t i = start; i < end; i++)
  {
    strip1.setPixelColor(i, c);
    strip2.setPixelColor(i, c);
    strip1.show();
    strip2.show();
    delay(20);
  }
}

gavinchilly
 
Posts: 8
Joined: Tue Sep 25, 2018 5:28 pm

Re: Two Buttons, Two NeoPixel Strips, Two Actions - Code Hel

by adafruit_support_bill on Wed Aug 07, 2019 6:31 am

The problem is here in your colorWipe function:
Code: Select all | TOGGLE FULL SIZE
// Fill the dots one after the other with a color
void colorWipe(int start, int end, uint32_t c, uint8_t wait)
{
  for(uint16_t i = start; i < end; i++)
  {
    strip1.setPixelColor(i, c);
    strip2.setPixelColor(i, c);
    strip1.show();
    strip2.show();
    delay(20);
  }
}


Every time you call it, it will do the same thing for both strip1 and strip2.

If you modify it like this:
Code: Select all | TOGGLE FULL SIZE
// Fill the dots one after the other with a color
void colorWipe(Adafruit_NeoPixel& strip, int start, int end, uint32_t c, uint8_t wait)
{
  for(uint16_t i = start; i < end; i++)
  {
    strip.setPixelColor(i, c);
    strip.show();
    delay(20);
  }
}

You can specify the strip you want it to work on as in:

colorWipe(strip1, 0, 4, strip2.Color(255, 255, 0), 10 ); // yellow
or
colorWipe(strip2, 0, 4, strip2.Color(255, 255, 0), 10 ); // yellow

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

Re: Two Buttons, Two NeoPixel Strips, Two Actions - Code Hel

by gavinchilly on Thu Aug 08, 2019 4:59 pm

Thanks Very Much!
That did get me going for the most part. Now both strips are running through the cases, but still they are not controlled by the two buttons.
I was looking to have one button control one light and another to control another light. One has a colorWipe, the other is a theaterChase.

I've updated the code on your recommendations and tweaked it a bit, but still only one button will work for the one LED strip.

Code: Select all | TOGGLE FULL SIZE

#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN1   3     
#define PIXEL_PIN1    1   
#define PIXEL_COUNT1 5

#define BUTTON_PIN2   4     
#define PIXEL_PIN2    2   
#define PIXEL_COUNT2 4


Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(PIXEL_COUNT1, PIXEL_PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(PIXEL_COUNT2, PIXEL_PIN2, NEO_GRB + NEO_KHZ800);

bool oldState1 = HIGH;
bool oldState2 = HIGH;
int showType1 = 0;
int showType2 = 0;

//!!!!!!!!!!!Setup - a colorWipe on Strip1 and Strip2 like a "loading process" for the prop
void setup() {
  pinMode(BUTTON_PIN1, INPUT_PULLUP);
  strip1.begin();
  strip1.show(); // Initialize all pixels in strip1 to 'green'
  colorWipe(strip1, 0, 1, strip1.Color(0, 255, 0), 10 ); //  green
  delay(200);
  colorWipe(strip1, 0, 2, strip1.Color(0, 255, 0), 10 ); //  green
  delay(400);
  colorWipe(strip1, 0, 3, strip1.Color(0, 255, 0), 10 ); //  green
  delay(600);
  colorWipe(strip1, 0, 4, strip1.Color(0, 255, 0), 10 ); //  green
  delay(1000);
  colorWipe(strip1, 0, 5, strip1.Color(0, 255, 0), 10 ); //  green



  pinMode(BUTTON_PIN2, INPUT_PULLUP);
  strip2.begin();
  strip2.show(); // Initialize all pixels in strip 2 to 'red'
  colorWipe(strip2, 0, 1, strip2.Color(255, 0, 0), 10 ); //  red
  delay(200);
  colorWipe(strip2, 0, 2, strip2.Color(255, 0, 0), 10 ); //  red
  delay(400);
  colorWipe(strip2, 0, 3, strip2.Color(255, 0, 0), 10 ); //  red
  delay(600);
  colorWipe(strip2, 0, 4, strip2.Color(255, 0, 0), 10 ); //  red
 
}

//!!!!!!!!!!!Two IF statments in one loop() - is that a problem?
void loop() {
  // Get current button state.
  bool newState1 = digitalRead(BUTTON_PIN1);
 
  // Check if state changed from high to low (button press).
  if (newState1 == LOW && oldState1 == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState1 = digitalRead(BUTTON_PIN1);
    if (newState1 == LOW) {
      showType1++;
      if (showType1 > 6)
        showType1=0;
      startShow1(showType1);
    }
  }

 // Get current button state.
  bool newState2 = digitalRead(BUTTON_PIN2);
 
  // 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(BUTTON_PIN2);
    if (newState2 == LOW) {
      showType2++;
      if (showType2 > 2)
        showType2=0;
      startShow2(showType2);
    }
  }
  // Set the last button state to the old state.
  oldState1 = newState1;
  oldState2 = newState2;
}

//!!!!!!!!!!!This should be started when button 1 is hit, and it does-works great!!
void startShow1(int i) {
  switch(i){
              //colorWipe(strip1, 0, 4, strip1.Color(255, 255, 0), 10 ); // yellow
       case 0:
              //sub-name(starting LED, ending LED, color, wait??)
              colorWipe(strip1, 0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              colorWipe(strip1, 0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(strip1, 0, 5, strip1.Color(0, 255, 0), 10 ); //  green
              colorWipe(strip1, 0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(strip1, 0, 5, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 1:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(strip1, 0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(strip1, 0, 4, strip1.Color(0, 255, 0), 10 ); //     green
              break;
       case 2:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(strip1, 0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(strip1, 0, 3, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 3:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(strip1, 0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(strip1, 0, 2, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 4:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(strip1, 0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              colorWipe(strip1, 0, 1, strip1.Color(0, 255, 0), 10 ); //  green
              break;
       case 5:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(strip1, 0, 5, strip1.Color(255, 255, 0), 10 ); // yellow
              break;
       case 6:
              //sub-name(starting LED, ending LED, color, wait??)
              delay(100);
              colorWipe(strip1, 0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              colorWipe(strip1, 0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(strip1, 0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              colorWipe(strip1, 0, 5, strip1.Color(0, 0, 0), 10 ); //  off/black
              colorWipe(strip1, 0, 5, strip1.Color(255, 0, 0), 10 ); //  red
              break;
       
      }
}

//!!!!!!!!!!!This should be started when button 2 is hit, it does not. If I groud button 1 to button 2,
//SOMTIMES it will trigger this.
void startShow2(int i) {
  {
  theaterChase(strip2.Color(255,   0,   0), 50); // Red
  theaterChase(strip2.Color(255,   0,   0), 100); // Red
  theaterChase(strip2.Color(255,   0,  0), 500); // Red
  colorWipe(strip2, 0, 4, strip2.Color(255, 0, 0), 5); // red
  //delay(30000);
   
      }
}


// Fill the dots one after the other with a color
void colorWipe(Adafruit_NeoPixel& strip, int start, int end, uint32_t c, uint8_t wait)
{
  for(uint16_t i = start; i < end; i++)
  {
    strip.setPixelColor(i, c);
    strip.show();
    delay(20);
  }
}


//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 4; q++) {
      for (int i=0; i < strip2.numPixels(); i=i+4) {
        strip2.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip2.show();
     
      delay(wait);
     
      for (int i=0; i < strip2.numPixels(); i=i+4) {
        strip2.setPixelColor(i+q, 0);        //turn every fourth pixel off
      }
    }
  }
}


THANKS!!
Last edited by gavinchilly on Thu Aug 08, 2019 5:07 pm, edited 1 time in total.

gavinchilly
 
Posts: 8
Joined: Tue Sep 25, 2018 5:28 pm

Re: Two Buttons, Two NeoPixel Strips, Two Actions - Code Hel

by adafruit_support_bill on Thu Aug 08, 2019 5:06 pm

Most likely, the problem you are seeing is due to the fact that the Arduino can only do one thing at a time, so the button input is ignored until you finish with the 'startShow()'.

The solution to this involves some re-structuring of the code. This series of guides shows how. Part 3 deals specifically with Neopixels.

https://learn.adafruit.com/multi-taskin ... 1/overview
https://learn.adafruit.com/multi-taskin ... 2/overview
https://learn.adafruit.com/multi-taskin ... 3/overview

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

Re: Two Buttons, Two NeoPixel Strips, Two Actions - Code Hel

by gavinchilly on Fri Aug 23, 2019 2:21 pm

thanks!
I tried to go to the last page to get all the code and just tried to load it on the Trinket, and it ran out of memory.
I am going to read through all the instructions to get more familiure with the process..and I'm going to use a Trinket MO with a bit more memory next time.

I happened upon this lil gem on Adafruit: DS2413 1-Wire Two GPIO Controller Breakout.
https://www.adafruit.com/product/1551?f ... H63Eah4X6U

Would this help me with controlling two Neostrips with one button?

gavinchilly
 
Posts: 8
Joined: Tue Sep 25, 2018 5:28 pm

Re: Two Buttons, Two NeoPixel Strips, Two Actions - Code Hel

by adafruit_support_bill on Fri Aug 23, 2019 2:34 pm

The original Trinket has very limited memory. The M0 version will give you a lot more room.

I happened upon this lil gem on Adafruit: DS2413 1-Wire Two GPIO Controller Breakout.
Would this help me with controlling two Neostrips with one button?

Not really. With just one button, you are better off connecting it directly.

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

Re: Two Buttons, Two NeoPixel Strips, Two Actions - Code Hel

by Grey_Area on Sat Sep 07, 2019 6:10 am

With a bit of extra work and using "millis()" you could probably get the two strips to work off one button - one responding to a short press, the other to a long press. Or a double press if you're feeling creative!

Grey_Area
 
Posts: 26
Joined: Tue Dec 12, 2017 8:54 am

Please be positive and constructive with your questions and comments.