RTC ali ura v realnem času je najpogosteje uporabljen modul v elektroniki in vgrajenih napravah za beleženje časa. Toda težava RTC je v tem, da mikročipi v računalnikih niso tako natančni in lahko zagotavljajo le čas lokalne naprave. Po drugi strani pa je uporaba interneta za pridobivanje časa s strežnikov NTP boljša rešitev za pridobivanje časa, saj je natančnejša in lahko zagotavlja čas katerega koli geografskega območja na svetu. Potrebujemo samo modul Wi-Fi in dostop do interneta, da s pomočjo strežnikov NTP pridobimo čas na kateri koli lokaciji na svetu. V tej vadnici bomo uporabili ESP8266 NodeMCU, da dobimo trenutni čas in datum s strežnikov NTP ter jih prikažemo na OLED zaslonu.
Network Time Protocol (NTP)
NTP je eden najstarejših omrežnih internetnih protokolov (IP) za sinhronizacijo ur med računalniškimi omrežji. Zasnoval ga je David L. Mills z Univerze v Delawareju leta 1981. Ta protokol lahko v nekaj milisekundah sinhronizirate številna omrežja z univerzalnim koordiniranim časom (UTC). UTC je primarni časovni standard, po katerem svet ureja uro in čas. UTC se ne spreminja in se razlikuje za različne geografske lokacije. NTP uporablja UTC kot referenco časa in zagotavlja natančen in sinhroniziran čas po internetu.
NTP deluje na hierarhičnem modelu odjemalec-strežnik. Vrhunski model ima referenčne ure, znane kot "stratum0", kot so atomske ure, radijski valovi, GPS, GSM, ki sprejema čas od satelita. Strežniki, ki prejemajo čas iz stratum0, se imenujejo "stratum1", strežniki, ki prejemajo čas iz stratum1, pa "stratum2" itd. To se nadaljuje in natančnost časa se po vsaki fazi zmanjšuje. NTP samodejno izbere najboljši izmed več razpoložljivih časovnih virov za sinhronizacijo, zaradi česar je protokol odporen na napake.
Torej tukaj v tem projektu dobivamo čas s strežnika NTP z uporabo ESP8266 NodeMCU in ga prikazujemo na OLED zaslonu. Ta ista vrsta internetne ure je zgrajena z uporabo ESP32 v prejšnjih vajah.
ESP8266 lahko dostopa do strežnikov NTP prek interneta, da dobi natančen čas. Tu NTP deluje v načinu odjemalec-strežnik, ESP8266 deluje kot odjemalska naprava in se poveže s strežniki NTP z uporabo UDP (User Datagram Protocol). Odjemalec pošlje paket zahtevkov strežnikom NTP, v zameno pa NTP pošlje paket časovnega žiga, ki vsebuje informacije, kot so natančnost, časovni pas, časovni žig UNIX itd. Nato odjemalec loči podatke o datumu in času, ki jih je mogoče nadalje uporabiti v aplikacijah v skladu z zahtevami.
Potrebne komponente
- Enobarvni 7-pinski SSD1306 0.96 ”OLED zaslon
- ESP8266 NodeMCU
- Kabel Micro USB
- Breadboard
- Žice moškega do moškega
Shema vezja in povezave
Ta 7-nožni zaslon OLED komunicira z modulom ESP8266 z uporabo protokola SPI, spodaj so shema vezij in tabela povezav za povezavo zatičev OLED SPI z NodeMCU za prikaz internetnega časa.
Ne |
OLED zaslon |
NodeMCU |
1. |
GND |
GND |
2. |
VDD |
3.3V |
3. |
SCK |
D5 |
4. |
MOSI (SPI) ali SDA (I2C) |
D7 |
5. |
PONASTAVITI |
D3 |
6. |
DC |
D2 |
7. |
CS |
D8 |
Če želite izvedeti več o tem enobarvnem 7-polnem OLED zaslonu in njegovem povezovanju z ESP8266 NodeMCU, sledite povezavi.
Razlaga kode
Najprej moramo prenesti in namestiti knjižnico NTP v ESP8266. Za odjemalca NTP je na voljo veliko knjižnic. Kateri koli lahko namestite iz Arduino IDE. V tej vadnici sem namestil knjižnico NTPClient podjetja Taranais, ker je enostavna za uporabo in ima funkcije za pridobivanje datuma in ure s strežnikov NTP. ESP8266 NodeMCU je mogoče enostavno programirati z uporabo Arduino IDE.
Če želite namestiti knjižnico NTP, najprej prenesite knjižnico s pomočjo zgornje povezave in jo nato namestite z uporabo Arduino IDE. Če ga želite namestiti, pojdite na Sketch> Include Library> Add.ZIP Library , nato odprite mapo Zip, tako da pojdite na mesto, kjer ste prenesli mapo zip, in znova zaženite Arduino IDE.
Knjižnica NTPClient vsebuje primere. Odprite Arduino IDE in pojdite na Primeri> NTPClient> Napredno . Koda, podana na tej skici, prikazuje čas s strežnika NTP na serijskem monitorju. To skico bomo uporabili za prikaz trenutnega časa in datuma na OLED zaslonu.
Popolna koda je na voljo na koncu te vadnice, tukaj sem razložil nekaj pomembnih delov kode.
Knjižnica ESP8266WiFi ponuja specifične Wi-Fi rutine za povezavo z omrežjem ESP8266. WiFiUDP.h obravnava pošiljanje in prejemanje paketov UDP. Ker za vmesnik OLED-a z NodeMCU uporabljamo protokol SPI, bomo zato uvozili knjižnico “SPI.h”. Za OLED zaslon se uporabljata “Adafruit_GFX.h” in “Adafruit_SSD1306.h”.
#include
Naša velikost OLED je 128 x 64, zato širino in višino zaslona nastavimo na 128 oziroma 64. Torej definirajte spremenljivke za OLED nožice, povezane z NodeMCU za komunikacijo SPI.
#define SCREEN_WIDTH 128 // OLED širina zaslona, v slikovnih pikah #define SCREEN_HEIGHT 64 // OLED display display, in pixels // Izjava za SSD1306 zaslon, povezan s programsko opremo SPI (privzeti primer): #define OLED_MOSI D7 #define OLED_CLK D5 #define OLED_DC D2 #define OLED_CS D8 #define OLED_RESET D3
Zaslon Adafruit_SSD1306 (SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
V spodnjih vrsticah kode zamenjajte »your_ssid« in »your_password« z vašim SSID-jem Wi-Fi in geslom.
const char * ssid = "your_ssid"; const char * password = "your_password";
Nastavite povezavo WI-Fi, tako da funkciji WiFi.begin dodelite SSID in geslo. Povezava ESP8266 traja nekaj časa, da se poveže z NodeMCU, zato moramo počakati, da se poveže.
WiFi.begin (ssid, geslo); medtem ko (WiFi.status ()! = WL_CONNECTED) { zamuda (500); Serial.print ("."); }
Če želite zahtevati datum in uro, inicializirajte odjemalca časa z naslovom strežnikov NTP. Za boljšo natančnost izberite naslov strežnikov NTP, ki so blizu vašega geografskega območja. Tu uporabljamo “ pool.ntp.org ”, ki ponuja strežnike iz celega sveta. Če želite izbrati strežnike iz Azije, lahko uporabite » asia.pool.ntp.org «. timeClient upošteva tudi časovni zamik UTC v milisekundah vašega časovnega pasu. Na primer, UTC premik za Indijo je +5: 30, zato pretvorimo ta odmik v milisekundah, kar je enako 5 * 60 * 60 + 30 * 60 = 19800.
Območje |
Odmik časa UTC (ure in minute) |
Čas pomika UTC (v sekundah) |
INDIJA |
+5: 30 |
19800 |
LONDON |
0:00 |
0 |
NEW YORK |
-5: 00 |
-18000 |
WiFiUDP ntpUDP; NTPClient timeClient (ntpUDP, "pool.ntp.org", 19800,60000);
SSD1306_SWITCHCAPVCC je podan za notranje generiranje 3.3V za inicializacijo zaslona. Ko se OLED zažene, prikaže » DOBRODOŠLI V DIGESTI V KOLU « z velikostjo besedila 2 in barvo MODRO 3 sekunde.
if (! display.begin (SSD1306_SWITCHCAPVCC)) { Serial.println (F ("SSL1306 dodelitev ni uspela")); za (;;); // Ne nadaljujte, zanko za vedno } display.clearDisplay (); display.setTextSize (2); // Nariši prikaz besedila v 2- kratnem merilu.setTextColor (MODRA); display.setCursor (5, 2); display.println ("DOBRODOŠLI NA"); display.println ("KROG"); display.println ("DIGEST"); display.display (); zamuda (3000);
Odjemalec NTP se inicializira s funkcijo start () za nastavitev datuma in ure s strežnikov NTP.
timeClient.begin ();
Funkcija Update () se uporablja za sprejemanje datuma in ure, kadar koli zahtevamo strežnike NTP.
timeClient.update ();
Hitrost prenosa 115200 je nastavljena za tiskanje časa na serijski monitor.
Serial.begin (115200); Serial.println (timeClient.getFormattedTime ());
getHours (), getMinutes (), getSeconds (), getDay so funkcija knjižnice in podajajo trenutno uro, minute, sekunde in dan s strežnika NTP. Spodnja koda se uporablja za razlikovanje časa med AM in PM. Če je ura, ki jo dobimo z uporabo getHours () , večja od 12, nastavimo ta čas kot PM, sicer je AM.
int hh = timeClient.getHours (); int mm = timeClient.getMinutes (); int ss = timeClient.getSeconds (); int day = timeClient.getDay (); če (hh> 12) { hh = hh-12; display.print (hh); display.print (":"); zaslon.tiskanje (mm); display.print (":"); display.print (ss); display.println ("PM"); } else { display.print (hh); display.print (":"); zaslon.tiskanje (mm); display.print (":"); display.print (ss); display.println ("AM"); } int day = timeClient.getDay (); display.println ("'" + arr_days + "'");
getFormattedDate () je uporabljen datum pridobivanja v obliki llll-mm-dd s strežnika NTP. Ta funkcija poda datum in uro v obliki llll-mm-dd T hh: mm: ss . Vendar potrebujemo samo datum, zato moramo ta niz, ki je shranjen v obliki date_time, razdeliti na "T", kar opravi funkcija substring (), in nato datum shraniti v spremenljivko "date" .
date_time = timeClient.getFormattedDate (); int index_date = date_time.indexOf ("T"); Niz niza = datum_časov.podniz (0, datum_indeksa); Serial.println (datum); display.println (datum); display.display ();
Tako bo končno videti ura OLED Internet Time Clock: