ESP8266 (ESP-WROOM-02) でNTP(時刻合わせ)をするライブラリ。(Timeライブラリと連携して)

## 概要
ESP8266 (以下 WROOM02) で、Timeライブラリと連携して、自動的に時刻合わせをする。

## はじめに
ESP8266 (以下 WROOM02) では、時刻に関する処理は Time ライブラリを使うのが便利ですが、起動直後は時刻がズレて(1970/01/01になって)いるので、時刻修正をしないといけない。
Time ライブラリでは外部時刻合わせ用の関数を設定できるので、それに対応した NTP サーバから正確な時刻を取得する関数をライブラリ化しておきます。

## 準備
ArduinoIDE でのライブラリの使い方は、<a href="http://qiita.com/exabugs/items/fe46ec45ff2ffd6c5777" target="_blank">Qiita「はじめての Arduino ライブラリ」</a> 等を参照してください。

ネットワーク(Wi-Fi)への接続が必要です。
(より詳しくは、<a href="http://qiita.com/exabugs/items/2f67ae363a1387c8967c" target="_blank">Qiita「ESP8266 (ESP-WROOM-02) でWi-Fi使用時のSSID/パスワードをブラウザで設定できるように」</a> 等を参照してください。)

## ライブラリの使い方

 1. <a href="https://github.com/PaulStoffregen/Time" target="_blank">Timeライブラリ</a> をインポートします。<br>
(zipを作成して、「zip形式のライブラリをインポート」を実行)

```
$ git clone https://github.com/PaulStoffregen/Time.git Time
$ zip -r Time.zip Time
```

 2. 今回作成した、<a href="https://github.com/exabugs/sketchLibraryNTP" target="_blank">NTPライブラリ</a>をインポートします。<br>
(zipを作成して、「zip形式のライブラリをインポート」を実行)<br>

```
$ git clone https://github.com/exabugs/sketchLibraryNTP NTP
$ zip -r NTP.zip NTP
```

 3. スケッチは以下になります。

``` cpp
#include <ESP8266WiFi.h>
#include <NTP.h>

void setup() {
  Serial.begin(115200);
  Serial.println();

  // 自分のネットワークに合わせてください
  WiFi.begin("your-ssid", "your-password");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");

  // 初期化
  // 2390 はローカルのUDPポート。空いている番号なら何番でもいいです。
  ntp_begin(2390);

  // NTPサーバを変更 (デフォルト: ntp.nict.jp)
  //setTimeServer("s2csntp.miz.nao.ac.jp");

  // NTP同期間隔を変更 (デフォルト: 300秒)
  //setSyncInterval(10);
}


void display(){

  time_t n = now();
  time_t t;

  char s[20];
  const char* format = "%04d-%02d-%02d %02d:%02d:%02d";

  // JST
  t = localtime(n, 9);
  sprintf(s, format, year(t), month(t), day(t), hour(t), minute(t), second(t));
  Serial.print("JST : ");
  Serial.println(s);

  // UTC
  t = localtime(n, 0);
  sprintf(s, format, year(t), month(t), day(t), hour(t), minute(t), second(t));
  Serial.print("UTC : ");
  Serial.println(s);
}

void loop() {
  display();
  delay(2000);
}
```
 - time_t から年月日への変換結果はTimeライブラリ内部でキャッシュされていますので、連続した year(t), month(t) 等の実行は効率的に処理されます。

## 実行結果
```
...
WiFi connected
Transmit NTP Request
sendNTPpacket : ntp.nict.jp
Receive NTP Response
JST : 2016-01-10 12:36:42
UTC : 2016-01-10 03:36:42
JST : 2016-01-10 12:36:44
UTC : 2016-01-10 03:36:44
JST : 2016-01-10 12:36:46
UTC : 2016-01-10 03:36:46
...
```













## 個人利用が許可されている国内の公開NTPサーバー
出典:http://www.atmarkit.co.jp/ait/articles/1507/08/news003.html

|提供組織|アドレス|
|----|----|
|独立行政法人 情報通信研究機構（NICT）|ntp.nict.jp|
|インターネットマルチフィード（MFEED）|ntp.jst.mfeed.ad.jp|
|国立天文台|s2csntp.miz.nao.ac.jp|
|Ring Server Project|ntp.ring.gr.jp|
|NTP POOL PROJECT|jp.pool.ntp.org|

> 公開NTPサーバーでは、NICT（情報通信研究機構）が運営するサーバーの時刻精度が日本標準時に対して10ナノ秒（1億分の1秒）以内、処理能力も毎秒100万リクエスト以上と、信頼性とキャパシティの両面から推奨できます。


NTPサーバは、冗長化のためにDNSラウンドロビンされている場合があるので、IPアドレスではなく、ホスト名でアクセスするようにします。

## まとめ
Timeライブラリに時刻同期用関数を設定できる仕組みがあるので、それを使ってNTP同期するライブラリを作成しました。
(完全に非同期になるようにしたかったのですが、うまくいかなかったのでTimeライブラリの時刻同期用関数を使う方式になっています。)

次は、<a href="" target="_blank">Qiita「ESP8266 (ESP-WROOM-02) で7セグメントLEDを制御する」</a> で、NTP時計を作ろうかと思っています。