#include <WiFi.h>
#include <NTPClient.h>
#include <TimeLib.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 = 0;
const int secondIndicatorPin = 15; // Пін для індикатора секунд
const int alarmPin = 17; // Пін для бізеру сигналу будильника
const int switchPin = 2; // Пін для перемикача
const int alarmSwitchPin = 25; // Пін для окремого перемикача
const int changeHourPin = 12; // Пін для зміни годин будильника
const int changeMinutePin = 13; // Пін для зміни хвилин будильника
const byte digit[10] =
{
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111 // 9
};
uint32_t myTimer1 = 0;
uint32_t myTimer2 = 0;
uint32_t myTimer3 = 0;
uint32_t myTimer4 = 0;
int digitBuffer[4] = {0};
int digitScan = 0;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
int alarmHour = 8; // Година будильника
int alarmMinute = 0; // Хвилина будильника
bool alarmActive = false;
bool showAlarmTime = false;
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 && (millis() - myTimer1 >= 1000))
{
//delay(1000);
Serial.println("Connecting...");
attempts++;
}
if (WiFi.status() == WL_CONNECTED && (millis() - myTimer2 >= 1000))
{
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 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); // Додаємо пін для бізеру сигналу будильника
pinMode(switchPin, INPUT_PULLUP); // Додаємо пін для перемикача з підтяжкою
pinMode(changeHourPin, INPUT_PULLUP); // Додаємо пін для зміни годин будильника
pinMode(changeMinutePin, INPUT_PULLUP); // Додаємо пін для зміни хвилин будильника
pinMode(alarmSwitchPin, INPUT_PULLUP);
}
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 checkAlarm()
{
if (alarmActive && timeClient.getHours() == alarmHour && timeClient.getMinutes() == alarmMinute)
{
// Включити бізер сигналу будильника
digitalWrite(alarmPin, HIGH);
}
else
{
// Вимкнути бізер сигналу будильника
digitalWrite(alarmPin, LOW);
}
}
void updateSwitchState()
{
// Читання стану основного перемикача
int mainSwitchState = digitalRead(switchPin);
// Встановлення значення alarmActive в залежності від стану основного перемикача
alarmActive = (mainSwitchState == LOW);
// Читання стану перемикача на піні 25
int alarmSwitchState = digitalRead(alarmSwitchPin);
// Встановлення значення showAlarmTime в залежності від стану перемикача на піні 25
showAlarmTime = (alarmSwitchState == LOW);
}
void updateAlarmTime()
{
if (digitalRead(changeHourPin) == LOW && (millis() - myTimer3 >= 200))
{
// Збільшуємо годину будильника, якщо натиснута кнопка для зміни годин
alarmHour = (alarmHour + 1) % 24;
myTimer1 = millis(); // Оновлюємо таймер
Serial.print("New Alarm Hour: ");
Serial.println(alarmHour);
}
if (digitalRead(changeMinutePin) == LOW && (millis() - myTimer4 >= 200))
{
// Збільшуємо хвилини будильника, якщо натиснута кнопка для зміни хвилин
alarmMinute = (alarmMinute + 1) % 60;
myTimer2 = millis(); // Оновлюємо таймер
Serial.print("New Alarm Minute: ");
Serial.println(alarmMinute);
}
}
void loop()
{
timeClient.update();
int hours = timeClient.getHours();
int minutes = timeClient.getMinutes();
int seconds = timeClient.getSeconds();
// Виводимо секунди на індикатор секунд
digitalWrite(secondIndicatorPin, seconds % 2 == 0 ? HIGH : LOW);
if (showAlarmTime) {
hours = alarmHour;
minutes = alarmMinute;
delay(50);
}
digitBuffer[3] = hours / 10;
digitBuffer[2] = hours % 10;
digitBuffer[1] = minutes / 10;
digitBuffer[0] = minutes % 10;
updateDisp();
updateSwitchState(); // Оновлення стану перемикача
updateAlarmTime(); // Оновлення годин та хвилин будильника
checkAlarm();
delay(5);
}