[Solved] Trouble turning addressable LED strip off/on

I've copied some code for a clock with an RTC and also some code to switch between the modes of an LED strip. My aim for this project is to be able to change the mode on an LED strip with a button, have the whole strip turn off when it is dark, then turn back on when the light comes back on, this is all with a clock running in the background. I'm having trouble with turning the strip back on when the light turns on again. I am using an Elegoo Uno R3 and the LED strip is WS2812B and is 3 pin (I am using the NeoPixel library), here is a link: https://www.amazon.co.uk/gp/product/B08L8X7Z4P/ref=ox_sc_act_title_3?smid=A2QAK0OPJGGPMM&psc=1

Any help would be appreciated, here is my code:

#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN   7    // Digital IO pin connected to the button.  This will be
                          // driven with a pull-up resistor so the switch should
                          // pull the pin to ground momentarily.  On a high -> low
                          // transition the button press logic will execute.

#define PIXEL_PIN    6   // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 57   // number of neopixel (change this accordingly)

// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;

// Include the libraries:
#include "RTClib.h"
#include <TM1637Display.h>

// Define the connections pins:
#define CLK 2
#define DIO 3

// Create rtc and display object:
RTC_DS3231 rtc;
TM1637Display display = TM1637Display(CLK, DIO);
int light=0;

void setup() {
  // Begin serial communication at a baud rate of 9600:
  Serial.begin(9600);
  

  // Check if RTC is connected correctly:
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  // Check if the RTC lost power and if so, set the time:
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // The following line sets the RTC to the date & time this sketch was compiled:
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  // Set the display brightness (0-7):
  display.setBrightness(5);
  // Clear the display:
  display.clear();

pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

strip.setBrightness(100);
}

void loop() {
  // Get current date and time:
  DateTime now = rtc.now();

  // Create time format to display:
  int displaytime = (now.hour() * 100) + now.minute();

  // Print displaytime to the Serial Monitor:
  Serial.println(displaytime);

  // Display the current time in 24 hour format with leading zeros enabled and a center colon:
  display.showNumberDecEx(displaytime, 0b11100000, true);

  // Get current button state.
  bool newState = digitalRead(BUTTON_PIN);

void startShow(int i);
light = analogRead(A0); // read and save value from PR
Serial.println(light);
   if(light < 150){ //While the light is off, stay in this loop
     strip.show();
       }
   else{ 
    colorWipe(strip.Color(0, 0, 0), 50); // Powers down the LED Strip in the light              'strip.clear();' and 'strip.show();' turn the LED's off instantly
     
       }

  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if (newState == LOW) {
      showType++;
      if (showType > 9)
        showType=0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
}
void startShow(int i) {
  switch(i){
    case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
            break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red
            break;
    case 2: colorWipe(strip.Color(255, 0, 127), 50);  // Pink
            break;
    case 3: colorWipe(strip.Color(255, 255, 0), 50);    //Yellow Lime
            break;
    case 4: colorWipe(strip.Color(0, 255, 0), 50);  // Green
            break;
    case 5: colorWipe(strip.Color(0, 255, 255), 50);   //Light Blue
            break;
    case 6: colorWipe(strip.Color(0, 0, 255), 50);  // Blue
            break;
    case 7: rainbow(20);
            break;
    case 8: rainbowCycle(20);
            break;
    case 9: theaterChaseRainbow(50);
            break;
  }
}


// Fill the dots one after the other with a color
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);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// 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 strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Which devices work, which doesn't ?

  1. You use an RTC. Have You verified that it reads correctly?
  2. You use a display. Have You verified the function of it?
  3. You use a LED strip. Have You verified that You have full control of it?

Those 3 steps should have been done one by one, and when they all work they can be integrated. Did You do like that?

Yes I have full control over those things, I'm just don't know the code to turn the LED's back on and show what was lit up before they turned off.

You could bring back the LED test/example program and work it out there.

I've already tried many different lines of code but none of them have worked, the LED strip stays off until I push the button again.

I'm having trouble with the line which at the moment reads, 'strip.show();' This line is in the section of code where I receive the data from the photoresistor.

Check this strange line of code:

  if (light < 150) { //While the light is off, stay in this loop
    strip.show();
  }
  else {
    colorWipe(strip.Color(0, 0, 0), 50); // Powers down the LED Strip in the light              'strip.clear();' and 'strip.show();' turn the LED's off instantly

What looks like 2 lines is one line of code!

Use the Autoformat in the IDE! Many simple and silly mistakes shows up there.

That's a really cool feature that I didn't know was there but I auto formatted it and those lines you picked out didn't change, they were only moved further away from the left side of the sketch.

Good You see it!
Know that // makes everything after that being a comment. There are calls to 'strip.clear();' and 'strip.show(); that will not be executed. That's suspicious to me.
What do You say? I'm not familiar with the details in Your LED stuff....

Those two were just for me to know how to make the LED's turn off instantly if I wanted them to, but I decided I prefer them 'powering down'. Do you know how, instead of the line 'strip.show()' in the code, I could make the LED's go back to how they were before they turned off?

Off would just be sending 0-0-0 for each LED unit, and then re-sending whatever color you have before that.
These are addressable LEDs, but they only hold 3 bytes at a time, there's no save & restore capability or anything like that.

That's a shame. Is there a way I could go to the start of the scenes, so the code starts from the beginning again when the external light turns off?

Shure. Set a boolean flag when the button is pressed. Poll the flag at the top of loop and do a reset and end it by resetting the flag.

I'm not sure how I would do that as I am quite new to programming. Any suggestions?

void loop() {

  if(buttonOrderedRestFlag){
//perform reset/restore operation


reset operations.....
   buttonOrderedRestFlag = false;
}


  // Get current date and time:
  DateTime now = rtc.now();

Set "buttonOrderedRestFlag" true where ever You want in the code. Delare buttonOrderedRestFlag up in the top of the sketch and assign it the value ""false"

Would "buttonOrderedRestFlag" be declared in the "void setup()" area or before that?

I think I have done what you said, however the same thing is happening, the LED's stay off when the external light turns off instead of them turning on again.
Here is the code now:

#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN   7    // Digital IO pin connected to the button.  This will be
// driven with a pull-up resistor so the switch should
// pull the pin to ground momentarily.  On a high -> low
// transition the button press logic will execute.

#define PIXEL_PIN    6   // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 57   // number of neopixel (change this accordingly)

// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;


// Include the libraries:
#include "RTClib.h"
#include <TM1637Display.h>

// Define the connections pins:
#define CLK 2
#define DIO 3

// Create rtc and display object:
RTC_DS3231 rtc;
TM1637Display display = TM1637Display(CLK, DIO);
int light = 0;

void setup() {
  // Begin serial communication at a baud rate of 9600:
  Serial.begin(9600);


  // Check if RTC is connected correctly:
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  // Check if the RTC lost power and if so, set the time:
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // The following line sets the RTC to the date & time this sketch was compiled:
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  // Set the display brightness (0-7):
  display.setBrightness(5);
  // Clear the display:
  display.clear();

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  strip.setBrightness(100);
}
int buttonOrderedRestFlag;

void loop() {
  if (buttonOrderedRestFlag) {
    //perform reset/restore operation


    //reset operations.....
    buttonOrderedRestFlag = false;
  }

  // Get current date and time:
  DateTime now = rtc.now();

  // Create time format to display:
  int displaytime = (now.hour() * 100) + now.minute();

  // Print displaytime to the Serial Monitor:
  Serial.println(displaytime);

  // Display the current time in 24 hour format with leading zeros enabled and a center colon:
  display.showNumberDecEx(displaytime, 0b11100000, true);

  // Get current button state.
  bool newState = digitalRead(BUTTON_PIN);

  void startShow(int i);
  light = analogRead(A0); // read and save value from PR
  Serial.println(light);
  if (light < 150) { //While the light is off, stay in this loop
    strip.show();
  }
  else {
    colorWipe(strip.Color(0, 0, 0), 50); // Powers down the LED Strip in the light              'strip.clear();' and 'strip.show();' turn the LED's off instantly

  }

  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if (newState == LOW) {
      showType++;
      if (showType > 9)
        showType = 0;
      startShow(showType);
    }
  }
  buttonOrderedRestFlag = true;

  // Set the last button state to the old state.
  oldState = newState;
}
void startShow(int i) {
  switch (i) {
    case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
      break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red
      break;
    case 2: colorWipe(strip.Color(255, 0, 127), 50);  // Pink
      break;
    case 3: colorWipe(strip.Color(255, 255, 0), 50);    //Yellow Lime
      break;
    case 4: colorWipe(strip.Color(0, 255, 0), 50);  // Green
      break;
    case 5: colorWipe(strip.Color(0, 255, 255), 50);   //Light Blue
      break;
    case 6: colorWipe(strip.Color(0, 0, 255), 50);  // Blue
      break;
    case 7: rainbow(20);
      break;
    case 8: rainbowCycle(20);
      break;
    case 9: theaterChaseRainbow(50);
      break;
  }
}


// Fill the dots one after the other with a color
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);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

// 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 strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

joester21:
Would "buttonOrderedRestFlag" be declared in the "void setup()" area or before that?

I don't use the skilled approach so I declare such variables before Setup(). It has worked for me.
Don't do it inside Setup. Then it would likely be local (valid) only inside Setup.

I have changed the declaration of int "buttonOrderedRestFlag" to above void setup() however nothing has changed. Here is the code now:

#include <Adafruit_NeoPixel.h>

#define BUTTON_PIN   7    // Digital IO pin connected to the button.  This will be
// driven with a pull-up resistor so the switch should
// pull the pin to ground momentarily.  On a high -> low
// transition the button press logic will execute.

#define PIXEL_PIN    6   // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 57   // number of neopixel (change this accordingly)

// Parameter 1 = number of pixels in strip,  neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct for neopixel stick
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;


// Include the libraries:
#include "RTClib.h"
#include <TM1637Display.h>

// Define the connections pins:
#define CLK 2
#define DIO 3

// Create rtc and display object:
RTC_DS3231 rtc;
TM1637Display display = TM1637Display(CLK, DIO);
int light = 0;
int buttonOrderedRestFlag;

void setup() {
  // Begin serial communication at a baud rate of 9600:
  Serial.begin(9600);


  // Check if RTC is connected correctly:
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  // Check if the RTC lost power and if so, set the time:
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // The following line sets the RTC to the date & time this sketch was compiled:
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  // Set the display brightness (0-7):
  display.setBrightness(5);
  // Clear the display:
  display.clear();

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  strip.setBrightness(100);
}

void loop() {
  if (buttonOrderedRestFlag) {
    //perform reset/restore operation


    //reset operations.....
    buttonOrderedRestFlag = false;
  }

  // Get current date and time:
  DateTime now = rtc.now();

  // Create time format to display:
  int displaytime = (now.hour() * 100) + now.minute();

  // Print displaytime to the Serial Monitor:
  Serial.println(displaytime);

  // Display the current time in 24 hour format with leading zeros enabled and a center colon:
  display.showNumberDecEx(displaytime, 0b11100000, true);

  // Get current button state.
  bool newState = digitalRead(BUTTON_PIN);

  void startShow(int i);
  light = analogRead(A0); // read and save value from PR
  Serial.println(light);
  if (light < 150) { //While the light is off, stay in this loop
    strip.show();
  }
  else {
    colorWipe(strip.Color(0, 0, 0), 50); // Powers down the LED Strip in the light              'strip.clear();' and 'strip.show();' turn the LED's off instantly

  }

  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if (newState == LOW) {
      showType++;
      if (showType > 9)
        showType = 0;
      startShow(showType);
    }
  }
  buttonOrderedRestFlag = true;

  // Set the last button state to the old state.
  oldState = newState;
}
void startShow(int i) {
  switch (i) {
    case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
      break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red
      break;
    case 2: colorWipe(strip.Color(255, 0, 127), 50);  // Pink
      break;
    case 3: colorWipe(strip.Color(255, 255, 0), 50);    //Yellow Lime
      break;
    case 4: colorWipe(strip.Color(0, 255, 0), 50);  // Green
      break;
    case 5: colorWipe(strip.Color(0, 255, 255), 50);   //Light Blue
      break;
    case 6: colorWipe(strip.Color(0, 0, 255), 50);  // Blue
      break;
    case 7: rainbow(20);
      break;
    case 8: rainbowCycle(20);
      break;
    case 9: theaterChaseRainbow(50);
      break;
  }
}


// Fill the dots one after the other with a color
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);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

// 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 strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

I checked the code. Just as I wanted, BUT..... You need to fill in, do the calls, needed for the operation, just there in the beginning of loop(), just above resetting the flag.