Arduino Analog Clock
ichibot#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define RTC_SDA A4
#define RTC_SCL A5
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
RTC_DS3231 rtc;
void setup() {
Serial.begin(9600);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 -> change to 0x3C
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display.display();
delay(2000);
display.clearDisplay();
// Set the date and time manually (Adjust as needed)
setDateTime(2024, 2, 29, 5, 50, 0);
}
void drawClockHand(int value, int angle, int length, uint16_t color, int handSize, int handThickness) {
// Convert angle to radians
float radian = angle * PI / 180.0;
// Calculate the endpoint coordinates
int x = SCREEN_WIDTH / 2 + length * cos(radian);
int y = SCREEN_HEIGHT / 2 + length * sin(radian);
// Draw the filled circle or line with specified thickness
if (handSize > 0) {
display.fillCircle(x, y, handSize, color);
} else {
display.drawLine(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, x, y, color);
if (handThickness > 1) {
// Draw additional lines to increase thickness
for (int i = 1; i < handThickness; i++) {
display.drawLine(SCREEN_WIDTH / 2 + i, SCREEN_HEIGHT / 2, x + i, y, color);
}
}
}
}
void loop() {
DateTime now = rtc.now();
int hour = now.hour();
int minute = now.minute();
int second = now.second();
// Clear the previous content
display.clearDisplay();
// Draw clock face
display.drawCircle(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / 2, SSD1306_WHITE);
// Draw clock numbers
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(SCREEN_WIDTH / 2 - 5, SCREEN_HEIGHT / 2 - 29); // Position 12
display.print("12");
display.setCursor(SCREEN_WIDTH / 2 + 25, SCREEN_HEIGHT / 2 - 3); // Position 3
display.print("3");
display.setCursor(SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT / 2 + 25); // Position 6
display.print("6");
display.setCursor(SCREEN_WIDTH / 2 - 30, SCREEN_HEIGHT / 2 - 3); // Position 9
display.print("9");
// Draw clock hands with longer lengths
drawClockHand(hour % 12, ((hour % 12) * 30.0) + (minute / 60.0) * 30.0, 15, SSD1306_WHITE, 0, 0); // Hour hand
// Correct the calculation for drawing the minute hand
drawClockHand(minute, (minute * 6.0) + (second / 60.0) * 6.0, 20, SSD1306_WHITE, 0, 0); // Minute hand
// Draw a small circle to indicate the second hand (without overlapping numbers)
int secondHandAngle = second / 60.0 * 360 - 90;
int secondHandLength = 20; // Length of the second hand
int secondHandSize = 3; // Size of the circle representing the second hand
drawClockHand(second, secondHandAngle, secondHandLength, SSD1306_WHITE, secondHandSize, 0);
display.display();
delay(1000);
}
void setDateTime(int year, int month, int day, int hour, int minute, int second) {
DateTime newDateTime(year, month, day, hour, minute, second);
rtc.adjust(newDateTime);
}