Trying to shut everything off and restart loop

Hi

Brand new to Arduino and coding in general. Bought the starter kit and went rogue with my own project, even though I'm only at the love-o-meter. It's a row of seven lights powered by a 2 3-way switches. If you turn on switch from one side, the lights from closest to farthest away light up one by one. Same from other switch. Program works okay although it's a bit laggy. Is there a way to nest or insert code to the middle of a function to essentially cancel it and start over (instant off button)? And I'm not talking during the actual delay but in between a series of delays? When I turn off a switch I want to be able to cancel the delay sequence at every point after the 750 delays, if i made power=low. I tried the return; but i think that only just recycles the same function, I'm not sure. Any help would be appreciated. I didn't write notes in the code but travelOne and travelTwo are the 3 way travelers and the power is the common to imitate the 3 way states. Pins 5 thru 11 are the lights. And weirdly my high\low state outputs are reversed.

Thanks

Harold

int travelOne = 0;
int travelTwo = 0;
int power = 0;
void setup() {
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);

digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
}
void loop() {
travelOne = digitalRead(3);
travelTwo = digitalRead(4);
power = digitalRead(2);

if (travelOne == HIGH && power == HIGH)
{digitalWrite(5, LOW);
delay(750);
digitalWrite(6, LOW);
delay(750);
digitalWrite(7, LOW);
delay(750);
digitalWrite(8, LOW);
delay(750);
digitalWrite(9, LOW);
delay(750);
digitalWrite(10, LOW);
delay(750);
digitalWrite(11, LOW);
}
else if (travelTwo == HIGH && power == HIGH)
{digitalWrite(11, LOW);
delay(750);
digitalWrite(10, LOW);
delay(750);
digitalWrite(9, LOW);
delay(750);
digitalWrite(8, LOW);
delay(750);
digitalWrite(7, LOW);
delay(750);
digitalWrite(6, LOW);
delay(750);
digitalWrite(5, LOW);
}
else if (travelOne == HIGH && power == LOW)
{digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
else if (travelTwo == HIGH && power == LOW)
{digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
digitalWrite(7, HIGH);
digitalWrite(6, HIGH);
digitalWrite(5, HIGH);
}
}

Please follow the advice on posting code in Read this before posting a programming question

In particular note the advice to Auto format code in the IDE and using code tags when posting code here

Basically use the code tags (top left </>) will insert the tags and you copy your code n between these tags.

To answer your question, I would add a while loop with the condition while whichever switch you want this to apply to is on.

Also, you can simplify the code significantly; here an idea for the setup()
The approach shown may give you an idea as to how to simplify the repeat statements in the loop().

uint8_t travelOne = 0;
uint8_t travelTwo = 0;
uint8_t power = 0;

const uint8_t pins_input[] = {2, 3, 4};
const uint8_t pins_output[] = {5, 6, 7, 8, 9, 10, 11};


void switch_leds_on ()
{
 for (uint8_t i = 0; i < 7; i++)
 {
 digitalWrite(pins_output[i], HIGH);
 }
}


void setup()
{
 for (uint8_t i = 0; i < 3; i++)
 {
 pinMode(pins_input[i], INPUT);
 }

 for (uint8_t i = 0; i < 7; i++)
 {
 pinMode(pins_output[i], OUTPUT);
 }

 switch_leds_on ();
}

WHILE loops are generally a bad idea - much better to allow loop() to do the repetition - it's what it is designed for.

The real problem is all the delay()s. The functions delay() and delayMicroseconds() block the Arduino until they complete.
Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

...R

Thanks for the quick feedback everyone! I'm still new but seeing shortcuts and other avenues really help me understand syntax and the logic better since I have comparative context in which to learn. I read up on the millis function and it fried my tiny brain. I'm just not there yet. I was more interested in running some sort of power = low check in between the delay intervals to turn all lights off, even if it's right after the delay. I don't mind a .75 lag on switch off. But .75*6 sec is annoying. Learning more everyday just realized that Arduino code is C++ so searching solutions under that will probably help. Thanks again. I try again tomorrow

haroldinteractive:
I read up on the millis function and it fried my tiny brain.

I find that programming stuff starts to make sense after the 14th read :slight_smile:

...R

Ok

Hours and days have passed I've exhausted all of my mental energy so I'm reaching out. I'm brand new to coding so please bear with me. I have a tunnel with 7 lights in a row and a switch at each end of the tunnel. When I flip the switch (not momentary) at one end of the tunnel , the LEDs light up one at a time from closest to me to farther away 600ms delay in between. It works the same for both switches. Both switches can turn off the lights when switching state. The latching mechanism was very hard for me to figure out but now it works. I'll post the code at the bottom. So I got it working but found that if I turn it off I have to wait 3-4 seconds to turn back on because I suspect the code cycles anyway in an off state. So then I got into millis, super confusing but I think I got it and I think I need it. Here's the problem, when I overlay a working millis prototype onto the sequencer "if" statements, it does not work. Here's the prototype I built from watching 4 hours of tutorials:

bool switch_position1;
bool switch_position2;
bool led_state;
bool sw_state;
const unsigned long sixHundred = 600;
unsigned long previousTime = 0;

void setup() {
Serial.begin(9600);
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
switch_position1 = digitalRead(2);
switch_position2 = digitalRead(3);
led_state = LOW;
sw_state = LOW;
}

void loop() {
unsigned long currentTime = millis();

if(digitalRead(2) == HIGH) {
digitalWrite(4, HIGH);
if(currentTime - previousTime >= sixHundred) {
digitalWrite(5, HIGH);
if(currentTime - previousTime >= 2UL * sixHundred) {
digitalWrite(6, HIGH);
if(currentTime - previousTime >= 3UL * sixHundred) {
digitalWrite(7, HIGH);
if(currentTime - previousTime >= 4UL * sixHundred) {
digitalWrite(8, HIGH);
if(currentTime - previousTime >= 5UL * sixHundred) {
digitalWrite(9, HIGH);
if(currentTime - previousTime >= 6UL * sixHundred) {
digitalWrite(10, HIGH);
}
}
}
}
}
}
}

if(digitalRead(2) == LOW) {
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
previousTime = currentTime;
}
}

And here's the "buggy" but working version of my project. that I'm trying to rid of delay functions:

bool switch_position1;
bool switch_position2;
bool led_state;
bool sw_state;

void setup() {

pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);

switch_position1 = digitalRead(2);
switch_position2 = digitalRead(3);
led_state = LOW;
sw_state = LOW;
}

void loop() {

if(switch_position1 != digitalRead(2) && sw_state == LOW) {
led_state = !led_state;
sw_state = !sw_state;
switch_position1 = !switch_position1;
digitalWrite(4, led_state);
delay(600);
digitalWrite(5, led_state);
delay(600);
digitalWrite(6, led_state);
delay(600);
digitalWrite(7, led_state);
delay(600);
digitalWrite(8, led_state);
delay(600);
digitalWrite(9, led_state);
delay(600);
digitalWrite(10, led_state);
sw_state = HIGH;
}
else if(switch_position2 != digitalRead(3) && sw_state == LOW) {
led_state = !led_state;
sw_state = !sw_state;
switch_position2 = !switch_position2;
digitalWrite(10, led_state);
delay(600);
digitalWrite(9, led_state);
delay(600);
digitalWrite(8, led_state);
delay(600);
digitalWrite(7, led_state);
delay(600);
digitalWrite(6, led_state);
delay(600);
digitalWrite(5, led_state);
delay(600);
digitalWrite(4, led_state);
sw_state = HIGH;
}
else if((switch_position1 != digitalRead(2) || switch_position2 != digitalRead(3)) && sw_state == HIGH) {
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
sw_state = LOW;
}
}

Any help would be greatly appreciated. My brain is toast.

Please edit your post to add code tags, as described in the "How to use the forum" post.

It would help everyone if you add comments to the code, explaining what the important lines are supposed to do. And, after a few months away from the project, you will need those comments too.

I’ll second the request to edit your post and add code tags. I would suggest you stick with the delay() version for just a bit longer. The fact that the code gets stuck for 3-4 seconds isn’t a bug, it’s a byproduct of using delay(). So, yes, you are on the correct path to fix it but let’s optimize and understand the delay() version before moving on.

Observationally, your statement about switches and your code don’t agree. You said the switches are “not momentary” which means they are maintained and therefore you shouldn’t need the “state_sw” variable which provides the latching. Could you please clarify why you need a latch in software?

Also, I believe the final else if(..) logic is totally unnecessary, all those reads, ors and ands are superfluous and the line can become a simple else clause because if both switches are off, the lights need to be off.

please read HOW TO USE THIS FORUM, it is a sticky post on the top of every forum.
#7 talks about code tags and how to use them
go back to your post, bottom right, other > modify, then add code tags for each of the two sketches you posted.

as for your code, somethings you will find.
#1) you do not need to nest the if() for each time on
#2) do need to create an off/on flag for the first moment the switch goes high

here is an example of loop(), but I did not test it
I did abbreviate and used 600/1200, etc and also millis() so that each if() would fit on one line.

void loop() {
  unsigned long currentTime = millis();

SwitchState = digitalRead(2) ;

if (oldSwitchState == LOW) {
  if (SwitchState == HIGH) {
    SystemRun = HIGH ;
    previousTime = millis() ; // locks in time the switch started
  }
}

  if (SystemRun == HIGH) {
    digitalWrite(4, HIGH);
    if (millis() - previousTime >= 600) {digitalWrite(5, HIGH); }
    if (millis() - previousTime >= 1200) { digitalWrite(6, HIGH);}
    if (millis() - previousTime >= 1800) { digitalWrite(7, HIGH);}
    if (millis() - previousTime >= 2400) { digitalWrite(8, HIGH);}
    if (millis() - previousTime >= 3000) { digitalWrite(9, HIGH);}
    if (millis() - previousTime >= 3600) { digitalWrite(10, HIGH);}
   }

  if (SwitchState == LOW) {
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
    digitalWrite(9, LOW);
    digitalWrite(10, LOW);
    SystemRun = LOW ;
  }

oldSwitchState = SwitchState ;
} // end loop

Got it to work!

I'll post here lmk if I can make any improvements

bool switch_position1; // 3 way switch1 status
bool switch_position2; // 3 way switch2 status
bool led_state; // latch one
bool sw_state; // latch two (because the switches initiate 2 actions)
void setup() {

pinMode(2, INPUT_PULLUP); // 2 "3way switches"
pinMode(3, INPUT_PULLUP);
pinMode(4, OUTPUT); // Lights in a row
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);

switch_position1 = digitalRead(2);
switch_position2 = digitalRead(3);
led_state = LOW;
sw_state = LOW;
}

void off_State() { // function I created to halt timed sequence if OFF
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
sw_state = LOW;
switch_position1 = !switch_position1;
}
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
sw_state = LOW;
switch_position2 = !switch_position2;
}
}

void loop() {

if(switch_position1 != digitalRead(2) && sw_state == LOW && led_state == HIGH) {
led_state = LOW;
}
if(switch_position2 != digitalRead(3) && sw_state == LOW && led_state == HIGH) {
led_state = LOW;
}
if(switch_position1 != digitalRead(2) && sw_state == LOW && led_state == LOW) {
led_state = !led_state;
switch_position1 = !switch_position1;
sw_state = HIGH;
digitalWrite(4, led_state);
delay(600);
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(5, led_state);
delay(600);
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(6, led_state);
delay(600);
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(7, led_state);
delay(600);
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(8, led_state);
delay(600);
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(9, led_state);
delay(600);
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(10, led_state);
}
else if(switch_position2 != digitalRead(3) && sw_state == LOW && led_state == LOW) {
led_state = !led_state;
switch_position2 = !switch_position2;
digitalWrite(10, led_state);
delay(600);
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(9, led_state);
delay(600);
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(8, led_state);
delay(600);
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(7, led_state);
delay(600);
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(6, led_state);
delay(600);
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(5, led_state);
delay(600);
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
void offState();
return;
}
digitalWrite(4, led_state);
sw_state = HIGH;
}
if(switch_position1 != digitalRead(2) && sw_state == HIGH && led_state == HIGH) {
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW); // these 2 blocks control off when fully on
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
sw_state = LOW;
switch_position1 = !switch_position1;
}
if(switch_position2 != digitalRead(3) && sw_state == HIGH && led_state == HIGH) {
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
sw_state = LOW;
switch_position2 = !switch_position2;
}
}

// Works pretty good. I'm happy with it. If there is a way to streamline the code or make it work faster // lmk I'd like to learn.

OK some suggestions and ideas based on my own very limited experience coding in Arduino.

This bit is repeated in your code. You could write it as a function, but a "clever" alternative would be to use direct access to the register(s). Without knowing WHICH arduino youre using I cant give you a specific link but here is one such.

digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);

Similarly for this

pinMode(4, OUTPUT); // Lights in a row
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);

The loop you could write as a state machine using millis() (like Dave's example) in a switch - case structure.

Looking forward to seeing the results!

@haroldinteractive

TOPIC MERGED.

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum.

Also please use CODE TAGS for sketches.

If you put this as the first instructions in loop()

switch_position1 = digitalRead(2);
switch_position2 = digitalRead(3);

You could duplicate the 3 way switch logic with:

if(switch_position1 == switch_position2) // both switches in same position
{
  // lights ON
}
else // switches in different positions
{
  // lights OFF
}