//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <TimerOne.h>
#include <ezButton.h>
#include <TM1637.h>
#include <ArduinoTrace.h>
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Clock Variables Declaration (7:27 as default time)
#define ON 1
#define OFF 0
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char halfsecond = 0;
unsigned char second;
unsigned char hour = 7;
unsigned char minute = 27;
// Alarm Variables Declaration (00:00 as default)
unsigned char alarm_hour=0;
unsigned char alarm_minute=0;
// IMPORTANT CONTROL VARIABLES THAT DEFINES WHAT SHOWS ON DISPLAY
#define TIME 1
#define ALARM 0
bool displayMode = TIME;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//pin definitions for TM1637
TM1637 DISP;
#define CLK 2
#define DIO 3
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Button Declarations
ezButton alarmSetBtn(4); // create ezButton object that attach to pin 4;
ezButton timeSetBtn(5); // create ezButton object that attach to pin 5;
ezButton hourBtn(6); // create ezButton object that attach to pin 6;
ezButton minuteBtn(7); // create ezButton object that attach to pin 7;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Variables for miliseconds calculations
unsigned long pm1;
unsigned long pm2;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void setup(){
// Set serial monitor frecuency
Serial.begin(115200);
// Display init
DISP.begin(CLK, DIO, 4); // clockpin, datapin, #digits
DISP.displayClear();
DISP.setBrightness(7); // full brightness, default is 3
// Timer for clock init
Timer1.initialize(500000);//timing for 500ms
Timer1.attachInterrupt(TimingISR);//declare the interrupt serve routine:TimingISR
// Debounce times and pin configuration for buttons
alarmSetBtn.setDebounceTime(50);
timeSetBtn.setDebounceTime(50); // set debounce time to 50 milliseconds
hourBtn.setDebounceTime(50);
minuteBtn.setDebounceTime(50);
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
}
void loop(){
// Update Clock
if (Update == ON) TimeUpdate();
// Always display time, clockpoint bool defines if dots
// show or not, no need for extra code in TimeUpdate func
if(displayMode==TIME){
DISP.displayTime(hour,minute,ClockPoint);
}else{
DISP.displayTime(alarm_hour,alarm_minute,ClockPoint);
}
// Button functions
alarmSetBtn.loop();
timeSetBtn.loop();
hourBtn.loop();
minuteBtn.loop();
// Changing time with buttons
incrementHours_Time();
incrementMinute_Time();
// Changing the alarm time with buttons
incrementHours_Alarm();
incrementMinute_Alarm();
// Making time into the right format
hour%=24;
minute%=60;
alarm_hour%=24;
alarm_minute%=60;
}
// Clock functions and Calculations
void TimingISR(){
halfsecond ++;
Update = ON;
if(halfsecond == 2){
second ++;
if(second == 60)
{
minute ++;
if(minute == 60)
{
hour ++;
if(hour == 24)hour = 0;
minute = 0;
}
second = 0;
}
halfsecond = 0;
}
ClockPoint = (~ClockPoint) & 0x01;
}
void TimeUpdate(void){
Update = OFF;
}
//Button functions to change time
void incrementHours_Time(){
enum {s0,s1,s2,s3};
static int state=s0;
switch(state)
{
case s0:
if(timeSetBtn.getState()==LOW)
{
state=s1;
displayMode=TIME;
}
break;
case s1:
if(hourBtn.getState()==LOW && timeSetBtn.getState()==LOW)
{
hour++;
pm1=millis();
state=s2;
}
else
{
state=s0;
}
break;
case s2:
if(hourBtn.getState()==LOW && timeSetBtn.getState()==LOW)
{
if((millis()-pm1)>800)
{
pm1=millis();
state=s3;
}
}
else
{
state=s0;
}
break;
case s3:
if(hourBtn.getState()==LOW && timeSetBtn.getState()==LOW)
{
if((millis()-pm1)>250)
{
pm1=millis();
hour++;
}
}
else
{
state=s0;
}
break;
}
}
void incrementMinute_Time(){
enum {s0,s1,s2,s3};
static int state=s0;
switch(state)
{
case s0:
if(timeSetBtn.getState()==LOW)
{
state=s1;
displayMode=TIME;
}
break;
case s1:
if(minuteBtn.getState()==LOW && timeSetBtn.getState()==LOW)
{
minute++;
pm2=millis();
state=s2;
}
else
{
state=s0;
}
break;
case s2:
if(minuteBtn.getState()==LOW && timeSetBtn.getState()==LOW)
{
if((millis()-pm2)>800)
{
pm2=millis();
state=s3;
}
}
else
{
state=s0;
}
break;
case s3:
if(minuteBtn.getState()==LOW && timeSetBtn.getState()==LOW)
{
if((millis()-pm2)>250)
{
pm2=millis();
minute++;
}
}
else
{
state=s0;
}
break;
}
}
//Button functions to change the alarm time
void incrementHours_Alarm(){
enum {s0,s1,s2,s3};
static int state=s0;
switch(state)
{
case s0:
if(alarmSetBtn.getState()==LOW)
{
state=s1;
displayMode=ALARM;
}
break;
case s1:
if(hourBtn.getState()==LOW && alarmSetBtn.getState()==LOW)
{
alarm_hour++;
pm1=millis();
state=s2;
}
else
{
state=s0;
}
break;
case s2:
if(hourBtn.getState()==LOW && alarmSetBtn.getState()==LOW)
{
if((millis()-pm1)>800)
{
pm1=millis();
state=s3;
}
}
else
{
state=s0;
}
break;
case s3:
if(hourBtn.getState()==LOW && alarmSetBtn.getState()==LOW)
{
if((millis()-pm1)>250)
{
pm1=millis();
alarm_hour++;
}
}
else
{
state=s0;
}
break;
}
}
void incrementMinute_Alarm(){
enum {s0,s1,s2,s3};
static int state=s0;
switch(state)
{
case s0:
if(alarmSetBtn.getState()==LOW)
{
state=s1;
displayMode=ALARM;
}
break;
case s1:
if(minuteBtn.getState()==LOW && alarmSetBtn.getState()==LOW)
{
alarm_minute++;
pm2=millis();
state=s2;
}
else
{
state=s0;
}
break;
case s2:
if(minuteBtn.getState()==LOW && alarmSetBtn.getState()==LOW)
{
if((millis()-pm2)>800)
{
pm2=millis();
state=s3;
}
}
else
{
state=s0;
}
break;
case s3:
if(minuteBtn.getState()==LOW && alarmSetBtn.getState()==LOW)
{
if((millis()-pm2)>250)
{
pm2=millis();
alarm_minute++;
}
}
else
{
state=s0;
}
break;
}
}