[Arduinoのすすめ][ArduinoConf][ArduinoMonitor][iArduino]

NTPで合わせる時計

概要

デジットで300円で売っていた 7セグメントLED基板とWifi モジュール ESP-WROOM-02 を使って NTP で時刻合わせをする時計を作ってみました。LED基板の下に AtMega168 と ESP-WROOM-02 が収まっています。

AtMega168 はブートローダを入れて、Arduino Duemillanove 相当(5V, 16MHz)にしています。ESP-WROOM-02 はスイッチサイエンスのピッチ変換モジュール(シンプル版)を使っています。こちらも Arduino IDE でプログラムを書き込んでいます。

回路

電源はLEDの消費電流が大きいので電池駆動をあきらめ、入手が容易な5VのACアダプタ(安定化タイプ, USB電源ともいう)を使うことにしました。LED基板は18本の端子があり、約半数のLEDを交互にダイナミック点灯するタイプでした。回路図ではマイコンのピン番号の順番とLED基板のピン番号の順番が同じようになっていますが、逆にした方が配線がきれいになると思います。UEW線で配線するときになって気づきました。プログラム側を書き換えるのが面倒になってそのままです。

AtMega168 を使っているのは手持ち部品があったからで、328でも構いません。 クロックは水晶発振子を使っています。NTPで時刻合わせができないときに、あまりずれないようにするためです。また8Mhzより16MHzの方がダイナミック点灯の切り替えを高速にしても余裕があるので。

ESP-WROOM-02はピッチ変換基板の裏面で IO15 を GND に接続(購入時から)、EN, RST, IO0, IO2 をプルアップしています。EN, RSTはR1, R2に1608サイズの10kΩ程度のチップ抵抗をつければOKです。IO0, IO2はSJ2, SJ3の片方のパッドにチップ抵抗をつけ、チップ抵抗の片方を3.3VへUEW線へつなぎました。プログラムの書き込み時は、IO0をGNDにつなぎ、リセットを掛けてから、USBシリアル(3.3V)などを使って書き込みます。

プログラム

AtMega168側単体でも時計として機能するようにしてあります。 LED基板にダイナミック点灯をして時刻を表示します。 シリアルポート(115.2kbps)から表示の切り替え(時:分(M0<LF>), 月:日(M1<LF>), 分:秒(M2<LF>))と時刻合わせができます。 時刻合わせは、hhmmss<LF>もしくはYYYYMMDDhhmmss<LF>を受け取ると、その時刻に切り替わります(<LF>を受け取ったタイミングで指定された時刻(1秒以下は0)に設定する, 15bytesなので通信にかかる時間は2msぐらいなので無視)。

ESP-WROOM-02 (ESP8266EX) 側はサンプルベースに作りました。 ESP-WROOM-02内で時計を持ち、それを更新する形にしています。 更新時には受け取った時刻(tとする, NTPサーバの送信時の時刻, 1秒以下の桁もある)をそのままセットするのではなく、パケットを送ってから受け取るまでの時間(Δt)の半分だけずれた値(t+Δt)で更新するようにしています。また、更新のタイミングを少し調整して、NTPサーバ(同一ネットワーク内にある)との差が見た目に1秒以内になるようにしています。

検索すると、NTP で時刻合わせする時計を作られている方は大勢見つかるのですが、こういう1秒以内のNTPサーバとのずれについて考慮されていないようでした。NTPサーバが同一ネットワーク内にないとずれに気づかないかもしれませんが、気になったので合わせてみました。

ダウンロード

いずれも Time ライブラリを使っているので、Arduino IDEから扱えるようにしておきます。


Arduinoのすすめ
Copyright (c) 2016, Noriaki Mitsunaga