Good day,
I have this little project I am working on where I must make a light go on and off certain times.
Now here is how it works:
There are 2 buttons for each variable one to increase and the other to decrease the variable. There are 3 variables like that _ON,_OFF and CYCLE. _ON is for the amount of seconds the light must be on. _OFF is for the number of seconds the light must be off. Lastly CYCLE will be the number of times the light will turn on and off.
I do not have a problem with increasing and decreasing that variables, I have 2 more buttons that gives me the problems. They are the start/stop button and on/off button. The on/off button must toggle the light on and off if the loop of cycles is not running. The start/stop button must start the cycle loop that will turn the light on and off according to the variables, but I need to "pause" the loops if the start/stop button is pressed after the loops started. There is also a screen connected for some debugging. I do decrease the CYCLE variable every loop. I have this working more or less but not without some hiccups.
I get the loop to work well if it is not stopped. When I press the start/stop button after the loops started I get a flicker of the light and while it jumps out of all the loops. The state of the light sometimes change like if the light is on and I press the start/stop button while it is cycling the light turn off. I need the light to stay in the same state when the loops are stopped as well as the variables must be the same value.
Here is my code:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
const int btnSTARTStop = 2;
const int btnONoff = 3;
const int Output = 10;
const int btnCYCLEeUp = 4;
const int btnCYCLEeDown = 5;
const int btnOnUp = 6;
const int btnOnDown = 7;
const int btnOffUp = 8;
const int btnOffDown = 9;
int _ON=2;
int _OFF=2;
int CYCLE=2;
boolean isON = false;
boolean START = false;
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
int state = HIGH;
int reading = LOW;
int previous = LOW;
long time = 0;
long debounce = 200;
int state1 = HIGH;
int reading1 = LOW;
int previous1 = LOW;
long time1 = 0;
long debounce1 = 200;
void setup()
{
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
printDisplay();
pinMode(Output, OUTPUT);
pinMode(btnONoff, INPUT);
pinMode(btnSTARTStop, INPUT);
pinMode(btnCYCLEeUp, INPUT);
pinMode(btnCYCLEeDown, INPUT);
pinMode(btnOnUp, INPUT);
pinMode(btnOnDown, INPUT);
pinMode(btnOffUp, INPUT);
pinMode(btnOffDown, INPUT);
attachInterrupt(digitalPinToInterrupt(btnSTARTStop), pin_ISR, CHANGE);
}
void loop()
{
printDisplay();
checkvarbuttons();
btnisON();
if (checkSTART()) {
printDisplay();
if (START) {
printDisplay();
STARTLoop();
}
}
}
boolean checkSTART() {
if (_OFF<=0)return false;
if (_ON <= 0)return false;
if (CYCLE <= 0)return false;
return true;
}
void STARTLoop() {
printDisplay();
while (START) {
previous1 = LOW;
timeLoop(millis(), random(3000, 5000));
printDisplay();
isON = false;
checkisON();
printDisplay();
while (CYCLE >0) {
printDisplay();
if (!START)break;
timeLoop(millis(), _OFF * 1000);
if (!START)break;
isON = true;
checkisON();
if (!START)break;
printDisplay();
if (!START)break;
timeLoop(millis(), _ON * 1000);
if (!START)break;
isON = false;
checkisON();
if (!START)break;
printDisplay();
if (!START)break;
CYCLE -= 1;
}
START = false;
}
}
void checkisON() {
if (isON) {
digitalWrite(Output, HIGH);
}
else {
digitalWrite(Output, LOW);
}
}
void pin_ISR() {
reading = digitalRead(btnSTARTStop);
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
if (state == HIGH) {
START = false;
state = LOW;
}
else {
state = HIGH;
START = true;
}
time = millis();
}
previous = reading;
}
void timeLoop(long int STARTMillis, long int interval) {
while (millis() - STARTMillis < interval) {
if (!START)break;
}
}
void printDisplay() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("CYCLEes:");
display.println(CYCLE);
display.print("_OFF:");
display.println(_OFF);
display.print("_ON:");
display.println(_ON);
if (START == false) {
display.println("Stopped");
}
else {
display.println("STARTed");
}
if (isON == false) {
display.drawRect(112, 32, 1, 32, WHITE);
}
else {
display.drawRect(112, 32, 16, 32, WHITE);
}
display.display();
delay(100);
}
void btnisON() {
reading1 = digitalRead(btnONoff);
if (reading1 == HIGH && previous1 == LOW && millis() - time1 > debounce1) {
if (state1 == HIGH) {
isON = false;
state1 = LOW;
}
else {
state1 = HIGH;
isON = true;
}
time1 = millis();
}
checkisON();
previous1 = reading1;
}
int _OFFUpprev = 0;
int _OFFDownprev = 0;
int _ONUpprev = 0;
int _ONDownprev = 0;
int CYCLEesUpprev = 0;
int CYCLEesDownprev = 0;
int _OFFUpReading = 0;
int _OFFDownReading = 0;
int _ONUpReading = 0;
int _ONDownReading = 0;
int CYCLEesUpReading = 0;
int CYCLEesDownReading = 0;
void checkvarbuttons() {
/////Button _OFFUp////////
_OFFUpReading = digitalRead(btnOnUp);
if (_OFFUpReading != _OFFUpprev) {
if (_OFFUpReading == HIGH) {
_OFF++;
printDisplay();
if (_OFF > 25)_OFF = 25;
}
delay(100);
}
_OFFUpprev = _OFFUpReading;
/////Button _OFFUp////////
/////Button _OFFDown////////
_OFFDownReading = digitalRead(btnOnDown);
if (_OFFDownReading != _OFFDownprev) {
if (_OFFDownReading == HIGH) {
_OFF -= 1;
printDisplay();
if (_OFF <0) {
_OFF = 0;
printDisplay();
}
}
delay(100);
}
_OFFDownprev = _OFFDownReading;
/////Button _OFFDown////////
/////Button _ONUp////////
_ONUpReading = digitalRead(btnOffUp);
if (_ONUpReading != _ONUpprev) {
if (_ONUpReading == HIGH) {
_ON++;
printDisplay();
if (_ON > 25)_ON = 25;
}
delay(100);
}
_ONUpprev = _ONUpReading;
/////Button _ONUp////////
/////Button _ONDown////////
_ONDownReading = digitalRead(btnOffDown);
if (_ONDownReading != _ONDownprev) {
if (_ONDownReading == HIGH) {
_ON -= 1;
printDisplay();
if (_ON <0) {
_ON = 0;
printDisplay();
}
}
delay(100);
}
_ONDownprev = _ONDownReading;
/////Button _ONDown////////
/////Button CYCLEesUp////////
CYCLEesUpReading = digitalRead(btnCYCLEeUp);
if (CYCLEesUpReading != CYCLEesUpprev) {
if (CYCLEesUpReading == HIGH) {
CYCLE++;
printDisplay();
if (CYCLE > 25)CYCLE = 25;
}
delay(100);
}
CYCLEesUpprev = CYCLEesUpReading;
/////Button CYCLEesUp////////
/////Button CYCLEesDown////////
CYCLEesDownReading = digitalRead(btnCYCLEeDown);
if (CYCLEesDownReading != CYCLEesDownprev) {
if (CYCLEesDownReading == HIGH) {
CYCLE -= 1;
printDisplay();
if (CYCLE <0) {
CYCLE = 0;
printDisplay();
}
}
delay(100);
}
CYCLEesDownprev = CYCLEesDownReading;
/////Button CYCLEesDown////////
}
It may look like a mess but there is some logic going on there.
I just need help with stopping the STARTLoop() correctly and let the light (Output) stay the same state when the loop is stopped.
Thank you.