#include <Adafruit_NeoPixel.h>
#include <TimeLib.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define PIN 6
#define NUM_LEDS 60
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SSD1306_I2C_ADDRESS 0x3C
#define BTN_ADD_PIN 2
#define BTN_SUB_PIN 3
#define BTN_ENTER_PIN 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
unsigned long previousMillis = 0;
const long interval = 1000;
int settingState = 0;
int settingValue = 0;
int maxSettingValue[] = {23, 59, 59};
unsigned long lastButtonPressMillis = 0;
const unsigned long debounceDelay = 200;
void setup() {
Serial.begin(9600);
strip.begin();
strip.show();
setTime(12, 0, 0, 1, 1, 2022); // Initial time setup
if (!display.begin(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;) ;
}
display.clearDisplay();
pinMode(BTN_ADD_PIN, INPUT_PULLUP);
pinMode(BTN_SUB_PIN, INPUT_PULLUP);
pinMode(BTN_ENTER_PIN, INPUT_PULLUP);
}
void setAllColor(uint32_t color) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, color);
}
strip.show();
}
void updateClock() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
int seconds = second();
int minutes = minute();
int hours = hour();
int secondsLED = map(seconds, 0, 59, 0, NUM_LEDS - 1);
int minutesLED = map(minutes, 0, 59, 0, NUM_LEDS - 1);
int hoursLED = map(hours % 12, 0, 11, 0, NUM_LEDS - 1);
setAllColor(strip.Color(0, 0, 0));
strip.setPixelColor(secondsLED, strip.Color(0, 0, 255));
strip.setPixelColor(minutesLED, strip.Color(0, 255, 0));
strip.setPixelColor(hoursLED, strip.Color(255, 0, 0));
strip.show();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
if (settingState == 0) {
display.print("Time: ");
display.print(hours);
display.print(":");
if (minutes < 10) display.print("0");
display.print(minutes);
display.print(":");
if (seconds < 10) display.print("0");
display.print(seconds);
} else {
display.print("Set: ");
switch (settingState) {
case 1:
display.print("Hours ");
break;
case 2:
display.print("Minutes ");
break;
case 3:
display.print("Seconds ");
break;
}
display.print(settingValue);
}
display.display();
}
}
void handleButtons() {
unsigned long currentMillis = millis();
if (currentMillis - lastButtonPressMillis >= debounceDelay) {
if (digitalRead(BTN_ADD_PIN) == LOW) {
if (settingState == 0) {
settingState = 1; // Enter setting hours mode
settingValue = hour();
} else {
settingValue = (settingValue + 1) % (maxSettingValue[settingState - 1] + 1);
}
lastButtonPressMillis = currentMillis;
}
if (digitalRead(BTN_SUB_PIN) == LOW) {
if (settingState == 0) {
settingState = 1; // Enter setting hours mode
settingValue = hour();
} else {
settingValue = (settingValue - 1 + maxSettingValue[settingState - 1] + 1) % (maxSettingValue[settingState - 1] + 1);
}
lastButtonPressMillis = currentMillis;
}
if (digitalRead(BTN_ENTER_PIN) == LOW) {
if (settingState == 0) {
settingState = 1; // Enter setting hours mode
settingValue = hour();
} else if (settingState == 3) {
// Set the time when finishing the setting sequence
setTime(settingValue, minute(), second(), day(), month(), year());
settingState = 0; // Exit setting mode
} else {
// Increment the setting state and update the setting value
settingState++;
settingValue = (settingState == 1) ? hour() : (settingState == 2) ? minute() : second();
}
lastButtonPressMillis = currentMillis;
}
}
}
void loop() {
updateClock();
handleButtons();
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
ring1:GND
ring1:VCC
ring1:DIN
ring1:DOUT
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
oled1:GND
oled1:VCC
oled1:SCL
oled1:SDA