Button Press to run NeoPixel

Just a warning: this project got tossed on me and i am extremely new to the arduino. I have been working on this all day. I got the lighting sequence down since i can load the project without the button commands and it runs the lighting look once on start up. but i am have a difficult time with the button press.

When you press the button, 2 lights chase in a group of 8, for a duration of time and then go out. Pressing the button again would restart the sequence. With my failed button code, i can only get it to do it once within the first second.

#include <Adafruit_NeoPixel.h>

// Define pin to connect Neopixels to
#define PIN 6

//Define pin for pushbutton to connect to
const int BUTTON = 2;

//Initialize value to determine button press HIGH or LOW
int val = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN);

uint8_t  mode = 0, // Current animation effect
         offset = 1; // Position of spinny eyes
uint32_t color1  = 0x006688; // Light Blue
uint32_t color2  = 0x000000; // Black Out
uint32_t prevTime;

void setup() {
  pinMode(2, INPUT);
  strip.begin();
  //strip.setBrightness(85); // 1/3 brightness
  prevTime = millis();
}

void loop() {
  val = digitalRead(BUTTON);
  uint8_t  i;
  uint32_t t;

  if (val == HIGH) {
    switch(mode) {

       case 0: // Spinny wheels (8 LEDs on at a time)
        for(i=0; i<30; i++) {
        uint32_t c = 0;
        if(((offset + i) & 6) < 2) c = color1; // 4 pixels on...
         // if(((offset + i) & 5) < 2) c = color1; // 4 pixels on...
        strip.setPixelColor(   i, c); // First eye
        // strip.setPixelColor(31-i, c); // Second eye (flipped)
     
      }
      strip.show();
      offset++;
      delay(30);
      break;
    
      case 1: // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
      break;
    }

    t = millis();
    if((t - prevTime) > 2000) {      // Every 8 seconds...
      mode++;                        // Next mode
      if(mode > 2) {                 // End of modes?
        mode = 0;                    // Start modes over
        color1 >>= 16;                 // Next color R->G->B
        if(!color1) color1 = 0x000000; // Black Out
      }
      for(i=0; i<32; i++) strip.setPixelColor(i, 0);
      prevTime = t;
    }
  }
  
  else {
    // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
  }
}

Thanks for any assistance.

Take a look to this example:

I believe that your problem is this line:

  if (val == HIGH) {

Well i did discover that the "val == HIGH" required the button to be held down to work, so i changed that to low (button release), but i still can't get it to work past it's initial start up. I think need to latch the value to 1 or HIGH at the beginning of my lighting sequence, and then release it afterwards


I don't see anything in particular after going over the content in the link provided about the button. I am trying to implement the lastButtonState as a way to physical release the button and still have the code run out until complete.

Yes. That sound much better. You need to do 2 things.
1st- don't read the HIGH button but the transition from LOW to HIGH like they do in the example;
2nd- in that state you must start the sequence and do that sequence until the end, once you end the sequence you will need to sense that transition from LOW to HIGH to start again.

AGH, My code is looking worse and worse.

Well the lighting sequence runs at start up which is fine, but I still can't get anything to happen with the button press

#include <Adafruit_NeoPixel.h>

// Define pin to connect Neopixels to
#define PIN 6

//Define pin for pushbutton to connect to
const int buttonPin = 2;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN);

uint8_t  mode = 0, // Current animation effect
         offset = 1; // Position of spinny eyes
uint32_t color1  = 0x006688; // Light Blue
uint32_t color2  = 0x000000; // Black Out
uint32_t prevTime;

void setup() {
  pinMode(buttonPin, INPUT);
  strip.begin();
  //strip.setBrightness(85); // 1/3 brightness
  prevTime = millis();
}

void loop() {
  buttonState = digitalRead(buttonPin);
  uint8_t  i;
  uint32_t t;

  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    }
      // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
    }
  else  {
  switch(mode) {
  case 0: // Spinny wheels (8 LEDs on at a time)
        for(i=0; i<30; i++) {
        uint32_t c = 0;
        if(((offset + i) & 6) < 2) c = color1; // 2 pixels on...
         // if(((offset + i) & 5) < 2) c = color1; // 4 pixels on...
        strip.setPixelColor(i, c); // First eye
        // strip.setPixelColor(31-i, c); // Second eye (flipped)
     
      }
      strip.show();
      offset++;
      delay(30);
      break;
      
      // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
    }

    t = millis();
    if((t - prevTime) > 2000) {      // Every 8 seconds...
      mode++;                        // Next mode
      if(mode > 2) {                 // End of modes?
        mode = 0;                    // Start modes over
        color1 >>= 16;                 // Next color R->G->B
        if(!color1) color1 = 0x000000; // Black Out
      }
      for(i=0; i<132; i++) strip.setPixelColor(i, 0);
      prevTime = t;
    }
  }
  lastButtonState = buttonState;
}

Ok, i almost have it...

I just can't get it to start up again when i push the button a second or more times.

#include <Adafruit_NeoPixel.h>

// Define pin to connect Neopixels to
#define PIN 6

//Define pin for pushbutton to connect to
const int buttonPin = 2;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN);

uint8_t  mode = 0, // Current animation effect
         offset = 1; // Position of spinny eyes
uint32_t color1  = 0x006688; // Light Blue
uint32_t color2  = 0x000000; // Black Out
uint32_t prevTime;

void setup() {
  pinMode(buttonPin, INPUT);
  strip.begin();
  //strip.setBrightness(85); // 1/3 brightness
  prevTime = millis();
}

void loop() {
  buttonState = digitalRead(buttonPin);
  uint8_t  i;
  uint32_t t;

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  
  // turns on the LED every four button pushes by 
  // checking the modulo of the button push counter.
  // the modulo function gives you the remainder of 
  // the division of two numbers:
  if (buttonPushCounter % 4 == 0) {
    
    // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
    }
  
  else {
    switch(mode) {

        case 0: // Spinny wheels (8 LEDs on at a time)
        for(i=0; i<30; i++) {
        uint32_t c = 0;
        if(((offset + i) & 6) < 2) c = color1; // 2 pixels on...
         // if(((offset + i) & 5) < 2) c = color1; // 4 pixels on...
        strip.setPixelColor(i, c); // First eye
        // strip.setPixelColor(31-i, c); // Second eye (flipped)
     
      }
      strip.show();
      offset++;
      delay(30);
      break;
      
      case 1: // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
    }

    t = millis();
    if((t - prevTime) > 2000) {      // Every 8 seconds...
      mode++;                        // Next mode
      if(mode > 2) {                 // End of modes?
        mode = 0;                    // Start modes over
        color1 >>= 16;                 // Next color R->G->B
        if(!color1) color1 = 0x000000; // Black Out
      }
      for(i=0; i<132; i++) strip.setPixelColor(i, 0);
      prevTime = t;
    }
  }
}

I don't like these lines:

      if(mode > 2) {                 // End of modes?
        mode = 0;                    // Start modes over
        color1 >>= 16;                 // Next color R->G->B
        if(!color1) color1 = 0x000000; // Black Out
      }

You only have 2 states (the state 0 and the state 1) but you only change state when the state is greater than 2. That is you will have one state (the state 2 if you want) that the system don't do anything.

What I will do was create a variable, for example turn_on that goes true when the button change his state and goes off at the end of the sequence, for example:

#include <Adafruit_NeoPixel.h>

// Define pin to connect Neopixels to
#define PIN 6

//Define pin for pushbutton to connect to
const int buttonPin = 2;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN);

uint8_t  mode = 0, // Current animation effect
         offset = 1; // Position of spinny eyes
uint32_t color1  = 0x006688; // Light Blue
uint32_t color2  = 0x000000; // Black Out
uint32_t prevTime;

boolean turn_on=false;

void setup() {
  pinMode(buttonPin, INPUT);
  strip.begin();
  //strip.setBrightness(85); // 1/3 brightness
  prevTime = millis();
}

void loop() {
  buttonState = digitalRead(buttonPin);
  uint8_t  i;
  uint32_t t;

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
       turn_on = true;
    } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

  
  // turns on the LED every four button pushes by 
  // checking the modulo of the button push counter.
  // the modulo function gives you the remainder of 
  // the division of two numbers:
  if (buttonPushCounter % 4 == 0) {
    
    // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
    }
  
  else {
  }
   if (turn_on == true) {
    switch(mode) {

        case 0: // Spinny wheels (8 LEDs on at a time)
        for(i=0; i<30; i++) {
        uint32_t c = 0;
        if(((offset + i) & 6) < 2) c = color1; // 2 pixels on...
         // if(((offset + i) & 5) < 2) c = color1; // 4 pixels on...
        strip.setPixelColor(i, c); // First eye
        // strip.setPixelColor(31-i, c); // Second eye (flipped)
     
      }
      strip.show();
      offset++;
      delay(30);
      break;
      
      case 1: // Black Out
      strip.setPixelColor(i, 0);
      strip.show();
    }

    t = millis();
    if((t - prevTime) > 2000) {      // Every 8 seconds...
      mode++;                        // Next mode
      if(mode > 2) {                 // End of modes?
        mode = 0;                    // Start modes over
        color1 >>= 16;                 // Next color R->G->B
        if(!color1) color1 = 0x000000; // Black Out
        turn_on = false;
      }
      for(i=0; i<132; i++) strip.setPixelColor(i, 0);
      prevTime = t;
    }
  }
}

So i rewrote the code using boolean and added LedPin 13 to show status of the button/action.

I figured out that the lighting look was working, but was running the black out sequence instead, and i even got the button to to start the lighting.

Thank you

#include <Adafruit_NeoPixel.h>

// Define pin to connect Neopixels to
#define PIN 6

//Define pin for pushbutton to connect to
const int buttonPin = 2;
const int ledPin = 13;

// Variables will change:
int buttonState = 0;         // current state of the button

Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN);

uint8_t  mode = 1, // Current animation effect
         offset = 0; // Position of spinny eyes
uint32_t color1  = 0x006688; // Light Blue
uint32_t prevTime;

boolean turn_on=false;

void setup() {
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  strip.begin();
  prevTime = millis();
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    turn_on = true;
  } 
  else {
  }
    
  uint8_t  i;
  uint32_t t;

  if (turn_on == true) {
    digitalWrite(ledPin, HIGH);
    switch(mode) {
 
   case 0: // Spinny wheels (8 LEDs on at a time)
    for(i=0; i<30; i++) {
      uint32_t c = 0;
      if(((offset + i) & 6) < 2) c = color1; // 2 pixels on...
       // if(((offset + i) & 5) < 2) c = color1; // 4 pixels on...
      strip.setPixelColor(   i, c); // First eye
     // strip.setPixelColor(31-i, c); // Second eye (flipped)
    }
    
    strip.show();
    offset++;
    delay(30);
    break;
     
    case 1: // Black Out
      strip.show();
      turn_on = false;
      digitalWrite(ledPin, LOW);
  }

  t = millis();
  if((t - prevTime) > 1000) {      // Every 8 seconds...
    mode++;                        // Next mode
    if(mode > 1) {                 // End of modes?
      mode = 0;                    // Start modes over
    }
    for(i=0; i<32; i++) strip.setPixelColor(i, 0);
    prevTime = t;
  }
}
}

Why you remove the verification of change of the state of the button? I think is a better way to detect a button press than that you have.

If I understand right the problem was the:

      if(mode > 2) {                 // End of modes?

right?

I changed that portion of the code because it responded faster. originally, i had case 0, case 1, and case 2, i would have used the code you stated, but since i removed the sparkle lighting effect (case 0) and renumbered them, i changed mode to > 1. after the button press with mode > 2, the led lighting took about 1/2 second to start, and as mode > 1 it starts right when the button is pressed.

Now they want to see it fade out, but i don't want to try to figure that out just yet.