RTC veya Gerçek Zamanlı Saat, zamanın kaydını tutmak için Elektronik cihazlarda ve gömülü cihazlarda en yaygın kullanılan modüldür. Ancak RTC ile ilgili sorun, bilgisayarlardaki mikroçiplerin o kadar doğru olmaması ve sadece yerel cihazın saatini sağlayabilmeleridir. Öte yandan, zamanı NTP sunucularından almak için interneti kullanmak, daha doğru olduğu ve dünyadaki herhangi bir coğrafi bölgenin zamanını sağlayabildiği için daha iyi bir çözümdür. NTP sunucularını kullanarak dünyanın herhangi bir yerinde zaman kazanmak için bir Wi-Fi modülüne ve internete erişmeye ihtiyacımız var. Bu eğitimde, NTP sunucularından geçerli saat ve tarihi almak ve OLED ekranda görüntülemek için ESP8266 NodeMCU kullanacağız.
Ağ Zaman Protokolü (NTP)
NTP, bilgisayar ağları arasında saat senkronizasyonu için en eski ağ İnternet Protokolü'nden (IP) biridir. 1981'de Delaware Üniversitesi'nden David L. Mills tarafından tasarlandı. Bu protokol, birçok ağı birkaç milisaniye içinde Koordineli Evrensel Zaman (UTC) ile senkronize etmek için kullanılabilir. UTC, dünyanın saati ve saati düzenlediği birincil zaman standardıdır. UTC farklı coğrafi konumlar için değişmez ve değişiklik göstermez. NTP, zaman referansı olarak UTC'yi kullanır ve İnternet üzerinden doğru ve senkronize zaman sağlar.
NTP, hiyerarşik bir istemci-sunucu modelinde çalışır. Üst model atomik saatler, radyo dalgaları, GPS, GSM gibi uydudan zaman alan "stratum0" olarak bilinen referans saatlere sahiptir. Stratum0'dan zaman alan sunucular "stratum1", stratum1'den zaman alan sunucular "stratum2" olarak adlandırılır ve bu böyle devam eder. Bu devam eder ve her aşamadan sonra zamanın doğruluğu azalmaya devam eder. NTP, senkronize etmek için mevcut birkaç zaman kaynağının en iyisini otomatik olarak seçer ve bu da onu hataya dayanıklı protokol yapar.
Yani burada bu projede ESP8266 NodeMCU kullanarak NTP sunucusundan zaman alıyoruz ve OLED ekranda gösteriyoruz. Bu aynı tür İnternet saati, önceki eğitimde ESP32 kullanılarak oluşturulmuştur.
ESP8266, doğru zaman almak için internet kullanarak NTP sunucularına erişebilir. Burada NTP istemci-sunucu modunda çalışır, ESP8266 istemci cihaz olarak çalışır ve UDP (Kullanıcı Datagram Protokolü) kullanarak NTP sunucularına bağlanır. İstemci, NTP sunucularına bir istek paketi iletir ve karşılığında NTP, doğruluk, zaman dilimi, UNIX zaman damgası vb. Gibi bilgileri içeren bir zaman damgası paketi gönderir. Ardından istemci, gereksinimlere göre uygulamalarda daha fazla kullanılabilecek tarih ve saat ayrıntılarını ayırır.
Gerekli Bileşenler
- Tek renkli 7 pimli SSD1306 0,96 ”OLED ekran
- ESP8266 NodeMCU
- Mikro USB kablosu
- Breadboard
- Erkek-Erkek Jumper kabloları
Devre Şeması ve Bağlantılar
Bu 7 pinli OLED ekran, SPI protokolünü kullanarak ESP8266 modülü ile iletişim kurar, aşağıda İnternet saatini görüntülemek için OLED SPI pinlerini NodeMCU ile bağlamak için devre şeması ve bağlantı tablosu verilmiştir.
Hayır. |
OLED Ekran |
NodeMCU |
1 |
GND |
GND |
2 |
VDD |
3.3V |
3 |
SCK |
D5 |
4 |
MOSI (SPI) veya SDA (I2C) |
D7 |
5 |
SIFIRLA |
D3 |
6 |
DC |
D2 |
7 |
CS |
D8 |
Bu Siyah Beyaz 7 pimli OLED ekran ve bunun ESP8266 NodeMCU ile arabirimi hakkında daha fazla bilgi edinmek için bağlantıyı izleyin.
Kod Açıklama
Öncelikle NTP kitaplığını ESP8266'ya indirip kurmalıyız. NTP İstemcisi için kullanılabilen birçok kitaplık vardır. Arduino IDE'den herhangi birini kurabilirsiniz. Bu eğitimde Taranais tarafından NTPClient kitaplığını kurdum çünkü kullanımı kolay ve NTP sunucularından tarih ve saat alma işlevlerine sahip. ESP8266 NodeMCU, Arduino IDE kullanılarak kolayca programlanabilir.
NTP kütüphanesini kurmak için önce yukarıdaki bağlantıyı kullanarak kütüphaneyi indirin ve ardından Arduino IDE'yi kullanarak kurun. Kurmak için Sketch> Include Library> Add.ZIP Library'ye gidin , ardından zip klasörünü indirdiğiniz konuma giderek Zip klasörünü açın ve Arduino IDE'yi yeniden başlatın.
NTPClient kitaplığı örneklerle birlikte gelir. Arduino IDE ve Goto Örnekleri> NTPClient> Gelişmiş'i açın . Bu çizimde verilen kod, seri monitörde NTP sunucusundan gelen zamanı gösterir. Bu taslağı, OLED ekranında mevcut saat ve tarihi görüntülemek için kullanacağız.
Tam kod bu eğitimin sonunda mevcuttur, burada kodun birkaç önemli bölümünü açıkladım.
ESP8266WiFi kitaplığı, ağa bağlanmak için ESP8266'ya özgü Wi-Fi rutinleri sağlar. WiFiUDP.h, UDP paketlerinin gönderilip alınmasını sağlar. OLED ile NodeMCU arasında arayüz oluşturmak için SPI protokolü kullandığımızdan, "SPI.h" kitaplığını içe aktaracağız. OLED Ekran için “Adafruit_GFX.h” ve “Adafruit_SSD1306.h” kullanılır.
#Dahil etmek
OLED boyutumuz 128x64 olduğundan ekran genişliğini ve yüksekliğini sırasıyla 128 ve 64 olarak ayarlıyoruz. Bu nedenle, SPI iletişimi için NodeMCU'ya bağlı OLED pinlerinin değişkenlerini tanımlayın.
#define SCREEN_WIDTH 128 // OLED ekran genişliği, piksel cinsinden #define SCREEN_HEIGHT 64 // OLED ekran yüksekliği, piksel olarak // Yazılım SPI kullanılarak bağlanan SSD1306 ekran beyanı (varsayılan durum): #define OLED_MOSI D7 #define OLED_CLK D5 #define OLED_DC D2 #define OLED_CS D8 #define OLED_RESET D3
Adafruit_SSD1306 ekranı (SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
“Your_ssid” ve “your_password” kısmını aşağıdaki kod satırlarında Wi-Fi SSID'niz ve şifrenizle değiştirin.
const char * ssid = "your_ssid"; const char * şifre = "şifreniz";
WiFi.begin işlevine SSID ve şifre vererek Wi-Fi bağlantısını kurun . ESP8266'nın bağlantısının NodeMCU'ya bağlanması biraz zaman alıyor, bu yüzden bağlanana kadar beklememiz gerekiyor.
WiFi.begin (ssid, şifre); while (WiFi.status ()! = WL_CONNECTED) { gecikme (500); Seri.baskı ("."); }
Tarih ve saat istemek için, zaman istemcisini NTP sunucularının adresiyle başlatın. Daha iyi doğruluk için coğrafi bölgenize yakın olan NTP sunucularının adresini seçin. Burada dünyanın her yerinden sunucular veren " pool.ntp.org " kullanıyoruz. Asya'dan sunucu seçmek isterseniz “ asia.pool.ntp.org ” kullanabilirsiniz. timeClient ayrıca, saat diliminizin milisaniye cinsinden UTC saat farkını alır. Örneğin, Hindistan için UTC farkı +5: 30'dur, bu nedenle bu ofseti 5 * 60 * 60 + 30 * 60 = 19800'e eşit olan milisaniye cinsinden dönüştürüyoruz.
Alan |
UTC saat farkı (saat ve dakika) |
UTC zaman farkı (saniye) |
HİNDİSTAN |
+5: 30 |
19800 |
LONDRA |
0:00 |
0 |
NEW YORK |
-5: 00 |
-18.000 |
WiFiUDP ntpUDP; NTPClient timeClient (ntpUDP, "pool.ntp.org", 19800,60000);
SSD1306_SWITCHCAPVCC , ekranı başlatmak için dahili olarak 3.3V üretmesi için verilir. OLED başladığında, metin boyutu 2 ve MAVİ renkle 3 saniye süreyle " DEVRE ÖZETİNE HOŞ GELDİNİZ " mesajını görüntüler.
if (! display.begin (SSD1306_SWITCHCAPVCC)) { Serial.println (F ("SSD1306 tahsisi başarısız oldu")); için(;;); // Devam etmeyin, sonsuza kadar döngü yapın } display.clearDisplay (); display.setTextSize (2); // 2X ölçekli metin çiz display.setTextColor (BLUE); display.setCursor (5, 2); display.println ("HOŞGELDİNİZ"); display.println ("CIRCUIT"); display.println ("DIGEST"); display.display (); gecikme (3000);
NTP istemcisi, NTP sunucularından tarih ve saati ayarlamak için begin () işlevi kullanılarak başlatılır .
timeClient.begin ();
Update () işlevi, NTP sunucularına her istediğimizde tarih ve saati almak için kullanılır.
timeClient.update ();
115200 Baud hızı, seri monitörde saati yazdırmak için ayarlanır.
Serial.begin (115200); Serial.println (timeClient.getFormattedTime ());
getHours (), getMinutes (), getSeconds (), getDay kütüphane işlevleridir ve NTP sunucusundan geçerli saat, dakika, saniye ve günü verir. Aşağıdaki kod, AM ve PM arasındaki zamanı ayırt etmek için kullanılır. GetHours () kullanarak elde ettiğimiz saat 12'den büyükse, o zamanı PM, aksi takdirde AM olarak ayarlarız.
int hh = timeClient.getHours (); int mm = timeClient.getMinutes (); int ss = timeClient.getSeconds (); int gün = timeClient.getDay (); eğer (hh> 12) { hh = hh-12; display.print (hh); display.print (":"); display.print (mm); display.print (":"); display.print (ss); display.println ("PM"); } else { display.print (hh); display.print (":"); display.print (mm); display.print (":"); display.print (ss); display.println ("AM"); } int gün = timeClient.getDay (); display.println ("'" + arr_days + "'");
getFormattedDate () , NTP sunucusundan "yyyy-aa-gg" biçiminde tarih almak için kullanılır. Bu işlev tarih ve saati "yyyy-aa-gg T ss: dd: ss biçiminde verir. Ancak sadece tarihe ihtiyacımız var, bu yüzden date_time formatında saklanan bu dizgeyi substring () işlevi tarafından yapılan "T" ye kadar bölmek ve ardından tarihi "date" değişkeninde saklamak zorundayız.
date_time = timeClient.getFormattedDate (); int index_date = tarih_saat.indexOf ("T"); Dize tarihi = tarih_saat.substring (0, dizin_tarihi); Serial.println (tarih); display.println (tarih); display.display ();
Bu nasıl OLED Internet saat Saat nihayet görünecektir: