// segment macros #define A 5 #define B 8 #define C A3 #define D A1 #define E A0 #define F 6 #define G A4 #define DP A2 // common anodes macros #define GND1 7 #define GND2 9 #define GND3 10 #define GND4 A5 #define DOWN 0 #define UP 1 #define BUZZER 11 int minutes = 0; int seconds = 0; volatile boolean TurnUpDetected; //rotary encoder volatile boolean TurnDownDetected; unsigned long Watch, _micro; unsigned int Clock = 0, R_clock; boolean Reset = false, Stop = true, Paused = false, _type; volatile boolean timeFlag = false; unsigned long time; int timer=0; boolean timerStart=false; int i=0; // functions to display digits void setup() { pinMode(2, INPUT_PULLUP); pinMode(4, INPUT_PULLUP); pinMode(3, INPUT);//button attachInterrupt(digitalPinToInterrupt(2), setState, FALLING); pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT); pinMode(E, OUTPUT); pinMode(F, OUTPUT); pinMode(G, OUTPUT); pinMode(DP, OUTPUT); pinMode(BUZZER, OUTPUT); pinMode(GND1, OUTPUT); pinMode(GND2, OUTPUT); pinMode(GND3, OUTPUT); pinMode(GND4, OUTPUT); digitalWrite(DP, HIGH); Serial.begin(9600); } void digit0 () { digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, HIGH); } void digit1 () { digitalWrite(A,HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, HIGH); } void digit2 () { digitalWrite(A,LOW); digitalWrite(B, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, HIGH); digitalWrite(G, LOW); }; void digit3 () { digitalWrite(A,LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, LOW); } void digit4 () { digitalWrite(A,HIGH); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(G, LOW); } void digit5 () { digitalWrite(A,LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(G, LOW); } void digit6 () { digitalWrite(A,LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW); } void digit7 () { digitalWrite(A,LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, HIGH); } void digit8 () { digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); digitalWrite(E, LOW); digitalWrite(F, LOW); digitalWrite(G, LOW); } void digit9 () { digitalWrite(A, LOW); digitalWrite(B, LOW); digitalWrite(C, LOW); digitalWrite(D, LOW); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(G, LOW); } void showdigit (int digit) { switch (digit) { case 0: digit0 (); break; case 1: digit1 (); break; case 2: digit2 (); break; case 3: digit3 (); break; case 4: digit4 (); break; case 5: digit5 (); break; case 6: digit6 (); break; case 7: digit7 (); break; case 8: digit8 (); break; case 9: digit9 (); break; default: break; }; } // showing 4 digits void showdigits (int number) { // e.g. we have "1234" showdigit(number/1000); // segments are set to display "1" digitalWrite(GND1, HIGH); // first digit on, digitalWrite(GND2, LOW); // other off digitalWrite(GND3, LOW); digitalWrite(GND4, LOW); digitalWrite(DP, HIGH); delay (1); number = number%1000; // remainder of 1234/1000 is 234 digitalWrite(GND1, LOW); // first digit is off showdigit(number/100); //// segments are set to display "2" digitalWrite(GND2, HIGH); // second digit is on digitalWrite(DP, LOW); delay (1); // and so on.... number =number%100; digitalWrite(GND2, LOW); showdigit(number/10); digitalWrite(GND3, HIGH); digitalWrite(DP, HIGH); delay (1); number =number%10; digitalWrite(GND3, LOW); showdigit(number); digitalWrite(GND4, HIGH); digitalWrite(DP, HIGH); delay (1); }; void loop () { if(timerStart) { CountUpDownTimer(DOWN); timer++; showdigits(i); if (timer==10) { timer = 0; } } if (TimeHasChanged() && timerStart) { int screenMinutes = ShowMinutes(); int screenSeconds = ShowSeconds(); i=(screenMinutes*100)+screenSeconds; if(Clock==0) { playAlarm(); timerStart=false; } } if(!timerStart) { //Serial.println(minutes); showCurrentTime(); if(TurnDownDetected) { TurnDownDetected = false; if(seconds>0&&seconds<3600) seconds=seconds-30; if(seconds>=3600) seconds=seconds-60; SetTimer(0,0,seconds); } if(TurnUpDetected) { TurnUpDetected = false; if(seconds>=0&&seconds<3600) seconds=seconds+30; if(seconds>=3600) seconds=seconds+60; SetTimer(0,0,seconds); } if (digitalRead(3)==LOW && Clock!=0) { timerStart = true; time = micros(); StartTimer(); } } } void showCurrentTime() { showdigits(i); int screenMinutes = ShowMinutes(); int screenSeconds = ShowSeconds(); int screenHours = ShowHours(); if(screenMinutes<60) { i= (screenMinutes*100)+screenSeconds; } if(screenMinutes>=60) { i=(screenHours*100)+screenMinutes%60; } if (timer==10) { timer = 0; } } void setState() //encoder { if(digitalRead(4)) { TurnDownDetected = true; } else { TurnUpDetected = true; } } void playAlarm() // { for(int i=0;i<12;i++) { tone(11, 4000); //4kHz pwm sequention delay(100); noTone(11); delay(100); tone(11, 4001); delay(100); noTone(11); delay(700); } } boolean CountUpDownTimer(boolean Type) { _type = Type; static unsigned long duration = 1000000; // 1 second timeFlag = false; if (!Stop && !Paused) // if not Stopped or Paused, run timer { // check the time difference and see if 1 second has elapsed if ((_micro = micros()) - time > duration ) { _type == UP? Clock++ : Clock--; timeFlag = true; if (_type == DOWN && Clock == 0) // check to see if the clock is 0 Stop = true; // If so, stop the timer // check to see if micros() has rolled over, if not, // then increment "time" by duration _micro < time ? time = _micro : time += duration; } } return !Stop; // return the state of the timer } void ResetTimer() { if(_type) Clock = 0; else SetTimer(R_clock); Stop = false; } void StartTimer() { Watch = micros(); // get the initial microseconds at the start of the timer Stop = false; Paused = false; if(_type == UP) Clock = 0; } void StopTimer() { Stop = true; } void StopTimerAt(unsigned int hours,unsigned int minutes, unsigned int seconds) { if (TimeCheck(hours, minutes, seconds) ) Stop = true; } void PauseTimer() { Paused = true; } void ResumeTimer() // You can resume the timer if you ever stop it. { Paused = false; } void SetTimer(unsigned int hours, unsigned int minutes, unsigned int seconds) { // This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1, 2, 0 unsigned int _S = (seconds / 60), _M = (minutes / 60); if(_S) minutes += _S; Clock = (minutes * 60) + (seconds % 60); R_clock = Clock; } void SetTimer(unsigned int seconds) { // StartTimer(seconds / 3600, (seconds / 3600) / 60, seconds % 60); Clock = seconds; R_clock = Clock; Stop = false; } int ShowMinutes() { return Clock / 60; } int ShowSeconds() { return Clock % 60; } int ShowHours() { return Clock / 3600; } boolean TimeHasChanged() { return timeFlag; } // output true if timer equals requested time boolean TimeCheck(unsigned int hours, unsigned int minutes, unsigned int seconds) { return (hours == ShowHours() && minutes == ShowMinutes() && seconds == ShowSeconds()); }