class Timer {
private:
unsigned long nextChangeTime;
unsigned long timeOn_;
boolean overFlow;
public:
void TimerSet (unsigned long timeOn) {
timeOn_ = timeOn;
unsigned long currentTime = millis();
nextChangeTime = currentTime + timeOn_;
if (nextChangeTime > currentTime) {
overFlow = false;
} else {
overFlow = true;
}
}
boolean TimerActive() {
unsigned long currentTime = millis();
boolean val = false;
if (! overFlow) {
if (currentTime < nextChangeTime) {
val = true;
}
} else if ((currentTime + timeOn_)<(nextChangeTime + timeOn_)){
val = true;
}
return val;
}
};
Timer TMR;
int minute = 10000;
#include <LiquidCrystal_I2C.h> /*include LCD I2C Library*/
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
int BTN_SET = 12;
byte buttonState_SET = HIGH;
int BTN_TH = 11;
byte buttonState_TH = HIGH;
int BTN_TM = 10;
byte buttonState_TM = HIGH;
int BTN_DD = 9;
byte buttonState_DD = HIGH;
int BTN_DM = 8;
byte buttonState_DM = HIGH;
int BTN_AH = 7;
byte buttonState_AH = HIGH;
int BTN_AM = 6;
byte buttonState_AM = HIGH;
int BTN_RD = 5;
byte buttonState_RD = HIGH;
int BTN_RU = 4;
byte buttonState_RU = HIGH;
int BTN_RADIO = A1;
byte buttonState_RADIO = HIGH;
int BTN_SNOOZE = A0;
byte buttonState_SNOOZE = HIGH;
unsigned long debounceDuration = 50; //millis
int LED = 13;
int SWITCH_ONOFF = 3;
byte switchState_ONOFF = LOW;
int SWITCH_MODE = 2;
byte switchState_MODE = LOW;
int POT_VOL = A3;
int timeHour = 12;
int timeMin = 0;
int dateDay = 6;
int dateMonth = 9;
int alarmHour = 12;
int alarmMin = 1;
float radioFreq = 93.5;
bool isAlarmOn = false;
bool isRadioOn = false;
int volValue;
int lastVolValue;
bool timerActive = false;
enum alarmModeType {
off,
buzz,
radio
};
alarmModeType alarmMode = off;
byte radioChar[] = {
B00001,
B00011,
B00101,
B01001,
B01001,
B01011,
B11011,
B11000
};
byte alarmChar[] = {
B00000,
B00100,
B01110,
B01110,
B01110,
B11111,
B00100,
B00000
};
byte volumeChar[] = {
B00001,
B00011,
B00111,
B11111,
B11111,
B00111,
B00011,
B00001
};
void setup() {
lcd.init();
lcd.clear();
lcd.backlight();
lcd.createChar(0, radioChar);
lcd.createChar(1, alarmChar);
lcd.createChar(2, volumeChar);
pinMode(BTN_SET, INPUT_PULLUP);
pinMode(BTN_TH, INPUT_PULLUP);
pinMode(BTN_TM, INPUT_PULLUP);
pinMode(BTN_DD, INPUT_PULLUP);
pinMode(BTN_DM, INPUT_PULLUP);
pinMode(BTN_AH, INPUT_PULLUP);
pinMode(BTN_AM, INPUT_PULLUP);
pinMode(BTN_RD, INPUT_PULLUP);
pinMode(BTN_RU, INPUT_PULLUP);
pinMode(BTN_RADIO, INPUT_PULLUP);
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
pinMode(SWITCH_ONOFF, INPUT_PULLUP);
pinMode(SWITCH_MODE, INPUT_PULLUP);
lastVolValue = map(analogRead(POT_VOL), 0, 1023, 0, 10);
displayHandler();
}
void loop() {
checkAlarmMode();
checkVolButton();
if (timerActive) {
if(!TMR.TimerActive()){
if (timeMin >= 59) {
timeMin = minuteHandler(timeMin);
timeHour = hourHandler(timeHour);
checkIsAlarmOn();
displayHandler();
TMR.TimerSet(minute);
} else {
timeMin = minuteHandler(timeMin);
checkIsAlarmOn();
displayHandler();
TMR.TimerSet(minute);
}
}
} else {
TMR.TimerSet(minute);
timerActive = true;
}
if (buttonState_RADIO == HIGH) {
checkSetButton();
}
if (buttonState_SET == HIGH) {
checkRadioButton();
checkSnoozeButton();
}
if (buttonState_SET == LOW){
if (buttonState_TM == HIGH && buttonState_DD == HIGH && buttonState_DM == HIGH && buttonState_AH == HIGH && buttonState_AM == HIGH && buttonState_RD == HIGH && buttonState_RU == HIGH){
checkTHButton();
}
if (buttonState_TH == HIGH && buttonState_DD == HIGH && buttonState_DM == HIGH && buttonState_AH == HIGH && buttonState_AM == HIGH && buttonState_RD == HIGH && buttonState_RU == HIGH){
checkTMButton();
}
if (buttonState_TH == HIGH && buttonState_TM == HIGH && buttonState_DM == HIGH && buttonState_AH == HIGH && buttonState_AM == HIGH && buttonState_RD == HIGH && buttonState_RU == HIGH){
checkDDButton();
}
if (buttonState_TH == HIGH && buttonState_TM == HIGH && buttonState_DD == HIGH && buttonState_AH == HIGH && buttonState_AM == HIGH && buttonState_RD == HIGH && buttonState_RU == HIGH){
checkDMButton();
}
if (buttonState_TH == HIGH && buttonState_TM == HIGH && buttonState_DD == HIGH && buttonState_DM == HIGH && buttonState_AM == HIGH && buttonState_RD == HIGH && buttonState_RU == HIGH){
checkAHButton();
}
if (buttonState_TH == HIGH && buttonState_TM == HIGH && buttonState_DD == HIGH && buttonState_DM == HIGH && buttonState_AH == HIGH && buttonState_RD == HIGH && buttonState_RD == HIGH){
checkAMButton();
}
if (buttonState_TH == HIGH && buttonState_TM == HIGH && buttonState_DD == HIGH && buttonState_DM == HIGH && buttonState_AH == HIGH && buttonState_AM == HIGH && buttonState_RU == HIGH){
checkRDButton();
}
if (buttonState_TH == HIGH && buttonState_TM == HIGH && buttonState_DD == HIGH && buttonState_DM == HIGH && buttonState_AH == HIGH && buttonState_AM == HIGH && buttonState_RD == HIGH){
checkRUButton();
}
}
}
//SET Button
unsigned long lastTimeButtonStateChanged_SET = 0;
byte lastButtonState_SET = LOW;
void checkSetButton() {
if (millis() - lastTimeButtonStateChanged_SET > debounceDuration) {
buttonState_SET = digitalRead(BTN_SET);
if (buttonState_SET != lastButtonState_SET) {
lastTimeButtonStateChanged_SET = millis();
lastButtonState_SET = buttonState_SET;
}
}
};
//TH Button
unsigned long lastTimeButtonStateChanged_TH = 0;
byte lastButtonState_TH = LOW;
void checkTHButton() {
if (millis() - lastTimeButtonStateChanged_TH > debounceDuration) {
buttonState_TH = digitalRead(BTN_TH);
if (buttonState_TH != lastButtonState_TH) {
lastTimeButtonStateChanged_TH = millis();
lastButtonState_TH = buttonState_TH;
if (buttonState_TH == LOW) {
timeHour = hourHandler(timeHour);
displayHandler();
}
}
}
};
//TM Button
unsigned long lastTimeButtonStateChanged_TM = 0;
byte lastButtonState_TM = LOW;
void checkTMButton() {
if (millis() - lastTimeButtonStateChanged_TM > debounceDuration) {
buttonState_TM = digitalRead(BTN_TM);
if (buttonState_TM != lastButtonState_TM) {
lastTimeButtonStateChanged_TM = millis();
lastButtonState_TM = buttonState_TM;
if (buttonState_TM == LOW) {
timeMin = minuteHandler(timeMin);
displayHandler();
}
}
}
};
// DD Button
unsigned long lastTimeButtonStateChanged_DD = 0;
byte lastButtonState_DD = LOW;
void checkDDButton() {
if (millis() - lastTimeButtonStateChanged_DD > debounceDuration) {
buttonState_DD = digitalRead(BTN_DD);
if (buttonState_DD != lastButtonState_DD) {
lastTimeButtonStateChanged_DD = millis();
lastButtonState_DD = buttonState_DD;
if (buttonState_DD == LOW) {
dateDay = dayHandler(dateDay, dateMonth);
displayHandler();
}
}
}
};
// DM Button
unsigned long lastTimeButtonStateChanged_DM = 0;
byte lastButtonState_DM = LOW;
void checkDMButton() {
if (millis() - lastTimeButtonStateChanged_DM > debounceDuration) {
buttonState_DM = digitalRead(BTN_DM);
if (buttonState_DM != lastButtonState_DM) {
lastTimeButtonStateChanged_DM = millis();
lastButtonState_DM = buttonState_DM;
if (buttonState_DM == LOW) {
dateMonth = monthHandler(dateMonth);
displayHandler();
}
}
}
};
//AH Button
unsigned long lastTimeButtonStateChanged_AH = 0;
byte lastButtonState_AH = LOW;
void checkAHButton() {
if (millis() - lastTimeButtonStateChanged_AH > debounceDuration) {
buttonState_AH = digitalRead(BTN_AH);
if (buttonState_AH != lastButtonState_AH) {
lastTimeButtonStateChanged_AH = millis();
lastButtonState_AH = buttonState_AH;
if (buttonState_AH == LOW) {
alarmHour = hourHandler(alarmHour);
displayHandler();
}
}
}
};
//AM Button
unsigned long lastTimeButtonStateChanged_AM = 0;
byte lastButtonState_AM = LOW;
void checkAMButton() {
if (millis() - lastTimeButtonStateChanged_AM > debounceDuration) {
buttonState_AM = digitalRead(BTN_AM);
if (buttonState_AM != lastButtonState_AM) {
lastTimeButtonStateChanged_AM = millis();
lastButtonState_AM = buttonState_AM;
if (buttonState_AM == LOW) {
alarmMin = minuteHandler(alarmMin);
displayHandler();
}
}
}
};
// RD Button
unsigned long lastTimeButtonStateChanged_RD = 0;
byte lastButtonState_RD = LOW;
void checkRDButton() {
if (millis() - lastTimeButtonStateChanged_RD > debounceDuration) {
buttonState_RD = digitalRead(BTN_RD);
if (buttonState_RD != lastButtonState_RD) {
lastTimeButtonStateChanged_RD = millis();
lastButtonState_RD = buttonState_RD;
if (buttonState_RD == LOW) {
radioFreq = radioFreqHandler(radioFreq, false);
displayHandler();
}
}
}
};
// RU Button
unsigned long lastTimeButtonStateChanged_RU = 0;
byte lastButtonState_RU = LOW;
void checkRUButton() {
if (millis() - lastTimeButtonStateChanged_RU > debounceDuration) {
buttonState_RU = digitalRead(BTN_RU);
if (buttonState_RU != lastButtonState_RU) {
lastTimeButtonStateChanged_RU = millis();
lastButtonState_RU = buttonState_RU;
if (buttonState_RU == LOW) {
radioFreq = radioFreqHandler(radioFreq, true);
displayHandler();
}
}
}
};
// RADIO Button
unsigned long lastTimeButtonStateChanged_RADIO = 0;
byte lastbuttonState_RADIO = LOW;
void checkRadioButton() {
if (millis() - lastTimeButtonStateChanged_RADIO > debounceDuration) {
buttonState_RADIO = digitalRead(BTN_RADIO);
if (buttonState_RADIO != lastbuttonState_RADIO) {
lastTimeButtonStateChanged_RADIO = millis();
lastbuttonState_RADIO = buttonState_RADIO;
if (buttonState_RADIO == LOW) {
if(isRadioOn && isAlarmOn){
isAlarmOn = false;
}
radioHandler();
displayHandler();
}
}
}
};
// SNOOZE Button
unsigned long lastTimeButtonStateChanged_SNOOZE = 0;
byte lastbuttonState_SNOOZE = LOW;
void checkSnoozeButton() {
if (millis() - lastTimeButtonStateChanged_SNOOZE > debounceDuration) {
buttonState_SNOOZE = digitalRead(BTN_SNOOZE);
if (buttonState_SNOOZE != lastbuttonState_SNOOZE) {
lastTimeButtonStateChanged_SNOOZE = millis();
lastbuttonState_SNOOZE = buttonState_SNOOZE;
if (buttonState_SNOOZE == LOW) {
isAlarmOn = false;
if (isRadioOn) {
isRadioOn = false;
}
displayHandler();
}
}
}
};
// ALARM Mode
void checkAlarmMode() {
switchState_ONOFF = digitalRead(SWITCH_ONOFF);
switchState_MODE = digitalRead(SWITCH_MODE);
if (switchState_ONOFF == LOW) {
alarmMode = off;
} else if (switchState_ONOFF == HIGH && switchState_MODE == LOW) {
alarmMode = buzz;
} else if (switchState_ONOFF == HIGH && switchState_MODE == HIGH){
alarmMode = radio;
}
handleAlarmModeIndicators();
};
// VOL Button
unsigned long lastTimeVolValueChanged = 0;
void checkVolButton() {
volValue = map(analogRead(POT_VOL), 0, 1023, 0, 10);
if (volValue != lastVolValue) {
lastTimeVolValueChanged = millis();
lastVolValue = volValue;
displayHandler();
}
};
void checkIsAlarmOn() {
if (alarmMode != off && timeHour == alarmHour && timeMin == alarmMin) {
isAlarmOn = true;
if (alarmMode == radio){
isRadioOn = true;
}
} else {
isAlarmOn = false;
}
}
void handleAlarmModeIndicators() {
if (alarmMode != off){
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}
int hourHandler(int hour) {
if (hour <= 22) {
hour ++;
} else {
hour = 0;
}
return hour;
}
int minuteHandler(int minute) {
if (minute <= 58) {
minute ++;
} else {
minute = 0;
}
return minute;
}
int dayHandler(int day, int month) {
int maxValue = 31;
if (month == 2) {
maxValue = 28;
}
if (month == 4 || month == 6 || month == 9 || month == 11) {
maxValue = 30;
}
if (day <= (maxValue - 1)) {
day ++;
} else {
day = 1;
}
return day;
}
int monthHandler(int month) {
if (month <= 11) {
month ++;
} else {
month = 1;
}
return month;
}
float radioFreqHandler(float radio, bool up) {
float maxValue = 108.5;
float minValue = 88.0;
if (up) {
if (radio < maxValue) {
radio = radio + 0.5;
}
} else {
if (radio > minValue) {
radio = radio - 0.5;
}
}
return radio;
}
void radioHandler(){
if (isRadioOn) {
isRadioOn = false;
} else {
isRadioOn = true;
}
}
void displayHandler(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print(parseDisplayValue(timeHour) + ":" + parseDisplayValue(timeMin));
lcd.setCursor(7,0);
lcd.print(parseDisplayValue(dateDay) + "/" + parseDisplayValue(dateMonth));
lcd.setCursor(0,1);
if (isAlarmOn && !isRadioOn){
lcd.print(parseDisplayValue(alarmHour) + ":" + parseDisplayValue(alarmMin) + char(1));
} else {
lcd.print(parseDisplayValue(alarmHour) + ":" + parseDisplayValue(alarmMin));
}
lcd.setCursor(7,1);
if (isRadioOn){
lcd.print(String(radioFreq, 1) + char(0));
} else {
lcd.print(String(radioFreq, 1));
}
lcd.setCursor(13,1);
lcd.print(char(2) + String(volValue));
};
String parseDisplayValue(int value) {
if (value < 10){
return "0" + String(value);
} else {
return String(value);
}
}