目的:
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 件のコメント:
コメントを投稿