I want the for() loop to continue until the button is pressed/the counter becomes even... However, it is clear that once the for() loop begins, the void loop() no longer runs, so no input is read, meaning a simple break if(button is pressed) won't work...
Even after realizing this, I have no idea how to solve this problem and any help would be greatly appreciated!
Code:
const int BUTTON = A1;
const int RLED = 10;
const int GLED = 9;
const int BLED = 8;
const unsigned long debouncePeriod = 20;
unsigned long startMillis;
unsigned long currentMillis;
unsigned long debounceStartMillis;
byte previousButtonState;
byte currentButtonState;
int count = 0;
bool debouncing = false;
void setup()
{
Serial.begin(115200);
pinMode(BUTTON, INPUT_PULLUP);
pinMode(RLED, OUTPUT);
pinMode(GLED, OUTPUT);
pinMode(BLED, OUTPUT);
startMillis = millis();
}
void ledMode(byte mode)
{
switch (mode)
{
case 1:
digitalWrite(RLED, HIGH); //RED
digitalWrite(GLED, LOW);
digitalWrite(BLED, LOW);
delay(1000);
break;
case 2:
digitalWrite(RLED, LOW); //GREEN
digitalWrite(GLED, HIGH);
digitalWrite(BLED, LOW);
delay(1000);
break;
case 3:
digitalWrite(RLED, LOW); //BLUE
digitalWrite(GLED, LOW);
digitalWrite(BLED, HIGH);
delay(1000);
break;
case 4:
digitalWrite(RLED, HIGH); //Yellow
digitalWrite(GLED, HIGH);
digitalWrite(BLED, LOW);
delay(1000);
break;
case 5:
digitalWrite(RLED, LOW); //TEAL
digitalWrite(GLED, HIGH);
digitalWrite(BLED, HIGH);
delay(1000);
break;
case 6:
digitalWrite(RLED, HIGH); //PURPLE
digitalWrite(GLED, LOW);
digitalWrite(BLED, HIGH);
delay(1000);
break;
case 7:
digitalWrite(RLED, HIGH); //WHITE
digitalWrite(GLED, HIGH);
digitalWrite(BLED, HIGH);
delay(1000);
break;
}
}
int RGBloop()
{
for (byte x = 1; x < 9; x++)
{
if (x == 8)
{
x = 1;
}
else if(count % 2 == 0)
{
Serial.println("Button pressed.");
break;
}
ledMode(x);
}
}
int RGBoff()
{
Serial.println("Turning off.");
digitalWrite(RLED, LOW);
digitalWrite(BLED, LOW);
digitalWrite(GLED, LOW);
}
void loop()
{
currentMillis = millis();
previousButtonState = currentButtonState;
currentButtonState = digitalRead(BUTTON);
if (currentButtonState != previousButtonState)
{
debouncing = true;
debounceStartMillis = currentMillis;
}
if (currentMillis - debounceStartMillis >= debouncePeriod)
{
if(debouncing == true)
{
if (currentButtonState == LOW)
{
debouncing = false;
count++;
Serial.println(count);
if (count % 2 == 0)
{
Serial.println("Turning off.");
RGBoff();
}
else if (count % 2==1)
{
Serial.println("Running loop function.");
RGBloop();
}
}
}
}
}
You should know that folks here appreciate it when posters with questions have at least spent some effort to find the answer before posting. The folks here answer questions because we like to help others. When someone doesn't at least spent some time researching before posting a question it doesn't sit will with us spending our time to do what you could easily do your self.
I don't mean to cause any hardship, and I already did search on google...
I'm already well aware of break;. The issue is when I want to break the loop if the button is pressed, I don't see anyway of doing so given that the computer is set to loop the different RGB modes within the for() loop.
I added the below code so that it would loop and reset to mode 1.
if (x == 8)
{
x = 1;
}
I suppose another way of explaining my problem is that I essentially want to run two loops simultaneously, but I'm unaware as to how to do so...
The void loop() to check for a button state change, and then the RGB loop to start once it is pressed. But also have it stop once the button is pressed again, which would require the void loop()to continue running....
That's what I originally tried, but it doesn't recognize if (GPIOx == 1), because it is stuck in switching LED modes. The main loop, which checks if (GPIOx == 1), does not run while it does switch LED modes.
Which is why I was hoping there was a way to have both loops run at once...
I did look at several things at the same time , but I can't open the link within the post. I will have to study it more in depth when I get the chance, I just thought there was simpler solution, such as changing the for() loop's position.
To do several things at "the same time" is really simple.
There is a millis() function that counts milliseconds. You simply use the millis() in your main loop to determine what gets run next.
See Arduino reference.
the basics are:
in setup:
variableoldmillis = millis()
on loop:
if (variableoldmillis => millis + howmanymillisbeforeyouwantsomecodetorun){
then run code#1
}
if (variableoldmillis => millis + howmanymillisbeforeyouwantanother codeun){
then run code#2
}
just before end of loop
variableoldmillis = millis()
The simplest way would be to read the button in the for-loop and react on that. The better way would be not to use for-loops or while-loops. As mentioned earlier, break your for-loop in small pieces.
int RGBloop()
{
// loop counter
static byte x = 1;
if (x == 8)
{
x = 1;
}
ledMode(x);
x++;
}
}
The static keyword indicates that the variable will be remembered between calls (it makes x act as a global variable but x will only be known inside RGBloop()).
The above code needs to be called repeatedly from loop() and with the exception of the reacting on the button will do the same as your original.
void loop()
{
RGBloop();
}
You can also make x a global variable which might make life easier if you always want to start from 1 after an interruption; in that case I suggest that you rename x to e.g. loopCounter.