#include #include //*************************Изменить для себя ******************************************************* #define HourNightStart 23 //Время включения ночного режима #define HourNightEnd 6 //Времы выключения ночного режима #define AP_SSID "wlan-name" // Логин к вашему WiFi(кавычки оставить) #define AP_PASS "password" //Пароль у вашему WiFi #define TIMEZONE 3 // Часовой пояс //********************************************************************************** #define Key_Pr 5 // ;Задержка на подавление дребезга короткого нажатия кнопок #define Key_Long 50 // ;Задержка на длительное нажатие (в циклах прерывания) #define SH_CP 16 #define ST_CP 5 #define DS 4 #define LED 14 #define HV 12 static const uint8_t nixie_level[4][10] = { {1, 2, 6, 7, 5, 0, 4, 9, 8, 3}, {6, 7, 5, 0, 4, 9, 8, 3, 1, 2}, {5, 0, 4, 9, 8, 3, 1, 2, 6, 7}, {4, 9, 8, 3, 1, 2, 6, 7, 5, 0} }; char ssid[] = ""; char pass[] = ""; unsigned int localPort = 2390; // local port to listen for UDP packets unsigned long ntp_time = 0; long t_correct = 0; unsigned long cur_ms = 0; unsigned long ms1 = 0; unsigned long ms2 = 10000000UL; unsigned long ms3 = 0; unsigned long t_cur = 0; bool points = true; unsigned int err_count = 0; uint16_t my_s = 0; uint16_t my_m = 0; uint16_t my_h = 0; uint8_t Btt0 = 0; uint8_t Btt1 = 0; uint8_t Btt2 = 0; uint8_t Btt3 = 0; uint8_t Btt4 = 0; uint8_t Btt5 = 0; uint8_t temp = 0; uint8_t lastMinute = 0; uint16_t ADCkey = 0; uint8_t Key_Timer; uint8_t Key_1_Count; uint8_t Key_2_Count; uint8_t Key_3_Count; boolean Key_1_Pr = false; //Кнопка 1 нажата (с учетом дребезга контактов) boolean Key_2_Pr = false; //Кнопка 2 нажата (с учетом дребезга контактов) boolean Key_3_Pr = false; //Кнопка 3 нажата (с учетом дребезга контактов) boolean Key_1_LP = false; //Кнопка 1 длительное удержание boolean Key_2_LP = false; //Кнопка 2 длительное удержание boolean Key_3_LP = false; //Кнопка 3 длительное удержание boolean Key_1_PrR = false; //Отпускание кнопки 1 после короткого нажатия boolean Key_1_LPR = false; //Отпускание кнопки 1 после длинного нажатия bool LedON = true; //bool LedON_temp = false; bool NtpNoConn = false; unsigned long Next_ms = 3600000; IPAddress timeServerIP; const char* ntpServerName = "time.nist.gov"; const int NTP_PACKET_SIZE = 48; byte packetBuffer[ NTP_PACKET_SIZE]; WiFiUDP udp; void setup() { Serial.begin(115200); Serial.println(""); Serial.println(""); Serial.print("Free Memory: "); // Соединение с WiFi Serial.println(ESP.getFreeHeap()); if ( !ConnectWiFi(AP_SSID, AP_PASS) ) { Serial.println("Reset ESP8266 ..."); ESP.reset(); } delay(1000); // Инициализацият пинов pinMode(SH_CP, OUTPUT); pinMode(ST_CP, OUTPUT); pinMode(DS, OUTPUT); pinMode(LED, OUTPUT); pinMode(HV, OUTPUT); // Инициализауия UDP соединения с NTP сервером Serial.println("Starting UDP"); udp.begin(localPort); Serial.print("Local port: "); Serial.println(udp.localPort()); digitalWrite(HV, HIGH); } void loop() { cur_ms = millis(); t_cur = cur_ms / 1000; // Каждые 24 часа считываем время в интернете if ( cur_ms < ms2 || (cur_ms - ms2) > Next_ms ) { err_count++; // Делаем три попытки синхронизации с интернетом NtpNoConn = false; if ( GetNTP() ) { ms2 = cur_ms; err_count = 0; t_correct = ntp_time - t_cur; NtpNoConn = true; Next_ms = 86400000; } else { Next_ms = 60000; //соединяемся через минуту } } // Каждые секунду меняем точку время if ( cur_ms < ms1 || (cur_ms - ms1) > 1000 ) { ms1 = cur_ms; ntp_time = t_cur + t_correct; points = !points; DisplayTime(); } //опрос кнопок if ( cur_ms < ms3 || (cur_ms - ms3) > 5 ) { ms3 = cur_ms; ADCkey = analogRead(A0); button_press(); set_Mode(); } // Если нет соединения с интернетом, перезагружаемся if ( err_count > 10 ) { Serial.println("NTP connect false"); Serial.println("Reset ESP8266 ..."); ESP.reset(); } delay(100); } /** * Соединение с WiFi */ bool ConnectWiFi(const char *ssid, const char *pass) { // Три попытки соединения по WiFi for ( int i = 0; i < 3; i++) { Serial.print("\nConnecting to: "); Serial.println(ssid); WiFi.begin(ssid, pass); delay(1000); // Максиммум 12 раз проверка соединения for ( int j = 0; j < 12; j++ ) { if (WiFi.status() == WL_CONNECTED) { Serial.print("\nWiFi connect true: "); Serial.print(WiFi.localIP()); Serial.print("/"); Serial.print(WiFi.subnetMask()); Serial.print("/"); Serial.println(WiFi.gatewayIP()); return true; } delay(1000); Serial.print(WiFi.status()); } } Serial.println("\nConnect WiFi failed ..."); return false; } void DisplayTimeRandom(void) { for (int q = 0; q < 10; q++) { Btt0 = 0; Btt1 = 0; Btt2 = 0; Btt3 = 0; Btt4 = 0; Btt5 = 0; temp = nixie_level[3][q]; m2(temp); temp = nixie_level[2][q] ; m1(temp); temp = nixie_level[1][q]; h2(temp); temp = nixie_level[0][q]; h1(temp); if (my_h >= HourNightStart || my_h <= HourNightEnd ) { analogWrite(HV, 200); digitalWrite(LED, LOW); } else { analogWrite(HV, 0); digitalWrite(HV, HIGH); if (LedON) { digitalWrite(LED, HIGH); } } // NtpNoConn=0; if (NtpNoConn == 1) { bitWrite(Btt5, 1, LOW ); } else { bitWrite(Btt5, 1, HIGH); } if (points == 1) { bitWrite(Btt0, 0, HIGH); } else { bitWrite(Btt0, 0, LOW); } digitalWrite(ST_CP, LOW); // Последовательная передача данных на пин DS shiftOutMy(DS, SH_CP, MSBFIRST, Btt0); shiftOutMy(DS, SH_CP, MSBFIRST, Btt1); shiftOutMy(DS, SH_CP, MSBFIRST, Btt2); shiftOutMy(DS, SH_CP, MSBFIRST, Btt3); shiftOutMy(DS, SH_CP, MSBFIRST, Btt4); shiftOutMy(DS, SH_CP, MSBFIRST, Btt5); digitalWrite(ST_CP, HIGH); delay(10); digitalWrite(ST_CP, LOW); delay(30); } } /** * Выдача текущего времени на индикатор */ void DisplayTime(void) { my_s = ntp_time % 60; my_m = ( ntp_time / 60 ) % 60; my_h = ( ntp_time / 3600 ) % 24; if (!(lastMinute == my_m)) { lastMinute = my_m; DisplayTimeRandom(); } Btt0 = 0; Btt1 = 0; Btt2 = 0; Btt3 = 0; Btt4 = 0; Btt5 = 0; temp = my_m % 10; m2(temp); temp = my_m / 10; m1(temp); temp = my_h % 10; h2(temp); temp = my_h / 10; h1(temp); if (my_h >= HourNightStart || my_h <= HourNightEnd ) { analogWrite(HV, 200); digitalWrite(LED, LOW); } else { analogWrite(HV, 0); digitalWrite(HV, HIGH); if (LedON) { digitalWrite(LED, HIGH); } } // NtpNoConn=0; if (NtpNoConn == 1) { bitWrite(Btt5, 1, LOW ); } else { bitWrite(Btt5, 1, HIGH); } if (points == 1) { bitWrite(Btt0, 0, HIGH); } else { bitWrite(Btt0, 0, LOW); } // Выливаем на регистры digitalWrite(ST_CP, LOW); // Последовательная передача данных на пин DS shiftOutMy(DS, SH_CP, MSBFIRST, Btt0); shiftOutMy(DS, SH_CP, MSBFIRST, Btt1); shiftOutMy(DS, SH_CP, MSBFIRST, Btt2); shiftOutMy(DS, SH_CP, MSBFIRST, Btt3); shiftOutMy(DS, SH_CP, MSBFIRST, Btt4); shiftOutMy(DS, SH_CP, MSBFIRST, Btt5); digitalWrite(ST_CP, HIGH); delay(10); digitalWrite(ST_CP, LOW); // Serial.print("Time: "); // Serial.print(my_h); // Serial.print(":"); // Serial.print(my_m); // Serial.print(":"); // Serial.println(my_s); //Serial.print("LED: "); //Serial.println(LedON); } /** * Посылаем и парсим запрос к NTP серверу */ bool GetNTP(void) { WiFi.hostByName(ntpServerName, timeServerIP); sendNTPpacket(timeServerIP); delay(1000); int cb = udp.parsePacket(); if (!cb) { Serial.println("No packet yet"); return false; } else { Serial.print("packet received, length="); Serial.println(cb); // Читаем пакет в буфер udp.read(packetBuffer, NTP_PACKET_SIZE); // 4 байта начиная с 40-го сождержат таймстамп времени - число секунд // от 01.01.1900 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); // Конвертируем два слова в переменную long unsigned long secsSince1900 = highWord << 16 | lowWord; // Конвертируем в UNIX-таймстамп (число секунд от 01.01.1970 const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears; // Делаем поправку на местную тайм-зону ntp_time = epoch + TIMEZONE * 3600; Serial.print("Unix time = "); Serial.println(ntp_time); } return true; } /** * Посылаем запрос NTP серверу на заданный адрес */ unsigned long sendNTPpacket(IPAddress& address) { Serial.println("sending NTP packet..."); // Очистка буфера в 0 memset(packetBuffer, 0, NTP_PACKET_SIZE); // Формируем строку зыпроса NTP сервера packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[1] = 0; // Stratum, or type of clock packetBuffer[2] = 6; // Polling Interval packetBuffer[3] = 0xEC; // Peer Clock Precision // 8 bytes of zero for Root Delay & Root Dispersion packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; // Посылаем запрос на NTP сервер (123 порт) udp.beginPacket(address, 123); udp.write(packetBuffer, NTP_PACKET_SIZE); udp.endPacket(); } void h1(uint8_t output) { switch (temp) { case 0: Btt4 = Btt4 + 0b00100000; break; case 1: Btt5 = Btt5 + 0b00001000; break; case 2: Btt5 = Btt5 + 0b00010000; break; case 3: Btt5 = Btt5 + 0b00100000; break; case 4: Btt5 = Btt5 + 0b01000100; break; case 5: Btt5 = Btt5 + 0b10000000; break; case 6: Btt4 = Btt4 + 0b00000010; break; case 7: Btt4 = Btt4 + 0b00000100; break; case 8: Btt4 = Btt4 + 0b00001000; break; case 9: Btt4 = Btt4 + 0b00010000; break; } } void h2(uint8_t output) { switch (temp) { case 0: Btt2 = Btt2 + 0b00000010; break; case 1: Btt4 = Btt4 + 0b01000000; break; case 2: Btt4 = Btt4 + 0b10000000; break; case 3: Btt3 = Btt3 + 0b00000010; break; case 4: Btt3 = Btt3 + 0b00000100; break; case 5: Btt3 = Btt3 + 0b00001000; break; case 6: Btt3 = Btt3 + 0b00010000; break; case 7: Btt3 = Btt3 + 0b00100000; break; case 8: Btt3 = Btt3 + 0b01000000; break; case 9: Btt3 = Btt3 + 0b10000000; break; } } void m1(uint8_t output) { switch (temp) { case 0: Btt1 = Btt1 + 0b00010000; break; case 1: Btt2 = Btt2 + 0b00000100; break; case 2: Btt2 = Btt2 + 0b00001000; break; case 3: Btt2 = Btt2 + 0b00010000; break; case 4: Btt2 = Btt2 + 0b00100000; break; case 5: Btt2 = Btt2 + 0b01000000; break; case 6: Btt2 = Btt2 + 0b10000000; break; case 7: Btt1 = Btt1 + 0b00000010; break; case 8: Btt1 = Btt1 + 0b00000100; break; case 9: Btt1 = Btt1 + 0b00001000; break; } } void m2(uint8_t output) { switch (temp) { case 0: Btt0 = Btt0 + 0b10000000; break; case 1: Btt1 = Btt1 + 0b00100000; break; case 2: Btt1 = Btt1 + 0b01000000; break; case 3: Btt1 = Btt1 + 0b10000000; break; case 4: Btt0 = Btt0 + 0b00000010; break; case 5: Btt0 = Btt0 + 0b00000100; break; case 6: Btt0 = Btt0 + 0b00001000; break; case 7: Btt0 = Btt0 + 0b00010000; break; case 8: Btt0 = Btt0 + 0b00100000; break; case 9: Btt0 = Btt0 + 0b01000000; break; } } void shiftOutMy(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) { uint8_t i; for (i = 0; i < 8; i++) { if (bitOrder == LSBFIRST) digitalWrite(dataPin, !!(val & (1 << i))); else digitalWrite(dataPin, !!(val & (1 << (7 - i)))); // delay(1); digitalWrite(clockPin, HIGH); // delay(1); digitalWrite(clockPin, LOW); // delay(1); } } void set_Mode(void) { if (Key_1_Pr) { // нажатие 1й кнопки вкл/выкл подсветки LedON = !LedON; if (LedON) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } Key_1_Pr = 0; } // Реакция на кнопки if (Key_2_Pr) { //нажатин на вторую кнопку - запрос времени NtpNoConn = false; if ( GetNTP() ) { ms2 = cur_ms; t_correct = ntp_time - t_cur; NtpNoConn = true; Next_ms = 86400000; } Key_2_Pr = 0; } if (Key_1_LP == 1) { Key_1_LP = 0; } } // Опрос кнопок процедура візівается 200 раз в секунду void button_press(void) { if (ADCkey > 300) { Key_Timer = 0; if (Key_1_Count == 255) { return; } else { Key_1_Count++; if (Key_1_Count == Key_Pr) Key_1_Pr = 1; if (Key_1_Count == Key_Long) Key_1_LP = 1; return; } } else { Key_1_Count = 0; if (Key_1_Pr) Key_1_PrR = 1; if (!Key_1_LP) { Key_1_LPR = 1; Key_1_PrR = 0; } else { Key_1_Pr = 0; Key_1_LP = 0; } // return; } if (ADCkey > 150) { Key_Timer = 0; if (Key_2_Count == 255) { return; } else { Key_2_Count++; if (Key_2_Count == Key_Pr) Key_2_Pr = 1; if (Key_2_Count == Key_Long) Key_2_LP = 1; return; } } else { Key_2_Count = 0; Key_2_Pr = 0; Key_2_LP = 0; // return; } if (ADCkey > 100) { Key_Timer = 0; if (Key_3_Count == 255) { return; } else { Key_3_Count++; if (Key_3_Count == Key_Pr) Key_3_Pr = 1; if (Key_3_Count == Key_Long) Key_3_LP = 1; return; } } else { Key_3_Count = 0; Key_3_Pr = 0; Key_3_LP = 0; // return; } }