ニキシー管時計作ってみた3|NTPで時計機能実装

作ってみた

前回任意の数字を表示できるようになったので、現在時刻を表示できるようにします。物理的なスイッチがないので、Wi-Fi経由でNTPサーバーから時刻を取得しそれを表示させます。

やったこと

  • ESP32をWi-Fiでインターネット接続
  • NTPサーバーから現在時刻を取得
  • ニキシー管に現在時刻を表示

時計機能実装

SimpleTime.ino
arduino-esp32/SimpleTime.ino at master · espressif/arduino-esp32 · GitHub
ESP32用のサンプルを参考にニキシー管時計用に改造しました。

ESP32に下記コードを書き込みます。

#include <WiFi.h>
#include "time.h"

const char* ssid       = "YOUR_SSID";  //自分のSSID
const char* password   = "YOUR_PASS";  //自分のパスワード

const char* ntpServer = "pool.ntp.org";//接続するNTPサーバー
const long  gmtOffset_sec = 9 * 3600;  //UTC(世界標準時)から9時間進めJST(日本標準時)にする
const int   daylightOffset_sec = 0;    //サマータイムなし

#define DECODER_A 21  //数字表示に関するピンの定義
#define DECODER_B 18  //K155ID1(BCD to Decimal decoder)に送る
#define DECODER_C 17  //BCD(2進化10進数)を書き込むピン
#define DECODER_D 19

#define NIXIE_1 16    //光らせたいニキシー管を指定するためのピン
#define NIXIE_2 26    //HIGHでニキシー管が光る
#define NIXIE_3 13
#define NIXIE_4 25
#define NIXIE_5 14
#define NIXIE_6 33
#define NIXIE_7 27
#define NIXIE_8 32

#define PS_DOWN 4     //高電圧を出力するためのピン(TL494のDTCピン)
                      //LOWで高電圧を出力する

#define DISPLAY_MS 2     //1つのニキシー管を光らせる時間
#define BLANKING_US 200  //光らせる管を切り替える時に
                         //陽極をOFFにする時間(ゴースト対策)

/**
 * (表示したい数字(10進表現), 表示したいニキシー管名)で
 * 指定のニキシー管に指定の数字を表示させる関数
 */
void displayDigit(unsigned short digit, unsigned short pin)
{
  digitalWrite(DECODER_A, (1 << 0) & digit);
  digitalWrite(DECODER_B, (1 << 1) & digit);
  digitalWrite(DECODER_C, (1 << 2) & digit);
  digitalWrite(DECODER_D, (1 << 3) & digit);
  digitalWrite(pin, HIGH);
  delay(DISPLAY_MS);
  digitalWrite(pin, LOW);
  delayMicroseconds(BLANKING_US); 
}

/**
 * 8本のニキシー管に現在時刻を表示する関数
 */
void printNixiesLocalTime()
{
  struct tm timeinfo;
  //時間取得に失敗したら(00000500)を表示
  if(!getLocalTime(&timeinfo)){
    displayDigit(0, NIXIE_1);
    displayDigit(0, NIXIE_2);
    displayDigit(0, NIXIE_3);
    displayDigit(0, NIXIE_4);
    displayDigit(0, NIXIE_5);
    displayDigit(5, NIXIE_6);
    displayDigit(0, NIXIE_7);
    displayDigit(0, NIXIE_8);
    return;
  }
    //現在の(日付,時,分,秒)を表示
    displayDigit(timeinfo.tm_mday / 10, NIXIE_1);
    displayDigit(timeinfo.tm_mday % 10, NIXIE_2);
    displayDigit(timeinfo.tm_hour / 10, NIXIE_3);
    displayDigit(timeinfo.tm_hour % 10, NIXIE_4);
    displayDigit(timeinfo.tm_min / 10, NIXIE_5);
    displayDigit(timeinfo.tm_min % 10, NIXIE_6);
    displayDigit(timeinfo.tm_sec / 10, NIXIE_7);
    displayDigit(timeinfo.tm_sec % 10, NIXIE_8);
}

void setup() {
  //WiFiに接続
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
  }
  
  //時刻を取得して同期
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  
  //以降必要ないためWiFiとの接続を切る
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  
  // 数字表示に関するピンの準備
  pinMode(DECODER_A, OUTPUT);
  pinMode(DECODER_B, OUTPUT);
  pinMode(DECODER_C, OUTPUT);
  pinMode(DECODER_D, OUTPUT);

  //ニキシー管点灯に関するピンの準備
  pinMode(NIXIE_1, OUTPUT);
  pinMode(NIXIE_2, OUTPUT);
  pinMode(NIXIE_3, OUTPUT);
  pinMode(NIXIE_4, OUTPUT);
  pinMode(NIXIE_5, OUTPUT);
  pinMode(NIXIE_6, OUTPUT);
  pinMode(NIXIE_7, OUTPUT);
  pinMode(NIXIE_8, OUTPUT);

  //高電圧出力に関するピンの準備
  pinMode(PS_DOWN, OUTPUT);

  digitalWrite(PS_DOWN, LOW);  //高電圧出力を開始
}

void loop() {
  printNixiesLocalTime();  //現在時刻をニキシー管に表示
}

解説

  • 4−5行目
    接続したいWi-FiのSSID, パスワードを指定
  • 7行目
    NTPサーバーの指定
  • 8−10行目
    日本時間に変換するための設定
  • 37-47行目(displayDigit
    表示したい数字とニキシー管名を指定することで、指定されたニキシー管に指定された数字を表示する関数
  • 52-76行目(printNixiesLocalTime
    マイコン内の現在時刻をニキシー管に表示させるため、ニキシー管の桁ごとに表示させる内容を指定。tm構造体はtimeinfo.tm_***といった形で日付、時間に関しては2桁の数字が取り出せるので、10で割る(/10)ことで10の位を、10の剰余(%10)を計算することで1の位を取り出す。
  • 78-112行目(setup
    起動時に一度だけ呼ばれる関数。Wi-Fiでの通信は電力消費が大きいので、マイコンの内部時計を起動時に一度だけNTPサーバーと同期させWi-Fi機能はすぐにOFFにする。
  • 114-116行目(loop
    常に呼ばれ続ける関数。マイコン内部の時刻をニキニー管に表示させる。

結果

Wi-Fi経由でNTPサーバーから時刻を取得し、ニキシー管に表示させることができました。

8桁だと何の情報を表示するか迷います。
今回は秒数を表示させることでニキシー管の数字の切り替わりを楽しみたかったので「日日時時分分秒秒」としました。日付を表示させるなら月も表示させたい気がします。

よく見ると後ろのスマホの時刻と合っており、無事NTPサーバーから時刻を取得できたことがわかります。

参考文献

espressif/arduino-esp32
arduino-esp32/SimpleTime.ino at master · espressif/arduino-esp32 · GitHub

コメント

タイトルとURLをコピーしました