目的:
NTPサーバーと時刻同期を行い、現在時刻を取得する。
手順:
- 時刻同期
wifi 設定後、configTime() により、NTPサーバーを設定する。
書式:
void configTime(long gmtOffset_sec, int daylightOffset_sec,
const char* server1, const char* server2, const char* server3);
パラメータ :
gmtOffset_sec GMTとローカル時刻との差(秒)。日本では 3600*9 (9時間)
daylightOffset_sec 夏時間設定(秒)。日本では 0
server1 ~ server3 NTPサーバ。最低一つ設定する。
記述例 :
configTime(3600 * 9, 0, "ntp.nict.jp", "time.google.com",
"ntp.jst.mfeed.ad.jp" );
- 時刻取得
時刻の取得は、getLocalTime() で取得する。
getLocalTime()
書式 :
bool getLocalTime(struct tm *info, uint32_t ms);
パラメータ:
info 取得する時刻情報を格納する領域。
ms タイムアウト時間。省略した場合は5000。
記述例:
struct tm timeInfo;
getLocalTime(&timeInfo, 1);
Serial.printf(" %04d/%02d/%02d %02d:%02d:%02d\n",
timeInfo.tm_year + 1900,
timeInfo.tm_mon + 1,
timeInfo.tm_mday,
timeInfo.tm_hour,
timeInfo.tm_min,
timeInfo.tm_sec) ;
注:
getLocalTime は、取得した年が 116(2016年) 以下の場合、タイムアウトになるまで取得し直す。NTPサーバーと同期がとれない場合、タイムアウト値を指定しないと、5秒間、リトライする(処理が待たされる) こととなる。
NTPサーバーと同期がとれない要因の 1つとして、WIFI 固定IP設定時の DNSアドレス が正しく設定されていないことが考えられる。( やらかしてました。 )
例:
「SPIFFSのテキストファイルをダウンロードする 」の シリアル出力にタイムスタンプを追加した例を以下に示す。
(メインスケッチ以外のファイルは 「SPIFFSのテキストファイルをダウンロードする 」を参照 )
<表示例>
|
2020/05/06 17:08:03
+++++++++++++++++ new client! +++++++++++++++++
GET / HTTP/1.1
|
(メインスケッチ以外のファイルは 「SPIFFSのテキストファイルをダウンロードする 」を参照 )
<表示例>
|
2020/05/06 17:08:03
+++++++++++++++++ new client! +++++++++++++++++
GET / HTTP/1.1
|
#include <WiFi.h> // WiFi 使用の為 #include "FS.h" // SPIFFS 使用の為 #include "SPIFFS.h" // SPIFFS 使用の為 #include "time.h" // getLocalTime 使用の為 #define DEBUG_HTML // Debug用 Serial 表示制御用 #define DEBUG // Debug用 Serial 表示制御用 // AP モード用 WIFI 設定 --------------------------------------------- const char ssid[] = "ESP32_AP"; // SSID for softAP const char pass[] = "password"; // password for softAP const IPAddress ip(192, 168, 4, 1); // IPアドレス for softAP const IPAddress subnet(255, 255, 255, 0); // サブネットマスク for softAP // 動作モードフラグ --------------------------------------------------- bool stamode = true ; // WiFi STA 接続モード : true bool sta_exec = false ; // WiFi STA接続モード実行中フラグ bool config_mode = false ; // 初期設定モード ; true bool config_exec = false ; // 初期設定実行中フラグ // 設定ファイル用 ----------------------------------------------------- String s_config ; // 設定ファイル用 String char wifi_ssid[128] = "" ; // SSID for WiFi STA char wifi_pass[128] = "" ; // password for WiFi STA IPAddress wifi_ip(192,168,1,66) ; // IP Address for WiFi STA IPAddress wifi_gw(192,168,1,1) ; // gate way for WiFi STA IPAddress wifi_sm(255,255,255,0) ; // subnet mask for WiFi STA IPAddress wifi_dns(192,168,1,1) ; // dns address for WiFi STA char wifi_mode[16] = "" ; // wifi mode String foot_msg ="" ; // リブートメッセージ用 #define JST 3600*9 // 日本の GMT との時間差(秒) #define CLIENT_TIMEOUT 3000 // クライアントタイムアウト (mS) WiFiServer server(80); String html_CONF ; // 設定用 HTML String html_MAIN ; // メイン HTML String html_resp ; // LED 調光処理用 ---------------------------------------------------------------- // -- for ledc byte brightness = 0 ; // LED 明るさ設定 (0-255) // ----------------------------------------------------------------------------- // arduino 初期化処理 -- // ----------------------------------------------------------------------------- void setup() { int res = 0 ; // 結果格納用 (ワーク) Serial.begin(115200); // シリアル 開始 SPIFFS.begin(true) ; // SPIFFS 開始 // 初期設定用 HTML ファイルの読み込み --------------------------------------- res = rd_SPIFFS("/WiFi_Config.html",html_CONF) ; // html_CONF に Config.html を格納 // 本体 HTML ファイルの読み込み ---------------------------------------------- res = rd_SPIFFS("/main.html",html_MAIN) ; // html_MAIN に main.html を格納 // レスポンス用HTML ファイルの読み込み ---------------------------------------- res = rd_SPIFFS("/resp_cnfld.html",html_resp) ; // html_resp に resp_confld.html を格納 // 初期設定ファイルを読み込み、グローバル変数に設定し、wifi,画面モードを決定 --- res = rd_config() ; // // wifiモード(stamode) に応じて AP か STA かを選択してサーバー起動 ------------- if (stamode == false) { // APモードの場合 softAP WiFi 開始 start_AP_server() ; // APモードでサーバー起動 sta_exec = false ; // } else { // STAモードの場合 Wifi 開始 start_STA_server() ; // STAモードでサーバー起動 sta_exec = true ; // configTime(JST, 0, "ntp.nict.jp", // NTPサーバー設定 "time.google.com", // "ntp.jst.mfeed.ad.jp"); // } // // 実行中のモード (設定かメインか) を設定 ------------------------------------- if (config_mode) config_exec = true ; // config_mode なら config_exec を '1' else config_exec = false ; // Serial.println("Server start!"); // メイン処理用 初期化 ------------------------------------------------------ ledcSetup(0, 5000, 8); // channel 0 周波数 5000 Hz, 8 bit ledcAttachPin(2,0); // attach pin 2 to channel 0 ledcWrite(0, 0); // initialize channel 0 to off } // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // arduino メインループ処理 -- // ----------------------------------------------------------------------------- void loop() { WiFiClient client = server.available(); String htmlwk = "" ; // html 用 ワーク変数 String line = "" ; // クライアントからの入力用 int xhr = 0 ; // xhr 要求フラグ unsigned long start_time = 0 ; // タイムアウト監視開始時間 unsigned long wait_time = 0 ; // 開始/前回受信からの経過時間 struct tm timeInfo; // 時刻を格納するオブジェクト // HTML クライアント処理 ------------------------------------------------------ if (client) { start_time = millis() ; // タイムアウト監視開始時間を更新 getLocalTime(&timeInfo, 10); // 時刻を取得 Serial.printf(" %04d/%02d/%02d %02d:%02d:%02d\n", // タイムスタンプ表示 timeInfo.tm_year + 1900, // 年 (西暦) timeInfo.tm_mon + 1, // 月 timeInfo.tm_mday, // 日 timeInfo.tm_hour, // 時 timeInfo.tm_min, // 分 timeInfo.tm_sec ) ; // 秒 Serial.println(" +++++++++++++++++ new client! +++++++++++++++++ "); while (client.connected()) { // クライアントから接続されたとき if (client.available()) { // start_time = millis() ; // タイムアウト監視開始時間を更新 line = client.readStringUntil('\n'); // 1行分取得 # ifdef DEBUG_HTML // Serial.println(line) ; // # endif // if (line.indexOf("GET /?") != -1) { // GET 処理 if (config_mode) // 初期設定用 フォームデータ処理 set_form2param(line) ; // フォームデータを変数に格納 else { // メイン用 処理 xhr = proc_main(line) ; // フォームデータのメイン処理 } // } // // 最終行(空行)を受信した時 ------------------------------------------- if (line.length() == 1 && line[0] == '\r'){ // 最終行判定 if (stamode != sta_exec) { // sta_mode が変わった場合 if (strcmp(wifi_mode,"ap") == 0){ // リブートメッセージを設定 foot_msg = "アクセスポイントモードに移行します。<br> " ; foot_msg += "この画面を閉じてアクセスポイントに接続して下さい。" ; }else{ foot_msg = "ステーションモードに移行します。<br>"; foot_msg += "この画面を閉じて 設定したアドレスに接続して下さい。" ; } if (config_exec) { // 初期設定中なら send_CONF_html(client) ; // 初期設定 HTML 送信 } else { // メイン画面なら send_MAIN_html(client) ; // メイン HTML 送信 } // ( その後 リブート) } else { // sta_mode が変わらない場合 if (config_mode) { // 次に初期設定を表示するなら send_CONF_html(client) ; // 初期設定 HTML 送信 config_exec = true ; // } else { // 次にメイン画面なら if (xhr) { // XHR 応答の場合 send_resp_html(client) ; // XHR 応答 送信 } else { // HTML 送信なら send_MAIN_html(client) ; // メイン HTML 送信 config_exec = false ; // } // } // } // # ifdef DEBUG_HTML // Serial.println("Send HTML") ; // # endif // break ; // ループ終了 } // //------------------------------------------------------------------- } else { // 文字列受信していない時 wait_time = millis() - start_time ; // if ((wait_time) > CLIENT_TIMEOUT) { // 文字列受信 タイムアウト Serial.print("タイムアウト :") ; // Serial.print(wait_time) ; // Serial.println(" mS") ; // break ; // ループ終了 } // } } // 接続が切れた場合 ------------------------------------------------------ client.stop(); Serial.println("client disonnected"); Serial.println("----------------------------------------------------"); } if (stamode != sta_exec) { // sta_mode が変わった場合 Serial.println("------------------- リブートします------------------- "); delay(500); // ESP.restart() ; // リブート } else { } // -------------------------------------------------------------------------- }
(行#4)
getLocalTime を使用する為に必要な include
(行#32)
日本時間(GMTとの差) の定義。
(行#72~74)
STAモードにする場合、NTPサーバー設定を行う。
(行#103)
時刻を格納するオブジェクトの定義。
(行#108)
時刻を取得。
(行#109~115)
時刻(タイムスタンプ)の表示。
Serial 表示に printf が使用できる模様。
0 件のコメント:
コメントを投稿