/*
Pressing the button for more than 3 sedonds changes the mode
Quick press considered short press
Mode: 1. Clock
2. Stopwatch
Short press in Stopwatch mode starts the stopwatch. Second press stop the counting
and the third press resets it and start again.
*/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET 1
#include "RTClib.h"
RTC_DS3231 rtc;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int timer = 0;
int mode = 0;
bool srt = false;
unsigned long prevTime = 0;
bool down = false;
unsigned long startMillis;
unsigned long currentMillis;
unsigned long elapsedMillis;
unsigned long allSeconds;
const float pi = 3.14159267 ;
const int clock_center_x=85;
const int clock_center_y=32;
int x,y,x1,y1;
int seconds=0;
int minutes;
int hours;
int runHours;
int secsRemaining;
int runMinutes;
int runSeconds;
void setup() {
Serial.begin(9600);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
attachInterrupt(digitalPinToInterrupt(2),modChan,CHANGE);
int sec = InitSec();
int minu = InitMin();
int hr = InitHr();
DateTime newTime = DateTime(0,0,0,hr,minu,sec);
rtc.adjust(newTime);
display.display();
delay(2000);
display.clearDisplay();
draw_clock_face();
display.display();
}
void modChan(){
down = !down;
if(down){
prevTime = millis();
}else{
unsigned long duration = millis() - prevTime;
timer = duration;
}
}
int InitSec(){
Serial.println("Input Seconds");
while(!Serial.available()){;}
int sec = Serial.readString().toInt();
if(sec < 60 && sec > 0){
return sec;
} else{ return 0; }
}
int InitMin(){
Serial.println("Input Minutes");
while(!Serial.available()){;}
int minu = Serial.readString().toInt();
if(minu < 60 && minu > 0){
return minu;
} else{ return 0; }
}
int InitHr(){
Serial.println("Input Hour");
while(!Serial.available()){;}
int hr = Serial.readString().toInt();
if(hr < 24 && hr > 0){
return hr;
} else{ return 0; }
}
void draw_second(int second){
y= (24*cos(pi-(2*pi)/60*second))+clock_center_y;
x =(24*sin(pi-(2*pi)/60*second))+clock_center_x;
display.drawCircle(x, y, 1, SSD1306_WHITE);
}
void draw_hour(int hour, int minute){
y= (18*cos(pi-(2*pi)/12*hour-(2*PI)/720*minute))+clock_center_y;
x =(18*sin(pi-(2*pi)/12*hour-(2*PI)/720*minute))+clock_center_x;
y1=(18*cos(pi-(2*pi)/12*hour-(2*PI)/720*minute))+clock_center_y+1;
x1=(18*sin(pi-(2*pi)/12*hour-(2*PI)/720*minute))+clock_center_x+1;
display.drawLine(clock_center_x,clock_center_y,x,y,SSD1306_WHITE);
display.drawLine(clock_center_x+1,clock_center_y+1,x1,y1,SSD1306_WHITE);
}
void draw_minute(int minute){
y= (24*cos(pi-(2*pi)/60*minute))+clock_center_y;
x =(24*sin(pi-(2*pi)/60*minute))+clock_center_x;
display.drawLine(clock_center_x,clock_center_y,x,y,SSD1306_WHITE);
}
void draw_clock_face(void){
display.clearDisplay();
display.drawCircle(clock_center_x, clock_center_y,3, SSD1306_WHITE);
display.fillCircle(clock_center_x, clock_center_y,3, SSD1306_WHITE);
for (int i=0;i<12;i++){
y= (32*cos(pi-(2*pi)/12*i))+clock_center_y;
x =(32*sin(pi-(2*pi)/12*i))+clock_center_x;
y1= (28*cos(pi-(2*pi)/12*i))+clock_center_y;
x1 =(28*sin(pi-(2*pi)/12*i))+clock_center_x;
display.drawLine(x1,y1,x,y,SSD1306_WHITE);
}
display.drawCircle(26*sin(pi)+clock_center_x, (26*cos(pi))+clock_center_y, 6, SSD1306_BLACK);
display.fillCircle(26*sin(pi)+clock_center_x, (26*cos(pi))+clock_center_y, 5, SSD1306_BLACK);
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(clock_center_x-3,0);
display.println(F("12"));
}
void loop(){
if (timer < 3000 && timer > 0){
startMillis = millis();
srt = !srt;
timer = 0;
} else if (timer > 3000){
mode++;
display.clearDisplay();
timer = 0;
}
switch (mode){
case(1):
clock();
break;
case(2):
stopWatch();
break;
default:
mode = 1;
break;
}
}
void stopWatch(){
if(srt == true){
currentMillis = millis();
elapsedMillis = (currentMillis - startMillis);
allSeconds = elapsedMillis/1000;
runHours= allSeconds/3600;
secsRemaining=allSeconds%3600;
runMinutes=secsRemaining/60;
runSeconds=secsRemaining%60;
display.clearDisplay();
}
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
char buffer [16];
sprintf (buffer, "%02d:%02d", runMinutes, runSeconds);
display.setCursor(35,25);
display.print(buffer);
display.display();
}
void clock(){
DateTime now = rtc.now();
int thisSec, thisMin, thisHour;
thisSec = now.second();
thisMin = now.minute();
thisHour = now.hour();
draw_second(seconds);
draw_minute(minutes);
draw_hour(hours,minutes);
draw_second(seconds);
draw_minute(minutes);
draw_hour(hours,minutes);
display.display();
seconds=thisSec;
minutes=thisMin;
hours=thisHour;
draw_clock_face();
char buffer [16];
sprintf (buffer, "%02d:%02d:%02d", thisHour, thisMin, thisSec);
display.setTextSize(0.5);
display.setCursor(1,50);
display.print(buffer);
}