Hi,
I have a project with Arduino, an oled screen, and a button.
I have 3 voids with text/images/gigs that work on screen.
want to create a program that shows:
while counter is on 1: void1 in infinite loop
while counter is on 2: void2 in infinite loop
while counter is on 3: void3 in infine loop
counter is incrementing on button push
I know how to setup 99% of code but I don't know how to exit an infinite loop (how to increment state of button while in infinite loop and exit it)
Hello dpustahija
See below a example sketch based on functions pointer. You may tailor this sketch to your needs.
/* BLOCK COMMENT
ATTENTION: This Sketch contains elements of C++.
https://www.learncpp.com/cpp-tutorial/
Many thanks to LarryD
https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
https://forum.arduino.cc/t/how-to-run-infinite-loop-while-counter-is-on-specific-number/958680
*/
#define ProjectName "How to run infinite loop while counter is on specific number"
// HARDWARE AND TIMER SETTINGS
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
constexpr byte ButtonPins[] {A0}; // portPin o---|button|---GND
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct TIMER { // has the following members
unsigned long duration; // memory for interval time
unsigned long stamp; // memory for actual time
};
struct BUTTON { // has the following members
byte pin; // port pin
bool statusQuo; // current state
TIMER scan; // see timer struct
};
BUTTON selector {ButtonPins[One], false, 20, 0};
// User Tasks
void (*tasks[])() {
task0, task1, task2, task3
};
void task0() {
Serial.println(__func__);
}
void task1() {
Serial.println(__func__);
}
void task2() {
Serial.println(__func__);
}
void task3() {
Serial.println(__func__);
}
// -------------------------------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println(F("."));
Serial.print(F("File : ")), Serial.println(__FILE__);
Serial.print(F("Date : ")), Serial.println(__DATE__);
Serial.print(F("Project: ")), Serial.println(ProjectName);
pinMode (LED_BUILTIN, OUTPUT); // used as heartbeat indicator
// https://www.learncpp.com/cpp-tutorial/for-each-loops/
for (auto Input : ButtonPins) pinMode(Input, INPUT_PULLUP);
}
void loop () {
currentTime = millis();
digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
static int number = 0;
tasks[number]();
if (currentTime - selector.scan.stamp > selector.scan.duration) { // debounce button
selector.scan.stamp = currentTime;
int stateNew = ! digitalRead(selector.pin);
if (selector.statusQuo != stateNew) {
selector.statusQuo = stateNew;
if (stateNew)
++number %= sizeof(tasks) / sizeof(tasks[0]);
}
}
}
You can do this in more than one way, depending on what you actually want to do.
One way is to check if the value of the counter has changed, and if it has then execute the appropriate function. That will run the function once when counter changes, and then the program sits in loop checking the button to see if it has been pressed.
Another way is to check the value of counter in loop, then call the appropriate function depending on the value of counter. Afterwards, the function returns and you continue with loop, checking the button and then executing the same function again until the button is pressed, incrementing counter and going to the next function. This will execute the function repeatedly as long as counter remains the same.