say that I have few relays turns on and off with a sketch that runs in the loop and that sketch runs only after the pushbutton is pressed. so , if nothing else in the sketch, that will keep repeating in the loop and look for push button action input. If I press the push button then it will repeat that relay action again.
what I want it to happen is that; one press on the push button and the relays runs on their sketched sequence. but then, the second time the push button is pressed; I don't' want the sketch to do the relay sequence nor anything else until the Arduino is power cycled or rebooted or reset.
so, I only want the push button action done (pressed) only once and the sketch to run the relays sequence and then stops and awaits till the next power cycle but not when the button is pressed the second time.
is there any ways to achieve this?
I've tried adding very long delay (ie: 12 hours) but then the sketch doesn't runs at all. as if though the the long delays stops the sketch runs even once after the 1st push button action.
If your sketch was generated with an AI like ChatGPT, tell us prior to asking your questions.
If the sketch you post was mainly written by someone else tell us.
Questioners know what their hardware and software looks like but the volunteers here do not; you need to fully explain what’s not working, and how it is supposed to work.
Please read all the posting guidelines before asking your questions, follow these guidelines in your posts.
Always show us a good schematic of your proposed circuit.
Show us good images of your ‘actual’ wiring.
Give WEB links to components.
In the Arduino IDE, use CtrlT or CMDT to format your code, then copy the complete sketch.
Use the < CODE / > icon from the ‘posting menu’ to attach your copied sketch.
When you follow the posting guidelines, volunteers can be more effective.
I do want nothing happens until power cycle, but I want the sketch to run once with the 1st push button action, however, I don't want the 2nd, 3rd, 4th ...... n th push button action to do noting until next power cycle or reset.
// Constants:
int buttonState = 0;
int pushButtonPin = 3;
int pushButton;
int relay_1 = 4;
int relay_2 = 7;
int relay_3 = 8;
void setup()
{
// setup code here, to run once:
pinMode(pushButton, INPUT);
pinMode(relay_1, OUTPUT);
pinMode(relay_2, OUTPUT);
pinMode(relay_3, OUTPUT);
}
void loop()
{
// read the state of the pushbutton
buttonState = digitalRead(3);
// check if pushbutton is pressed. if it is, then...
// button state is HIGH
if (buttonState == HIGH)
{
// step one:
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
delay(1000);
// step two:
digitalWrite(relay_1, HIGH);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(1000);
digitalWrite(relay_1, LOW);
delay(500);
// step three:
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
}
else
{
digitalWrite(relay_1, LOW);
digitalWrite(relay_2, LOW);
digitalWrite(relay_3, LOW);
}
delay(43200000); //
}
Ok Delat_G, here is the code, So how would you use the while (1) to run my requirement.
don't forget; I need the sketch to run and repeat the loop till I press the Pushbutton and execute the void loop just once, and then it should enter into infinite loop with while(1) till power cycle or reset.
As a fairly newbie programmer, it looks like both gcjr and Delta_G code snippets would work. However gcjr's is a little complex looking with the case/switch stuff, and Delta_G's might be hard to modify in the future. I would set it up like DaveX suggested, with a "flag" to control it. I'd do something like this. It is probably not the most efficient way to do it but it makes sense to me and I think it would be easy to modify in the future.
//Stuff I am adding
int buttonPressed = 0;
// Constants:
int buttonState = 0;
int pushButtonPin = 3;
int pushButton;
int relay_1 = 4;
int relay_2 = 7;
int relay_3 = 8;
void setup()
{
// setup code here, to run once:
pinMode(pushButton, INPUT);
pinMode(relay_1, OUTPUT);
pinMode(relay_2, OUTPUT);
pinMode(relay_3, OUTPUT);
//Putting this here since it seems to be the default state of your sketch. (I'm not sure it's even needed though, I assume the Arduino treats them as LOW if it's not told otherwise)
digitalWrite(relay_1, LOW);
digitalWrite(relay_2, LOW);
digitalWrite(relay_3, LOW);
}
void loop()
{
if (buttonPressed == 0) { //(only need to read this if it hasn't been pressed yet)
// read the state of the pushbutton
buttonState = digitalRead(3);
// check if pushbutton is pressed. if it is, then...
// button state is HIGH
if (buttonState == HIGH)
{
// step one:
buttonPressed = 1; // ensure none of the loop ever happens again since this will never be 0 again
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
delay(1000);
// step two:
digitalWrite(relay_1, HIGH);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(1000);
digitalWrite(relay_1, LOW);
delay(500);
// step three:
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
}
}
}
Using buttonPressed as a "flag" to control whether the chunk of code works is very close to the same mechanics as @gcjr's solution. Consider @gcjr's 'state' variable to work much the same as 'buttonPressed' instead of 0 and not-0, it has three different options, and changes to 'state' control which chunk of code operates.
Both of them are "state machines" which are a basic building block for code that ever needs to do more than one thing at a time.
Another trick that all three codes share is the 'while(1){;}' trick, which in state machines is called an "absorbing state" because once it gets into that infinite loop, it never gets out of the state. @gcjr's absorbing state is the while(1); infinite loop inside of the Waitforever case, @Delta_G's absorbing state is the while(1); at the end of the code in loop(), and mine/yours is that there isn't anything left in loop() when the flag is triggered. It may not look like a while, but 'loop()' is called from a '`while(true){ loop();...}' line in the Arduino initialization code.
void setup() {
// setup code here, to run once:
// define IO-pins
// switch relays off
while (digitalRead(pushButtonPin) == LOW) // wait for the button-press
;
//when the while-loop is left as the last thing to do
relaySwitching();
//then exiting setup() // and NEVER execute the code in setup again. NEVER executing code again is the ONE AND ONLY purpose of setup()
}
void loop() {
// stays totally empty to really do nothing
}
the full code
// Constants:
int buttonState = 0;
int pushButtonPin = 3;
int pushButton;
int relay_1 = 4;
int relay_2 = 7;
int relay_3 = 8;
void setup() {
// setup code here, to run once:
pinMode(pushButton, INPUT);
pinMode(relay_1, OUTPUT);
pinMode(relay_2, OUTPUT);
pinMode(relay_3, OUTPUT);
digitalWrite(relay_1, LOW);
digitalWrite(relay_2, LOW);
digitalWrite(relay_3, LOW);
while (digitalRead(pushButtonPin) == LOW) // wait for the button-press
;
//when the while-loop is left as the last thing to do
relaySwitching();
//then exiting setup()
}
void loop() {
// stays totally empty to really do nothing
}
void relaySwitching() {
// step one:
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
delay(1000);
// step two:
digitalWrite(relay_1, HIGH);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(1000);
digitalWrite(relay_1, LOW);
delay(500);
// step three:
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
}
its great that there are more than one way get things done.
all the options discussed could work i think, I was originally interested in while(1) as Delta_G's, for the simplicity, as it was just a simple word and number, but as everyone says that it just stops my code dead in its track, not a very good approach and everyone agrees (including me) . since all of your inputs, I have decided to try all the different approaches and modify my code.
I am afraid I've setteld for while(1) as per Delta_G's suggestion. All because, I need part of the code to loop until I hit the pushbutton. So, I need the sketch to loop until I hit the button. Then I need it to stop till next powercycle or board reset. Unless anyone has better suggestion, this seems to be the best solution.
depending on what the code is that needs to loop
just put it inside the while-loop that is waiting for the button-press
like shown in this WOKWI-simulation
The code you have really posted just has a switching off of the relays
The IO-pins keep their logic state
until you change the logic state
so a single time executing
is completely sufficient to keep the relays switched off for years
If you need any other code to loop this looping can be done
inside function setup()
like shown in this code
I have added serial printing to make visible what the code is doing
// Constants:
int buttonState = 0;
int pushButtonPin = 3;
int pushButton;
int relay_1 = 4;
int relay_2 = 7;
int relay_3 = 8;
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
// setup code here, to run once:
pinMode(pushButton, INPUT);
pinMode(relay_1, OUTPUT);
pinMode(relay_2, OUTPUT);
pinMode(relay_3, OUTPUT);
Serial.println("IO-pins configured");
digitalWrite(relay_1, LOW);
digitalWrite(relay_2, LOW);
digitalWrite(relay_3, LOW);
Serial.println("all relays LOW");
Serial.println("waiting for button-press");
while (digitalRead(pushButtonPin) == LOW) { // wait for the button-press
// remove the two lines for real application
Serial.println("inside loop waiting for buttonpress");
delay(500);
}
Serial.println("button-press detected execute relay-ON/OFF-Sequence");
//when the while-loop is left as the last thing to do
relaySwitching();
Serial.println("relaySwitching done exiting setup");
//then exiting setup()
}
void loop() {
// stays totally empty to really do nothing
delay(2000);
Serial.println("loop can be empty then really NOTHING happends");
}
void relaySwitching() {
// step one:
Serial.println("step one");
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
delay(1000);
// step two:
Serial.println("step two");
digitalWrite(relay_1, HIGH);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(500);
digitalWrite(relay_3, HIGH);
delay(500);
digitalWrite(relay_3, LOW);
delay(1000);
digitalWrite(relay_1, LOW);
delay(500);
// step three:
Serial.println("step three");
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
delay(500);
digitalWrite(relay_2, LOW);
digitalWrite(relay_1, LOW);
}
here is a WOWKI-simulation of that code
this is the serial printing
Setup-Start
IO-pins configured
all relays LOW
waiting for button-press
inside loop waiting for buttonpress
inside loop waiting for buttonpress
inside loop waiting for buttonpress
inside loop waiting for buttonpress
inside loop waiting for buttonpress
button-press detected execute relay-ON/OFF-Sequence
step one
step two
step three
relaySwitching done exiting setup
loop can be empty then really NOTHING happends
loop can be empty then really NOTHING happends
loop can be empty then really NOTHING happends
loop can be empty then really NOTHING happends
loop can be empty then really NOTHING happends
loop can be empty then really NOTHING happends
Would you mind posting your final code that I can see what code you have to loop
before the button-press