I have a sketch that I would like to pause and restart when a button is pushed. The sketch utilizes four states (each a function) with a while loop in each to count millis until time expires for that event. The main loop simply cycles through the states in order and counts the number of times the cycle is completed. I'd like to be able to pause the sketch at any time and resume at the point where it stopped with no affect on the cycle. Any possibility someone has done this before? Any ideas on a decent approach? Is this too ambitious?
If you are in the middle of a loop you may need to use interrupts to stop the process.
Weedpharma
Delta_G:
When you see a button push, go into a while loop that does nothing but check the button for another push.
Do this and make it a 5th state called when millis() timer expires.
No need to pause the sketch.
Can't really say without seeing your code.
The standard line is that you should organize your sketch so that state variables can be used to do this. It's the most likely case.
But maybe that's really inconvenient or boarding on impossible. Then an interrupt could be the best way.
Then an interrupt could be the best way.
An interrupt is almost never the best way to deal with slow events like switch presses. The code would still have to be re-written to notice that the interrupt service routine had set a flag that meant stop.
I would do something like this (example posted)
im going to say paused/hold but that really means not moving to the next step as the arduino will not be paused it will just be skipping code and not executing it.
There should be extra code added depending on what you would like to do after the pause concerning the timer. If it a short timer then it shouldn't be a problem but lets say its a 2 hour timer and you pause at 1.5 hrs
once un-paused would you want to wait 2hrs or 0.5hrs or move to the next function instantly.
//I have a sketch that I would like to pause and restart when a button is pushed.
//The sketch utilizes four states (each a function) with a while loop in each to count millis
//until time expires for that event. The main loop simply cycles through the states in order
// and counts the number of times the cycle is completed. I'd like to be able to pause the sketch
// at any time and resume at the point where it stopped with no affect on the cycle. Any possibility
// someone has done this before? Any ideas on a decent approach? Is this too ambitious?
const byte button = 3;//button pin connect between pin3 and dc neg
unsigned long previousMillis = 0;
unsigned long interval = 1000 * 3; // 1000 millis per sec x 3 = 3 seconds
byte prevstate = 0;
byte prevbuttonstate = 0;
byte holdflag = 0;
byte state = 0;
void setup() {
// put your setup code here, to run once:
pinMode(button, INPUT_PULLUP);
pinMode(13, OUTPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
unsigned long currentMillis = millis();
byte buttonstate = digitalRead(button);
//next section deals with the button
// first press tells it to hold next press removes hold
if (prevbuttonstate != buttonstate) { //monitor state looking for change
delay(40);//crude button debounce
if (buttonstate == LOW) { //input pullup so button pressed is low
holdflag = ! holdflag; //toggle hold on or off
}
}
prevbuttonstate = buttonstate;
//next section used to show that program is holding by lighting onboard led
//also used to reset the timer
if (holdflag == 1) {
digitalWrite(13, HIGH);
previousMillis = currentMillis;//new time stamp. you may want to remove
// or recode this piece depending on the result required after a pause
} else {
digitalWrite(13, LOW);
}
//next section is a single timer that tells state to move when done
//see blink with out delay
if (currentMillis - previousMillis >= interval) {
if (holdflag == 0) {
state++;
}
previousMillis = currentMillis;
}
//next section controls the calls to the functions based
//on state
if (prevstate != state) {
switch (state) {
case 0:
break;
case 1:
showPrint1();//call function
interval = 3000;//delay before case 2
break;
case 2:
showPrint2();
interval = 5000;//delay before case 3
break;
case 3:
showPrint3();
interval = 2000;//delay before case 4
break;
case 4:
showPrint4();
interval = 3000;//delay before case 1
state = 0;
break;
}
}
prevstate = state;
}
void showPrint1() {
Serial.print("function 1 ");
Serial.println (millis());
}
void showPrint2() {
Serial.print("function 2 ");
Serial.println (millis());
}
void showPrint3() {
Serial.print("function 3 ");
Serial.println (millis());
}
void showPrint4() {
Serial.print("function 4 ");
Serial.println (millis());
}