twobuttonstimer/twobuttonstimer.ino

243 lines
8.0 KiB
C++

// 2 relay-buttons on timer with 4-digit display
#include <Arduino.h>
#include <TimeLib.h>
#include <Thread.h>
#include <DS1307RTC.h> // A basic DS1307 library that returns time as a time_t
#include <SevenSegmentExtended.h> // Extended TM1637 library https://github.com/bremme/arduino-tm1637
const byte PIN_CLK = 2; // Define CLK pin (for 4-Digit Display)
const byte PIN_DIO = 3; // Define DIO pin (for 4-Digit Display)
const byte redButton = 4; // RedButton: light on, open door
const byte blackButton = 5; // BlackButton: light off, close door
const byte stopButtonRelay = 6;
const byte startButtonRelay = 7;
const int msStart = 650; // Interval for pressing start button, ms
const int msStop = 750; // Interval for pressing stop button, ms
const int updateTime = 1000; // Interval for digit display update
const int buttonCheck = 200; // Interval for checking button state
const long manualButtonTime = 1800000; // 60 min - actual state of manual pressed button
long buttonMillis = 0; // Previous button press counter
byte indicator = 0; // Indicator of working states: 0 - scheduled off; 1 - scheduled on;
// 2 - manual off, 3 - manual on
SevenSegmentExtended display(PIN_CLK, PIN_DIO);
Thread showTimeThread = Thread(); // Create thread for LED pulse indication
Thread pressButtonThread = Thread(); // Create thread for button state checking
void setup() {
Serial.begin(9600); // Initializes the Serial connection @ 9600 baud for debug
serStr("starting setup...");
display.begin(); // Initializes the display
display.setBacklight(100); // Set the brightness to 100 %
display.print("INIT"); // Display INIT on the display
pinMode(redButton, INPUT);
pinMode(blackButton, INPUT);
pinMode(stopButtonRelay, OUTPUT);
pinMode(startButtonRelay, OUTPUT);
while (!Serial); // Wait until Arduino Serial Monitor opens
setSyncProvider(RTC.get); // The function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
// showTime thread:
showTimeThread.onRun(showTime);
showTimeThread.setInterval(updateTime); // Interval for update time
// pressButtonThread thread:
pressButtonThread.onRun(pressButton);
pressButtonThread.setInterval(buttonCheck); // Interval for checking button pressing
delay(1000);
display.off();
delay(500);
display.on();
serStr("...setup finished");
}
void loop() {
// Threads init:
if (showTimeThread.shouldRun())
showTimeThread.run();
if (pressButtonThread.shouldRun())
pressButtonThread.run();
if (timeStatus() == timeSet) {
checkTime();
} else {
display.on();
display.print("SET TIME");
delay(5000);
}
}
// showTime thread
void showTime() {
display.printTime(hour(), minute(), true);
static bool showTimeStatus = false; // showTime status bool
showTimeStatus = !showTimeStatus; // Invert showTime state
if ((indicator==1)||(indicator==3) && showTimeStatus==true) {
display.print("BODA");
}
}
void pressStart() {
serStr("scheduled start button pressed");
display.print("on__");
delay(55000);
indicator = 1;
digitalWrite(startButtonRelay, HIGH);
delay(msStart);
digitalWrite(startButtonRelay, LOW);
delay(6000);
serStr("scheduled start button delay finished");
}
void pressStop() {
serStr("scheduled stop button pressed");
display.print("off_");
delay(5000);
indicator = 0;
digitalWrite(stopButtonRelay, HIGH);
delay(msStop);
digitalWrite(stopButtonRelay, LOW);
delay(61000); // wait a minute
// Double!
digitalWrite(stopButtonRelay, HIGH);
delay(msStop);
digitalWrite(stopButtonRelay, LOW);
delay(5000);
serStr("scheduled stop button delay finished");
}
void pressStopFalse() {
serStr("scheduled false-stop");
display.print("off_");
delay(5000);
indicator = 0;
delay(61000); // wait a minute
}
void pressStartManual() {
serStr("manual start button pressed");
display.print("on__");
buttonMillis = millis();
delay(500);
indicator = 3;
digitalWrite(startButtonRelay, HIGH);
delay(msStart);
digitalWrite(startButtonRelay, LOW);
delay(1500);
serStr("manual start button delay finished");
}
void pressStopManual() {
serStr("manual stop button pressed");
display.print("off_");
buttonMillis = millis();
delay(500);
indicator = 2;
digitalWrite(stopButtonRelay, HIGH);
delay(msStop);
digitalWrite(stopButtonRelay, LOW);
delay(1500);
serStr("manual stop button delay finished");
}
// Send string to serial monitor with millis() counter and date/time
void serStr(const char* serString) {
long currentTime = millis();
String space = " ";
String stringToPrint = currentTime + space + serString;
Serial.println(stringToPrint);
// RTC mark
Serial.print("RTC time = ");
Serial.print(hour());
Serial.write(':');
Serial.print(minute());
Serial.write(':');
Serial.print(second());
Serial.print(", date (D/M/Y) = ");
Serial.print(day());
Serial.write('/');
Serial.print(month());
Serial.write('/');
Serial.print(year());
Serial.println();
}
// Check button pressing thread
void pressButton() {
unsigned long currentMillis = millis();
if (buttonMillis>0) {
if (indicator==3) {
if ((currentMillis-buttonMillis) > manualButtonTime) {
serStr("manualButtonTime expired...stop pressed");
buttonMillis = 0;
pressStop();
}
}
if (indicator==2) {
if ((currentMillis-buttonMillis) > manualButtonTime) {
serStr("manualButtonTime expired...indicator state reset");
buttonMillis = 0;
indicator = 0;
}
}
}
if (digitalRead(redButton) == HIGH || digitalRead(blackButton) == HIGH) {
if (digitalRead(redButton) == HIGH) {
serStr("Manual red button short press");
pressStartManual();
}
if (digitalRead(blackButton) == HIGH) {
serStr("Manual black button short press");
pressStopManual();
}
}
}
void checkTime() {
// Winter
if (month()==12 || month()==1 || month()==2 ) {
// 6:00 - 7:16 - working
if ((hour()==6) && (indicator==0)) pressStart();
// 7:01 - stop
if ((hour()==7) && (minute()==16)) pressStopFalse();
// 12:00 - 13:01 - working
if ((hour()==12) && (indicator==0)) pressStart();
// 13:01 - stop
if ((hour()==13) && (minute()==1)) pressStopFalse();
// 17:00 - 18:01 - working
if ((hour()==17) && (indicator==0)) pressStart();
// 18:01 - stop
if ((hour()==18) && (minute()==1)) pressStopFalse();
}
// Spring & Autumn
if (month()==3 || month()==4 || month()==10 || month()==11) {
// 6:00 - 8:21 - working
if ((hour()==6 || hour()==7 || ((hour()==8) && (minute() < 5))) && (indicator==0)) pressStart();
// 8:21 - stop
if ((hour()==8) && (minute()==21)) pressStopFalse();
// 12:00 - 13:26 - working
if ((hour()==12 || ((hour()==13) && (minute() < 10))) && (indicator==0)) pressStart();
// 13:26 - stop
if ((hour()==13) && (minute()==26)) pressStopFalse();
// 17:00 - 18:21 - working
if ((hour()==17 || ((hour()==18) && (minute() < 5))) && (indicator==0)) pressStart();
// 18:21 - stop
if ((hour()==18) && (minute()==21)) pressStopFalse();
}
// Summer
if (month()==5 || month()==6 || month()==7 || month()==8 || month()==9) {
// 6:00 - 9:05 - working
if ((hour()==6 || hour()==7 || hour()==8) && (indicator==0)) pressStart();
// 9:05 - stop
if ((hour()==9) && (minute()==5)) pressStopFalse();
// 12:00 - 14:05 - working
if ((hour()==12 || hour()==13) && (indicator==0)) pressStart();
// 14:05 - stop
if ((hour()==14) && (minute()==5)) pressStopFalse();
// 17:00 - 19:50 - working
if ((hour()==17 || hour()==18) && (indicator==0)) pressStart();
// 19:50 - stop
if ((hour()==19) && (minute()==50)) pressStopFalse();
}
}