#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
RTC_DS1307 rtc;
#define SCREEN_WIDTH 128 //--> OLED display width, in pixels
#define SCREEN_HEIGHT 64 //--> OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
byte _day, _month, _hour24, _hour12, _minute, _second, _dtw;
int _year;
byte hr24;
byte clockCenterX=31;
byte clockCenterY=31;
const unsigned char Clock_Frame [] PROGMEM = {
0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xe0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00,
0x00, 0x00, 0xf0, 0x18, 0x70, 0x1e, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x28, 0x88, 0x07, 0x80, 0x00,
0x00, 0x07, 0x00, 0x08, 0x08, 0x01, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x08, 0x10, 0x00, 0x70, 0x00,
0x00, 0x38, 0x20, 0x08, 0x20, 0x10, 0x38, 0x00, 0x00, 0x70, 0x20, 0x08, 0x40, 0x10, 0x1c, 0x00,
0x00, 0xe0, 0x10, 0x3e, 0xf8, 0x20, 0x0e, 0x00, 0x01, 0xc0, 0x10, 0x00, 0x00, 0x20, 0x07, 0x00,
0x01, 0x80, 0x08, 0x00, 0x00, 0x40, 0x03, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x40, 0x01, 0x80,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38,
0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
0xc7, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0xc6, 0xc8, 0x80, 0x00, 0x07, 0xc0, 0x00, 0x02, 0x26,
0xc8, 0x80, 0x00, 0x0c, 0x60, 0x00, 0x00, 0x26, 0xc7, 0x80, 0x00, 0x0c, 0x60, 0x00, 0x00, 0xc6,
0xc0, 0x80, 0x00, 0x0c, 0x60, 0x00, 0x00, 0x26, 0xc1, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x02, 0x26,
0xce, 0x00, 0x00, 0x03, 0x80, 0x00, 0x01, 0xc6, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x38, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x08, 0x00, 0x00, 0x20, 0x01, 0x80,
0x01, 0x80, 0x08, 0x00, 0x00, 0x20, 0x03, 0x00, 0x01, 0xc0, 0x10, 0x00, 0x00, 0x10, 0x07, 0x00,
0x00, 0xe0, 0x10, 0x03, 0x80, 0x10, 0x0e, 0x00, 0x00, 0x70, 0x20, 0x06, 0x00, 0x08, 0x1c, 0x00,
0x00, 0x38, 0x20, 0x04, 0x00, 0x08, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x07, 0x80, 0x00, 0x70, 0x00,
0x00, 0x07, 0x00, 0x04, 0x40, 0x01, 0xc0, 0x00, 0x00, 0x03, 0xc0, 0x04, 0x40, 0x07, 0x80, 0x00,
0x00, 0x00, 0xf0, 0x03, 0x80, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xe0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x00
};
unsigned long previousMillisGetTimeDate = 0; //--> will store last time was updated
const long intervalGetTimeDate = 1000; //--> interval (milliseconds
void setup() {
Serial.begin(9600);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //-> If that doesn't work, use this line of code outside of "if (! rtc.isrunning())"
}
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); //--> Don't proceed, loop forever
}
delay(1000);
}
void loop() {
unsigned long currentMillisGetTimeDate = millis();
if (currentMillisGetTimeDate - previousMillisGetTimeDate >= intervalGetTimeDate) {
previousMillisGetTimeDate = currentMillisGetTimeDate;
GetDateTime();
display.clearDisplay();
Draw_Clock_Frame();
Analog_Clock(_hour12,_minute,_second);
display.display();
}
}
void GetDateTime(){
DateTime now = rtc.now();
_day=now.day();
_month=now.month();
_year=now.year();
_hour24=now.hour();
_minute=now.minute();
_second=now.second();
_dtw=now.dayOfTheWeek();
hr24=_hour24;
if (hr24>12) {
_hour12=hr24-12;
}
else if (hr24==0) {
_hour12=12;
}
else {
_hour12=hr24;
}
}
void Analog_Clock(byte h, byte m, byte s) {
Draw_Line_Seconds(s);
Draw_Line_Minutes(m);
Draw_Line_Hours(h,m);
for (byte i = 30; i < 33; i++) {
display.drawPixel(i, 30, SSD1306_BLACK);
display.drawPixel(i, 31, SSD1306_BLACK);
display.drawPixel(i, 32, SSD1306_BLACK);
}
}
void Draw_Line_Seconds(int s) {
float angle = s * 6 ;
angle = (angle / 57.29577951); //--> Convert degrees to radians
// 16 is the length of the "second line" on the Analog Clock
int xS = (clockCenterX + (sin(angle) * (16)));
int yS = (clockCenterY - (cos(angle) * (16)));
//----------------------------------------Special condition at the 15th second, because at that second the line is not symmetrical
if (s == 15) {
display.drawLine(clockCenterX, clockCenterY, xS, yS + 1, WHITE);
} else {
display.drawLine(clockCenterX, clockCenterY, xS, yS, WHITE);
}
}
//________________________________________________________________________Subroutine for drawing Minutes on an Analog Clock
void Draw_Line_Minutes(int m) {
float angle = m * 6 ;
angle = (angle / 57.29577951) ; //Convert degrees to radians
// 17 is the length of the "minute line" on the Analog Clock
int xM = (clockCenterX + (sin(angle) * (17)));
int yM = (clockCenterY - (cos(angle) * (17)));
//----------------------------------------Special condition at minute 15, because at that minute the line is not symmetrical
if (m == 15) {
display.drawLine(clockCenterX, clockCenterY - 1, xM, yM + 1, WHITE);
display.drawLine(clockCenterX - 1, clockCenterY, xM, yM + 1, WHITE);
display.drawLine(clockCenterX, clockCenterY, xM, yM + 1, WHITE);
display.drawLine(clockCenterX + 1, clockCenterY, xM, yM + 1, WHITE);
display.drawLine(clockCenterX, clockCenterY + 1, xM, yM + 1, WHITE);
} else {
display.drawLine(clockCenterX, clockCenterY - 1, xM, yM, WHITE);
display.drawLine(clockCenterX - 1, clockCenterY, xM, yM, WHITE);
display.drawLine(clockCenterX, clockCenterY, xM, yM, WHITE);
display.drawLine(clockCenterX + 1, clockCenterY, xM, yM, WHITE);
display.drawLine(clockCenterX, clockCenterY + 1, xM, yM, WHITE);
}
}
//________________________________________________________________________Subroutine for drawing Hour on an Analog Clock
void Draw_Line_Hours(int h, int m) {
float angle = h * 30 + int((m / 12) * 6);
angle = (angle / 57.29577951) ; //Convert degrees to radians
// 12 is the length of the "hour line" on the Analog Clock
int xH = (clockCenterX + (sin(angle) * (12)));
int yH = (clockCenterY - (cos(angle) * (12)));
//----------------------------------------Special condition at 12 o'clock, because at that hour the line is not symmetrical
if (h == 12 && m < 12) {
display.drawLine(clockCenterX, clockCenterY - 2, xH + 1, yH, WHITE);
display.drawLine(clockCenterX - 2, clockCenterY, xH + 1, yH, WHITE);
display.drawLine(clockCenterX, clockCenterY - 1, xH + 1, yH, WHITE);
display.drawLine(clockCenterX - 1, clockCenterY, xH + 1, yH, WHITE);
display.drawLine(clockCenterX, clockCenterY, xH + 1, yH, WHITE);
display.drawLine(clockCenterX + 1 ,clockCenterY, xH + 1, yH, WHITE);
display.drawLine(clockCenterX, clockCenterY + 1, xH + 1, yH, WHITE);
display.drawLine(clockCenterX + 2, clockCenterY, xH + 1, yH ,WHITE);
display.drawLine(clockCenterX, clockCenterY + 2, xH + 1, yH, WHITE);
} else {
display.drawLine(clockCenterX, clockCenterY - 2, xH, yH, WHITE);
display.drawLine(clockCenterX - 2, clockCenterY, xH, yH, WHITE);
display.drawLine(clockCenterX, clockCenterY - 1, xH, yH, WHITE);
display.drawLine(clockCenterX - 1, clockCenterY, xH, yH, WHITE);
display.drawLine(clockCenterX, clockCenterY, xH, yH, WHITE);
display.drawLine(clockCenterX + 1 ,clockCenterY, xH, yH, WHITE);
display.drawLine(clockCenterX, clockCenterY + 1, xH, yH, WHITE);
display.drawLine(clockCenterX + 2, clockCenterY, xH, yH ,WHITE);
display.drawLine(clockCenterX, clockCenterY + 2, xH, yH, WHITE);
}
}
//________________________________________________________________________Subroutine for drawing frames on an analog clock
void Draw_Clock_Frame() {
display.drawBitmap(0, 0, Clock_Frame, 63, 63, WHITE); //--> display.drawBitmap(x position, y position, bitmap data, bitmap width, bitmap height, color)
}