#include <WiFi.h>
#include <NTPClient.h>
#include <TimeLib.h>
#include <TaskScheduler.h>
const char *ssidOptions[] = {"Wokwi-GUEST", "Meteor.flash", "meteor", "Pixel"};
const char *passwordOptions[] = {"", "y0internet", "88888888", "88888888"};
const int numNetworks = sizeof(ssidOptions) / sizeof(ssidOptions[0]);
const int digitPins[4] = {4, 19, 21, 22};
const int clockPin = 18;
const int latchPin = 5;
const int dataPin = 23;
const int secondIndicatorPin = 15;
const int alarmPin = 17;
const byte digit[10] = {
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111 // 9
};
int digitBuffer[4] = {0};
int digitScan = 0;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
bool alarmEnabled = false;
unsigned long alarmStartTime = 0;
Scheduler scheduler;
void connectToWiFi() {
Serial.println("Connecting to WiFi...");
for (int i = 0; i < numNetworks; ++i) {
WiFi.begin(ssidOptions[i], passwordOptions[i]);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(1000);
Serial.println("Connecting...");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("Connected to WiFi");
return;
} else {
Serial.println("Connection failed. Retrying...");
WiFi.disconnect();
delay(1000);
}
}
Serial.println("Failed to connect to any WiFi network");
}
void updateDisp() {
for (byte j = 0; j < 4; j++)
digitalWrite(digitPins[j], LOW);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B11111111);
digitalWrite(latchPin, HIGH);
delayMicroseconds(5);
digitalWrite(digitPins[digitScan], HIGH);
digitalWrite(latchPin, LOW);
if (digitScan == 0)
shiftOut(dataPin, clockPin, MSBFIRST, ~(digit[digitBuffer[digitScan]] | B10000000));
else
shiftOut(dataPin, clockPin, MSBFIRST, ~digit[digitBuffer[digitScan]]);
digitalWrite(latchPin, HIGH);
digitScan++;
if (digitScan > 3) digitScan = 0;
}
void handleAlarm() {
unsigned long currentTime = millis();
unsigned long elapsedTime = currentTime - alarmStartTime;
if (elapsedTime < 120000) { // 2 minutes
digitalWrite(alarmPin, HIGH);
} else if (elapsedTime < 240000) { // 2 minutes break
digitalWrite(alarmPin, LOW);
} else {
alarmStartTime = currentTime;
}
}
void setAlarmTime() {
Serial.println("Enter alarm time (HH:MM): ");
while (Serial.available() < 5)
;
String input = Serial.readStringUntil('\n');
int hours = input.substring(0, 2).toInt();
int minutes = input.substring(3, 5).toInt();
alarmStartTime = hours * 3600000 + minutes * 60000;
Serial.println("Alarm set for " + input);
}
void updateTime() {
timeClient.update();
int hours = timeClient.getHours();
int minutes = timeClient.getMinutes();
int seconds = timeClient.getSeconds();
digitBuffer[3] = hours / 10;
digitBuffer[2] = hours % 10;
digitBuffer[1] = minutes / 10;
digitBuffer[0] = minutes % 10;
updateDisp();
digitalWrite(secondIndicatorPin, seconds % 2 == 0 ? HIGH : LOW);
}
void setup() {
Serial.begin(115200);
delay(5);
connectToWiFi();
timeClient.begin();
timeClient.setTimeOffset(2 * 3600);
for (int i = 0; i < 4; i++) {
pinMode(digitPins[i], OUTPUT);
}
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(secondIndicatorPin, OUTPUT);
pinMode(alarmPin, OUTPUT);
digitalWrite(alarmPin, LOW);
scheduler.init();
Task updateTask(1000, TASK_FOREVER, &updateTime);
Task alarmTask(1000, TASK_FOREVER, &handleAlarm);
Task dispTask(5, TASK_FOREVER, &updateDisp);
Task setAlarmTask(100, TASK_FOREVER, &setAlarmTime);
scheduler.addTask(updateTask);
scheduler.addTask(alarmTask);
scheduler.addTask(dispTask);
scheduler.addTask(setAlarmTask);
updateTask.enable();
alarmTask.enable();
dispTask.enable();
setAlarmTask.enable();
}
void loop() {
scheduler.execute();
}