NTP時計の製作
ESP32-WROOM-32を搭載したLOLIN32ボードを使って、時計を作ります。表示はコントローラTM1637が搭載された4桁の赤色7セグメントLEDです。こちらの記事でも利用しました。LOLIN32ボードは、ebayで入手しました。現在、600円前後です。ESP32のマイコン・ボードのI/Oはみんなが同じではありません。
開発は、Arduino IDE1.8.10を利用しました。
●接続
前記の記事と同じに配線したところ、書き込みに失敗しました。2番を隣の15番に変更しました。
TM1637 | LOLIN32 |
---|---|
CLK | 2 -> 15 |
DIO | 3 |
Vcc | 3V3 |
GND | GND |
TM1637のライブラリは、前出の記事と同じくTM1637 by Avishay Orpaz ver1.2.0を利用しました。
サンプルのTM1637testの #define CLK 2 を15に変更して書き込み、表示を確認します。
●NTPで時刻を得る
マイコン・ボードLOLIN32は、Wi-Fiでインターネットに接続できます。NTPサーバから正確な時刻を読みます。LOLIN32用のサンプル、ESP32->timeからsimpletimeを読み込み、下記の2行を自分のWi-Fiアクセス・ポイントに変更して実行します。
const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS"; |
このスケッチをベースに、上記のTM1637の表示スケッチと合成します。tmという構造体に時刻や年月日の情報が入っています。時と分の情報は、その構造体の要素を抜き出します。
getLocalTime(&timeinfo); Hour = timeinfo.tm_hour; Min = timeinfo.tm_min; |
4桁の表示データはdata[]配列に入れます。時と分は2桁の数値なので、それぞれ分離して、TM1637DisplayのライブラリにあるencodeDigit()関数を使って桁データに変換します。
2番目の桁はコロン(通常はドット)を表示したいので、最上位ビットを'1'にしています。
data[0] = display.encodeDigit(Hour / 10); data[1] = display.encodeDigit(Hour % 10) | 0b10000000; data[2] = display.encodeDigit(Min / 10); data[3] = display.encodeDigit(Min % 10); |
スケッチです。
#include <WiFi.h> #include "time.h" #include <TM1637Display.h> #define CLK 15 #define DIO 3 const char* ssid = "Buffalo-G-20EA"; const char* password = "********"; const char* ntpServer = "ntp.nict.jp"; const long gmtOffset_sec = 3600*9; // JST const int daylightOffset_sec = 0; TM1637Display display(CLK, DIO); uint8_t data[] = { 0xff, 0xff, 0xff, 0xff }; // all '1' struct tm timeinfo; byte Hour = 0; byte Min = 0; void printLocalTime(){ if(!getLocalTime(&timeinfo)){ Serial.println("Failed to obtain time"); return; } Serial.println(&timeinfo, "%H:%M"); } void setup(){ display.setBrightness(0x0f); Serial.begin(115200); //connect to WiFi Serial.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(" CONNECTED"); //init and get the time configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); printLocalTime(); //disconnect WiFi as it's no longer needed WiFi.disconnect(true); WiFi.mode(WIFI_OFF); } void loop(){ delay(1000); getLocalTime(&timeinfo); Hour = timeinfo.tm_hour; Min = timeinfo.tm_min; Serial.print(Hour);Serial.print(":");Serial.println(Min); data[0] = display.encodeDigit(Hour / 10); data[1] = display.encodeDigit(Hour % 10) | 0b10000000; data[2] = display.encodeDigit(Min / 10); data[3] = display.encodeDigit(Min % 10); display.setSegments(data); }
実行例です。
スタンドアロンで動作するように組み替えました。
(2020/01/03)時刻の先頭の文字が0を表示すると煩わしいので、下記の記述でゼロサプレスします。
data[0] = (Hour / 10) ? display.encodeDigit(Hour / 10) : 0x00; data[1] = display.encodeDigit(Hour % 10) | 0b10000000; data[2] = (Min / 10) ? display.encodeDigit(Min / 10) : 0x00; data[3] = display.encodeDigit(Min % 10);
(※) 二つのスケッチを合成したので、型の指定などが統一されていません。
(※) 本Webのプログラム中、インデントなどのスペースもしくは改行は、通常のプログラム内ではごみ文字になるので、コピペした後、エディタでスペース文字などを入れなおしてください。