RTCまたはリアルタイムクロックは、時間を追跡するために電子機器や組み込み機器で最も一般的に使用されるモジュールです。しかし、RTCの問題は、コンピューターのマイクロチップがそれほど正確ではなく、ローカルデバイスの時刻しか提供できないことです。一方、インターネットを使用してNTPサーバーから時間を取得することは、より正確であり、世界中のあらゆる地理的領域の時間を提供できるため、時間を取得するためのより良いソリューションです。NTPサーバーを使用して世界中のあらゆる場所の時間を取得するには、Wi-Fiモジュールとインターネットへのアクセスが必要です。このチュートリアルでは、ESP8266 NodeMCUを使用してNTPサーバーから現在の時刻と日付を取得し、それをOLEDディスプレイに表示します。
ネットワークタイムプロトコル(NTP)
NTPは、コンピュータネットワーク間でクロックを同期するための最も古いネットワークインターネットプロトコル(IP)の1つです。これは、1981年にデラウェア大学のDavid L. Millsによって設計されました。このプロトコルを使用して、数ミリ秒以内に多くのネットワークを協定世界時(UTC)に同期させることができます。 UTCは、世界が時計と時刻を規制する主要な時間基準です。 UTCは変化せず、地理的な場所によって異なります。 NTPは、UTCを時間基準として使用し、インターネット全体で正確で同期された時間を提供します。
NTPは、階層型のクライアントサーバーモデルで機能します。最上位モデルには、原子時計、電波、GPS、衛星から時間を受信するGSMなどの「stratum0」と呼ばれる基準時計があります。stratum0から時間を受信するサーバーは「stratum1」と呼ばれ、stratum1から時間を受信するサーバーは「stratum2」と呼ばれます。これは続き、時間の精度は各段階の後に低下し続けます。NTPは、同期するために利用可能ないくつかのタイムソースから最適なものを自動的に選択するため、フォールトトレラント対応のプロトコルになります。
したがって、このプロジェクトでは、ESP8266 NodeMCUを使用してNTPサーバーから時間を取得し、それをOLEDディスプレイに表示しています。これと同じ種類のインターネット時計は、前のチュートリアルでESP32を使用して作成されています。
ESP8266は、インターネットを使用してNTPサーバーにアクセスし、正確な時刻を取得できます。ここで、NTPはクライアントサーバーモードで動作し、ESP8266はクライアントデバイスとして動作し、UDP(ユーザーデータグラムプロトコル)を使用してNTPサーバーに接続します。クライアントは要求パケットをNTPサーバーに送信し、その代わりにNTPは、精度、タイムゾーン、UNIXタイムスタンプなどの情報で構成されるタイムスタンプパケットを送信します。次に、クライアントは、要件に応じてアプリケーションでさらに使用できる日付と時刻の詳細を分離します。
必要なコンポーネント
- モノクロ7ピンSSD13060.96インチOLEDディスプレイ
- ESP8266 NodeMCU
- マイクロUSBケーブル
- ブレッドボード
- オス-オスジャンパー線
回路図と接続
この7ピンOLEDディスプレイは、SPIプロトコルを使用してESP8266モジュールと通信します。以下は、OLEDSPIピンをNodeMCUに接続してインターネット時間を表示するための回路図と接続表です。
番号。 |
OLEDディスプレイ |
NodeMCU |
1 |
GND |
GND |
2 |
VDD |
3.3V |
3 |
SCK |
D5 |
4 |
MOSI(SPI)またはSDA(I2C) |
D7 |
5 |
リセット |
D3 |
6 |
DC |
D2 |
7 |
CS |
D8 |
このモノクロ7ピンOLEDディスプレイとESP8266NodeMCUとのインターフェースの詳細については、リンクをたどってください。
コードの説明
まず、NTPライブラリをダウンロードしてESP8266にインストールする必要があります。NTPクライアントで利用できるライブラリはたくさんあります。ArduinoIDEからそれらのいずれかをインストールできます。このチュートリアルでは、使いやすく、NTPサーバーから日付と時刻を取得する機能があるため、TaranaisによるNTPClientライブラリをインストールしました。ESP8266 NodeMCUは、ArduinoIDEを使用して簡単にプログラムできます。
NTPライブラリをインストールするには、最初に上記のリンクを使用してライブラリをダウンロードしてから、ArduinoIDEを使用してインストールします。インストールするには、[スケッチ]> [ライブラリを含める]> [。ZIPライブラリを追加]に移動し、zipフォルダーをダウンロードした場所に移動してZipフォルダーを開き、 ArduinoIDE を再起動します。
NTPClientライブラリには例が付属しています。 ArduinoIDE と Gotoの例> NTPClient> Advancedを開きます 。このスケッチに示されているコードは、NTPサーバーからの時刻をシリアルモニターに表示します。このスケッチを使用して、現在の時刻と日付をOLEDディスプレイに表示します。
完全なコードはこのチュートリアルの最後にあります。ここでは、コードのいくつかの重要な部分について説明しました。
ESP8266WiFiライブラリは、ネットワークに接続するためのESP8266固有のWi-Fiルーチンを提供します。WiFiUDP.hは、UDPパッケージの送受信を処理します。OLEDとNodeMCUのインターフェースにSPIプロトコルを使用しているため、「SPI.h」ライブラリをインポートします。また、OLEDディスプレイには「Adafruit_GFX.h」と「Adafruit_SSD1306.h」を使用しています。
#include
OLEDのサイズは128x64なので、画面の幅と高さをそれぞれ128と64に設定しています。したがって、SPI通信用にNodeMCUに接続されたOLEDピンの変数を定義します。
#define SCREEN_WIDTH 128 // OLEDディスプレイ幅(ピクセル単位) #define SCREEN_HEIGHT 64 // OLEDディスプレイ高さ(ピクセル単位) //ソフトウェアSPIを使用して接続されたSSD1306ディスプレイの宣言(デフォルトの場合): #define OLED_MOSI D7 #define OLED_CLK D5 #define OLED_DC D2 #define OLED_CS D8 #define OLED_RESET D3
Adafruit_SSD1306ディスプレイ(SCREEN_WIDTH、SCREEN_HEIGHT、OLED_MOSI、OLED_CLK、OLED_DC、OLED_RESET、OLED_CS);
以下のコード行で、「your_ssid」と「your_password」をWi-FiSSIDとパスワードに置き換えます。
const char * ssid = "your_ssid"; const char * password = "your_password";
WiFi.begin 関数にSSIDとパスワードを 指定 してWI-Fi接続を設定します。ESP8266の接続はNodeMCUに接続するのに時間がかかるため、接続されるまで待つ必要があります。
WiFi.begin(ssid、password); while(WiFi.status()!= WL_CONNECTED){ 遅延(500); Serial.print( "。"); }
日付と時刻を要求するには、タイムクライアントをNTPサーバーのアドレスで初期化します。精度を高めるために、地理的領域に近いNTPサーバーのアドレスを選択してください。ここでは、世界中のサーバーを提供する「 pool.ntp.org 」を使用します。アジアからサーバーを選択したい場合は、「 asia.pool.ntp.org 」を使用できます。 timeClient は、タイムゾーンのミリ秒単位のUTC時間オフセットも取ります。たとえば、インドのUTCオフセットは+5:30であるため、このオフセットをミリ秒単位で変換します。これは、5 * 60 * 60 + 30 * 60 = 19800に相当します。
範囲 |
UTC時間オフセット(時と分) |
UTC時間オフセット(秒) |
インド |
+5:30 |
19800 |
ロンドン |
0:00 |
0 |
ニューヨーク |
-5:00 |
-18000 |
WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP、 "pool.ntp.org"、19800,60000);
SSD1306_SWITCHCAPVCC は、ディスプレイを初期化するために内部で3.3Vを生成するために与えられています。OLEDが起動すると、「 WELCOME TO CIRCUIT DIGEST 」がテキストサイズ2、カラーBLUEで3秒間表示されます。
if(!display.begin(SSD1306_SWITCHCAPVCC)) { Serial.println(F( "SSD1306の割り当てに失敗しました")); にとって(;;); //続行せず、永久にループします } display.clearDisplay(); display.setTextSize(2); // 2倍スケールのテキストを描画します display.setTextColor(BLUE); display.setCursor(5、2); display.println( "WELCOME TO"); display.println( "CIRCUIT"); display.println( "DIGEST"); display.display(); delay(3000);
NTPクライアントは begin() 関数を使用して初期化 され、NTPサーバーから日付と時刻を設定します。
timeClient.begin();
Update() 関数は、NTPサーバーに要求するたびに日付と時刻を受け取るために使用されます。
timeClient.update();
115200のボーレートは、シリアルモニターに時間を出力するように設定されています。
Serial.begin(115200); Serial.println(timeClient.getFormattedTime());
getHours()、getMinutes()、getSeconds()、getDay はライブラリ関数であり、NTPサーバーからの現在の時間、分、秒、および日を提供します。以下のコードは、午前と午後を区別するために使用されます。 getHours() を使用して取得する時間が12より大きい場合は、その時刻をPMとして設定し、それ以外の場合はAMとして設定します。
int hh = timeClient.getHours(); int mm = timeClient.getMinutes(); int ss = timeClient.getSeconds(); int day = timeClient.getDay(); if(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 day = timeClient.getDay(); display.println( "'" + arr_days + "'");
getFormattedDate() は、NTPサーバーから 「yyyy-mm-dd」 形式の日付を取得するために使用されます。この関数は、日付と時刻を 「yyyy-mm-dd T hh:mm:ss 形式」で提供します。ただし、必要なのは日付だけなので、 date_time 形式で格納されているこの文字列を substring() 関数によって実行される「T」まで分割してから、日付を 「date」 変数に格納する必要があります。
date_time = timeClient.getFormattedDate(); int index_date = date_time.indexOf( "T"); 文字列日付= date_time.substring(0、index_date); Serial.println(date); display.println(date); display.display();
これは、OLEDインターネットタイムクロックが最終的にどのように見えるかです: