2812 LED strip operation-almost there

Good morning guys,
OK almost there-I'm wanting to use a button to A) start the switch case, B) Run thru each case based on the timer, C) return to the start and wait for another button press

Currently, the program waits until either A) press of the button (which will select a case one at a time) or B) holding down the button will cycle thru each case repeatedly until releasing the button.
Holding down the button is actually how I want the operation to act except instead of cycling, I want it return the wait state after one pass thru each case for me to push button again. (Also don't want to hold the button-just want to push it one time) Any suggestions? THANK YOU!


#include <WS2812FX.h>

#define Button 2
#define LED_COUNT 184 // Number of WS2812B LEDs
#define LED_PIN 6 // Pin connected to Data In (DIN)

int switchStatus;
int ButtonDelay = 500;
unsigned long ButtonTime = 0;


int showType = 0;
unsigned long patternInterval = 0; // time between steps in the pattern
unsigned long lastUpdate = 0; // for millis() when last update occurred
#define TIMER_MS 2000
unsigned long last_change = 0;
unsigned long now = 0;

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  pinMode(Button, INPUT_PULLUP);

  ws2812fx.init(); // Initialize WS2812FX library
  ws2812fx.setBrightness(50); // Brightness 0-255 [black to blinding]
  ws2812fx.setSpeed(2000); // Speed 10-5000 [fast to slow]
  ws2812fx.setColor(BLACK); // Set the color of the LEDs
  ws2812fx.strip_off(); // Start WS2812FX library

}

void loop()
{

  switchStatus = digitalRead(Button);   //
  if (digitalRead(Button) == LOW && millis() - ButtonTime > ButtonDelay)

  {
    ButtonTime = millis();
    startShow(showType);
    {
      if (millis() - now > TIMER_MS)
      {
        showType++;
        now = millis();   //keeps proper pattern switching intervals
        if (showType >= 5) // If case exceeds 5
        {
          showType = 0; // reset to case 0
        }
      }
    }

    ws2812fx.start();
  }

  ws2812fx.service();
}

void startShow(int showPattern)
{
  switch (showPattern)
  {

    case 0:  ws2812fx.resetSegments();  ws2812fx.resetSegmentRuntimes();
      ws2812fx.setSegment(0, 0, 97, FX_MODE_STATIC, PINK, 2000, false);
      break;

    case 1:  ws2812fx.resetSegments();  ws2812fx.resetSegmentRuntimes();
      ws2812fx.setSegment(0, 0, 97, FX_MODE_STATIC, PURPLE, 2000, false);
      break;
    case 2: ws2812fx.resetSegments(); ws2812fx.resetSegmentRuntimes();
      ws2812fx.setSegment(0, 0, 97, FX_MODE_STATIC, GREEN, 2000, false);
      break;
    case 3: ws2812fx.resetSegments(); ws2812fx.resetSegmentRuntimes();
      ws2812fx.setSegment(0, 0, 97, FX_MODE_STATIC, RED, 2000, false);
      break;
    case 4: ws2812fx.resetSegments(); ws2812fx.resetSegmentRuntimes();
      ws2812fx.setSegment(0, 0, 97, FX_MODE_STATIC, ORANGE, 2000, false);
      break;

  }
}

it is not really clear to me which functionality you want to have.
Somehow what you wrote sounds contradictory to me.

If you post a description like this it will become easy to understand

let's assume your code is showing pattern 0

short button press: switch to pattern 1 repeat pattern 1

long button press: switch to pattern 1 show pattern 1 once,
then switch to pattern 2 show pattern 2 once
then switch to pattern 3....

I guess this functionality is not exactly what you want. But this description shows how to describe it very precise to make it clear what you want.

You have a button and you have different button-press-duration
describe precise when do you press the button how long and what should happen

best regards Stefan

Hi StephanL38
Thanks for your reply . I would like to be able to press the button once, have it run thru each case, and then return and wait for me to press button again.

Right now, when I hold the button down (and don't release it), it continually runs thru all the cases (with the correct timing interval between each pattern). I'm wanting it to stop after case4 and return to the ready position. Hope this make sense

Use a boolean variable - ShowRunning perhaps. Use your button reading if to set the variable true.
Add an if to check the variable and if it's true, run your show logic. In the show logic, if showType is greater than 5, set the variable false.

Thanks wildbill

I will see if i can rewrite that.

so this means
power is on button is not pressed code waits for button-press
if button-press is detected
show pattern 1,
show pattern 2,
show pattern 3,
show pattern 4,

variable showType reached value 5

set boolean variable "RunShow" to value false

if variable RunShow has value false
wait for button-press
if button-press occures

set variable RunShow to value true
set showType to value 0

if variable RunShow has value true
call startShow(showType)

Your naming doe snot really reflect what the code inside does do

startShow not only "starts" the show it runs through the complete show
so a name like "showPattern() would explain it better

You are usingfixed numbers for each "show"
how about using constants with self-explaining names like

I don't know how your light-patterns are designed just a few example-names

const byte runningRed = 0

const byte horizontalRainBow = 1

const byte verticalBars = 2

then your switch-case looks like

  case runningRed:


  case horizontalRainBow: 

  case verticalBars: 

You will understand your own code much easier later if you use self-explaining names that really explain down the point what this part of the code is doing or what the purpose of a variable is.

best regards Stefan

Thanks for the guidance Stefan
I'll reconfigure this sketch. Probably won't be til later. Got get ready for the Halloween party : )
Thanks again

Hey Stefan

I appreciate your advice again. If I understand you correctly, I need to create another bool variable testing 2 scenarios AFTER the button is pushed? Something similiar to this sketch below? Can I use this as an example and incorporate what you said using this one? Want to make sure I'm not going down the wrong rabbit hole...

#include <WS2812FX.h>

#define LED_PIN    6  // digital pin used to drive the LED strip
#define LED_COUNT 240  // number of LEDs on the strip

const int buttonPin = 2;

WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);

  Serial.begin(115200);

  ws2812fx.init();
  ws2812fx.setBrightness(25);
  ws2812fx.setIdleSegment(0,  30, 50, FX_MODE_TRICOLOR_CHASE, COLORS(WHITE,RED,BLUE), 3000, false); // segment 0 is leds 0 - 9 0xFF0000-RED
  ws2812fx.setIdleSegment(1, 2, 20, FX_MODE_TRICOLOR_CHASE, COLORS(WHITE,RED,BLUE), 3000, false); // segment 1 is leds 10 - 19
}

void loop() {
  
  static bool blinkFlag = true;
  
  static int lastButtonState = digitalRead(buttonPin);
  int currButtonState = digitalRead(buttonPin);
  
  if (currButtonState != lastButtonState)
  {
    delay(50); // debounce
    lastButtonState = currButtonState;
    if (currButtonState == LOW)
    {
      if (blinkFlag)
      {
        blinkFlag = false;
        ws2812fx.stop();
        ws2812fx.addActiveSegment(0);
        ws2812fx.addActiveSegment(1);
        ws2812fx.start();
      }
      else
      {
        blinkFlag = true;
        ws2812fx.stop();
        ws2812fx.removeActiveSegment(1);
        ws2812fx.removeActiveSegment(0);
        ws2812fx.start();
      }
    }
    Serial.println(blinkFlag);
  }
  ws2812fx.service();
}