#include <WiFi.h>
#include <NTPClient.h>
#include <TimeLib.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
const char *ssidOptions[] = {"Wokwi-GUEST", "Meteor.flash", "meteor", "Pixel"}; //Parkovy
const char *passwordOptions[] = {"", "y0internet", "88888888", "88888888"};
const int numNetworks = sizeof(ssidOptions) / sizeof(ssidOptions[0]);
int _code;
TaskHandle_t _Task1Time;
const int digitPins[4] = {32, 35, 33, 34};
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; // Пін для зміни хвилин будильника
int digitBuffer[4] = {0};
int digitScan = 0;
bool alarmActive = false; // alarmA
bool showAlarmTime = false; // alarmA
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
Adafruit_SSD1306 display(128, 32, &Wire, -1);
const char *city = "Kyiv"; // City name
const char *api = "5596959aff336512de73ae27065cad69"; // OpenWeatherMap API key
const byte digit[10] = {
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111 // 9
};
// Array bytes of the Weather icons
const unsigned char from200to202 [] PROGMEM = {
// '200-202', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x8f, 0xa0, 0x00, 0x07, 0xe7, 0xe0,
0x00, 0x0f, 0xf7, 0xc0, 0x00, 0x0f, 0xfb, 0xf0, 0x00, 0x0f, 0xfb, 0xc0, 0x00, 0x7f, 0xf8, 0xe0,
0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x80, 0x01, 0xe0, 0xff, 0x80, 0x00, 0xee, 0xff, 0xc0,
0x00, 0xfc, 0xff, 0xc0, 0x00, 0xdd, 0xff, 0x80, 0x00, 0x5c, 0x7f, 0x00, 0x00, 0x1f, 0x7e, 0x00,
0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0xd8, 0x00, 0x00, 0x08, 0x98, 0x00, 0x00, 0x00, 0x90, 0x00,
0x00, 0x10, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from230to233 [] PROGMEM = {
// '230-233', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x09, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x7f, 0xe0, 0x00,
0x00, 0x7f, 0xc0, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xfe, 0x00,
0x07, 0xfe, 0x0e, 0x00, 0x07, 0xfe, 0xee, 0x00, 0x07, 0x80, 0xde, 0x00, 0x03, 0xb8, 0xc6, 0x00,
0x03, 0x39, 0xf4, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 0x70, 0xc0, 0x00, 0x00, 0x7c, 0x80, 0x00,
0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from300to302 [] PROGMEM = {
// '300-302', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x0f, 0xf8, 0x00,
0x00, 0x1f, 0xf8, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x80,
0x01, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0,
0x00, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x84, 0x00, 0x00, 0x10, 0x84, 0x00, 0x00, 0x04, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from500to520 [] PROGMEM = {
// '500,501,511,520', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0xf8, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x07, 0xfe, 0x00,
0x00, 0x1f, 0xfe, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xe0,
0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xe0,
0x00, 0x7f, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x62, 0x00,
0x00, 0x0c, 0x46, 0x00, 0x00, 0x0c, 0xcc, 0x00, 0x00, 0x18, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from502to502 [] PROGMEM = {
// '502', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x80, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x3f, 0xf0, 0x00,
0x00, 0x73, 0xf0, 0x00, 0x01, 0xf3, 0xf0, 0x00, 0x03, 0xef, 0xfc, 0x00, 0x07, 0xf0, 0x00, 0x00,
0x07, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x0f, 0xfe, 0x00, 0x00, 0x07, 0xfe, 0x7f, 0x80,
0x07, 0xfe, 0x3f, 0x00, 0x03, 0xff, 0x3f, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x31, 0x10, 0x00, 0x00, 0x23, 0x10, 0x00, 0x00, 0x22, 0x30, 0x00, 0x00, 0x62, 0x30, 0x00,
0x00, 0x42, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from521to521 [] PROGMEM = {
// '521', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x01, 0xf3, 0xd0,
0x00, 0x03, 0xf9, 0xe0, 0x00, 0x07, 0xfc, 0xf0, 0x00, 0x07, 0xfc, 0xe0, 0x00, 0x1f, 0xfc, 0x70,
0x00, 0x3f, 0xff, 0x80, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xe0,
0x00, 0x7f, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x28, 0x00, 0x00, 0x09, 0x48, 0x00, 0x00, 0x08, 0x4a, 0x00,
0x00, 0x0a, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from600to621 [] PROGMEM = {
// '600,610,621', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x03, 0x1f, 0x40, 0x00, 0x0f, 0xdf, 0xc0,
0x00, 0x1f, 0xef, 0x80, 0x00, 0x3f, 0xef, 0xe0, 0x00, 0x3f, 0xf7, 0x80, 0x00, 0xff, 0xf3, 0xc0,
0x01, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0x00,
0x03, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xfc, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x30, 0x00,
0x00, 0x11, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from601to622 [] PROGMEM = {
// '601,602,622', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00,
0x00, 0x07, 0xf8, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x1f, 0xfc, 0x00,
0x00, 0x7f, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xe0,
0x01, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xc0,
0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcc, 0x00, 0x00, 0x0c, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from611to612 [] PROGMEM = {
// '611,612', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0f, 0xc0, 0x00,
0x00, 0x1f, 0xe0, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0xff, 0xfc, 0x00,
0x00, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x8f, 0xfe, 0x00,
0x00, 0xaf, 0xfe, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xf0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from623to623 [] PROGMEM = {
// '623', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x0f, 0xf8, 0x00,
0x00, 0x0f, 0xfc, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x80,
0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xe0,
0x01, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x1f, 0xfe, 0x00,
0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcc, 0x00,
0x00, 0x08, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from700to751 [] PROGMEM = {
// '700-751', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x0f, 0x3e, 0x80,
0x00, 0x1f, 0xbf, 0x00, 0x00, 0x3f, 0xdf, 0x00, 0x00, 0x7f, 0xdf, 0xc0, 0x00, 0x7f, 0xef, 0x00,
0x01, 0xff, 0xe3, 0x80, 0x03, 0xff, 0xfc, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xfe, 0x00,
0x07, 0xff, 0xfe, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x07, 0x7f, 0xf6, 0x00, 0x00, 0x00, 0x0c, 0x00,
0x03, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from800 [] PROGMEM = {
// '800', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x0f, 0xf8, 0x00,
0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x80,
0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0,
0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xc0,
0x00, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0x80, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x3f, 0xfe, 0x00,
0x00, 0x1f, 0xfc, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from801to802 [] PROGMEM = {
// '801,802', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00,
0x00, 0x3d, 0xf8, 0x00, 0x00, 0xfb, 0xfe, 0x00, 0x00, 0x77, 0xff, 0x00, 0x00, 0x2f, 0xff, 0x80,
0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xfc,
0x03, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xfc,
0x01, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from803to803 [] PROGMEM = {
// '803', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x3f, 0x3c, 0x00,
0x00, 0xff, 0x9e, 0x00, 0x01, 0xff, 0xcf, 0x00, 0x03, 0xff, 0xe3, 0x80, 0x03, 0xff, 0xf8, 0x00,
0x1f, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xc0, 0x7f, 0xff, 0xff, 0x60, 0x7f, 0xff, 0xff, 0x60,
0xff, 0xff, 0xff, 0xbc, 0xff, 0xff, 0xff, 0x7e, 0x7f, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xfe, 0x7f,
0x3f, 0xff, 0xfc, 0xff, 0x00, 0x00, 0x03, 0xff, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xff,
0x00, 0x3f, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from900to900 [] PROGMEM = {
// '900', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0xf8, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x07, 0xfe, 0x00,
0x00, 0x1f, 0xfe, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xe0,
0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xff, 0xe0,
0x00, 0x7f, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x62, 0x00,
0x00, 0x0c, 0x46, 0x00, 0x00, 0x0c, 0xcc, 0x00, 0x00, 0x18, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char from804to804 [] PROGMEM = {
// '804', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xf8, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0x00,
0x00, 0x3f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xe0, 0x00, 0xe7, 0x3f, 0xf0, 0x00, 0xdf, 0xdf, 0xf0,
0x00, 0xbf, 0xef, 0xf0, 0x00, 0x7f, 0xf7, 0xf0, 0x00, 0x7f, 0xfd, 0xf0, 0x03, 0xff, 0xff, 0xc0,
0x07, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x00,
0x0f, 0xff, 0xff, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Функція для оновлення відображення на 7-сегментному індикаторі
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;
}
// Функція для виведення тексту на центр екрану OLED дисплея
void displayCenteredText(String text) {
int16_t x, y;
uint16_t textWidth, textHeight;
display.setTextSize(1);
display.getTextBounds(text, 0, 0, &x, &y, &textWidth, &textHeight);
int16_t xCentered = (128 - textWidth) / 2;
int16_t yCentered = (32 - textHeight) / 2 + textHeight;
display.setCursor(xCentered, yCentered);
display.println(text);
}
// Функція для підключення до Wi-Fi мережі
void connectWiFi()
{
int n = sizeof(ssidOptions) / sizeof(ssidOptions[0]);
for (int i = 0; i < n; i++) {
String loginWifiDislpay = "Start Connecting to\nWiFi: " + String(ssidOptions[i]);
display.setRotation(0);
display.setCursor(0, 0);
DisplayLog(loginWifiDislpay);
delay(1000);
WiFi.begin(ssidOptions[i], passwordOptions[i]);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
loginWifiDislpay = "Connection Failed!:\n" + String(ssidOptions[i]);
display.setCursor(0, 0);
DisplayLog(loginWifiDislpay);
delay(1000);
continue;
}
break;
}
}
// Функція для отримання погоди за допомогою OpenWeatherMap API
String getWeather() {
if ((WiFi.status() == WL_CONNECTED)) {
HTTPClient http;
String url = "http://api.openweathermap.org/data/2.5/weather?q=" + String(city) + "&appid=" + String(api) + "&units=metric";
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
String payload = http.getString();
http.end();
return parseWeather(payload);
} else {
Serial.println("Error on HTTP request");
return "HTTP error";
}
} else {
Serial.println("WiFi not connected");
return "WiFi error";
}
}
// Функція для обробки відповіді API OpenWeatherMap і витягування необхідних даних
String parseWeather(String json) {
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, json);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return "JSON error";
}
_code = doc["weather"][0]["id"].as<int>();
String city = doc["name"].as<String>();
String description = doc["weather"][0]["description"].as<String>();
int humidity = doc["main"]["humidity"].as<int>();
int pressure = doc["main"]["pressure"].as<int>();
float wind = doc["wind"]["speed"].as<float>();
char windBuf[8];
String windStr = dtostrf(wind, 0, 1, windBuf);
float temp = round(doc["main"]["temp"].as<float>());
char buf[8];
String tempStr;
if (temp >= 0) {
tempStr = dtostrf(temp, 0, 0, buf);
} else {
tempStr = dtostrf(temp, 0, 0, buf + 1);
}
display.cp437(true); // Use correct CP437 character codes
String result = "t:" + tempStr + F("\n\n") +
String(humidity) + (char)(0xF8) +
F("\n\n") + String(pressure) + F(" hPa\n\n") + windStr + F("\nm/s");
return result;
}
void setup() {
Serial.begin(115200);
delay(5);
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);
Wire.begin(21, 22);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C, 1);
display.setTextColor(WHITE);
delay(1000);
connectWiFi();
display.setRotation(1);
display.setCursor(0, 0);
DisplayLog("WiFi connected!");
delay(1000);
xTaskCreatePinnedToCore(
Task1Time, /* Task function. */
"Task1Time", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&_Task1Time, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
}
//Task1code: blinks an LED every 1000 ms
void Task1Time( void * pvParameters )
{
timeClient.begin();
timeClient.setTimeOffset(2 * 3600);
while(true)
{
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);
delay(6);
}
}
void loop() {
display.clearDisplay();
display.setCursor(0, 0);
String weather = getWeather();
if (weather == "HTTP error" || weather == "WiFi error")
{
CheckWiFi();
}
displaywidget(_code);
display.setCursor(0, 33);
display.println(weather);
display.display();
delay(5000);
}
void CheckWiFi()
{
connectWiFi();
display.setRotation(1);
}
void displaywidget(int code_no)
{
display.clearDisplay();
display.setCursor(0, 0);
if (200 <= code_no and code_no <= 202)
display.drawBitmap(0, 0, from200to202, 32, 31, WHITE , BLACK);
else if (230 <= code_no and code_no <= 233)
display.drawBitmap(0, 0, from230to233, 32, 31, WHITE , BLACK);
else if (300 <= code_no and code_no <= 302)
display.drawBitmap(0, 0, from300to302, 32, 31, WHITE , BLACK);
else if (code_no == 500 or code_no == 501 or code_no == 511 or code_no == 520)
display.drawBitmap(0, 0, from500to520, 32, 31, WHITE , BLACK);
else if (code_no == 502)
display.drawBitmap(0, 0, from502to502, 32, 31, WHITE , BLACK);
else if (code_no == 502)
display.drawBitmap(0, 0, from521to521, 32, 31, WHITE , BLACK);
else if (code_no == 600 or code_no == 610 or code_no == 621)
display.drawBitmap(0, 0, from600to621, 32, 31, WHITE , BLACK);
else if (code_no == 601 or code_no == 602 or code_no == 622)
display.drawBitmap(0, 0, from601to622, 32, 31, WHITE , BLACK);
else if (code_no == 611 or code_no == 612)
display.drawBitmap(0, 0, from611to612, 32, 31, WHITE , BLACK);
else if (code_no == 623)
display.drawBitmap(0, 0, from623to623, 32, 31, WHITE , BLACK);
else if (700 <= code_no and code_no <= 751)
display.drawBitmap(0, 0, from700to751, 32, 31, WHITE , BLACK);
else if (code_no == 800)
display.drawBitmap(0, 0, from800, 32, 31, WHITE , BLACK);
else if (code_no == 801 or code_no == 802)
display.drawBitmap(0, 0, from801to802, 32, 31, WHITE , BLACK);
else if (code_no == 803)
display.drawBitmap(0, 0, from803to803, 32, 31, WHITE , BLACK);
else if (code_no == 900)
display.drawBitmap(0, 0, from900to900, 32, 31, WHITE , BLACK);
else if (code_no == 804)
display.drawBitmap(0, 0, from804to804, 32, 31, WHITE , BLACK);
// else
// display.drawBitmap(0, 0, sunny, 32, 31, BLACK, WHITE);
}
void DisplayLog(String obj)
{
display.clearDisplay();
display.println(obj);
display.display();
}