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 を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のプログラム中、インデントなどのスペースもしくは改行は、通常のプログラム内ではごみ文字になるので、コピペした後、エディタでスペース文字などを入れなおしてください。

前へ

ESP32活用① ESP32とブラウザでお話しする(7)日時を表示する

次へ

リレーでON (1) Arduino UNO