/*
ds18b20.ino
DS18B20 温度取得サンプル
Web サーバー
M5STACK ATOM LITE
DS18B20 温度センサー
2025/02 : Ver.0.1 初版
Copyright 2025 Moo Soft(Yokoyama Akiyosi)
*/
#include <M5Atom.h>
#include <WiFi.h> // Wi-Fi
#include <WebServer.h> // Web Server
#include <ESPmDNS.h> // マルチキャストDNS
#include <OneWire.h> // DS18B20
#include <DallasTemperature.h> // DS18B20
//#include "freertos/task.h" // RTOS マルチタスク
//#include <sntp.h> // for sntp_sync_status
// === グローバル変数、定数 定義開始 ======================= //
WebServer server(80); // ポート80 の Web サーバ
// One Wire
#define DQ1 GPIO_NUM_26 // データ用 GPIO 指定 23,25,26,32
OneWire oneWire1(DQ1); // One Wire インスタンス
DallasTemperature DS18B_1(&oneWire1); // 温度制御ライブラリインスタンス
//
String my_SSID = "SSID"; // SSID
String my_PASS = "pass"; // パスフレーズ
String my_MDNS = "ds18b"; // マルチキャストDNS
//
bool DEBUG = true; // デバッグモードフラグ
volatile bool IS_WIFI = false; // Wi-Fi 接続状態フラグ true=接続中 false=切断
//volatile bool timeset = false; // NTP 同期フラグ
// === グローバル変数、定数 定義終了 ======================= //
// === 関数プロトタイプ宣言開始 =========================== //
void my_delay(unsigned long); // 指定時間待つ
void debug_print(String, bool); // デバッグ出力
//
void con_wifi(String, String); // Wi-Fi 接続
void WiFiEvent(WiFiEvent_t); // Wi-Fi event handler
//
void get_temp(String*); // One Wire DS18B20 の温度取得
//
void hdRoot(); // "/" アクセスレスポンス
void hdNotFound(); // File Not Found レスポンス
void web_task(void*); // Web サーバーリクエスト処理タスク
String get_lt(); // 現在時刻取得
// === 関数プロトタイプ宣言終了 =========================== //
// ===================================================== //
// 初期設定
// ===================================================== //
void setup() {
M5.begin(false, false, true);
Serial.begin(115200);
while (!Serial); // Serialport が開くのを待つ
con_wifi(my_SSID, my_PASS); // Wi-Fi 接続
DS18B_1.begin(); // One Wire センサインスタンス初期化
} // void setup()
// ===================================================== //
// メインループ
// ===================================================== //
void loop() {
String temp1 = "";
get_temp(&temp1); // DS18B20 の温度取得
debug_print(F("DS18B20_1:"), false);
debug_print(temp1 , true);
my_delay(10000UL); // 一休み(ms)
} // void loop()
// ===================================================== //
// Web サーバーリクエスト処理タスク
// ===================================================== //
void web_task(void* arg) {
while (true) {
if (IS_WIFI) server.handleClient();
delay(500);
} // while
} // void web_task()
// ===================================================== //
// Serial へデバッグ出力
// msg : 出力文字列
// lf : 改行指定フラグ
// ===================================================== //
void debug_print(String msg, bool lf) {
if (!DEBUG) return;
msg = " " + msg;
if (lf) Serial.println(msg);
else Serial.print(msg);
} // debug_print()
// ===================================================== //
// 指定時間待機する
// _wait : 待機時間(msec)
// ===================================================== //
void my_delay(unsigned long _wait) {
unsigned long _timer = millis(); // 現在時間退避
while (millis() - _timer < _wait);;
} // void my_delay()
// ===================================================== //
// Wi-Fi 接続
// _my_SSID : my_SSID
// _pass : パスフレーズ
// ===================================================== //
void con_wifi(String _ssid, String _pass) {
debug_print(F("Wi-Fi 接続先 :"), false);
debug_print(String(_ssid), true);
WiFi.disconnect(true); // 接続中なら切断
WiFi.mode(WIFI_STA); // ステーション(子機)モード
WiFi.onEvent(WiFiEvent); // イベントハンドラ設定
WiFi.begin(_ssid.c_str(), _pass.c_str()); // 接続開始
debug_print(F("Wi-Fi 接続中..."), true);
} // void con_wifi()
// ===================================================== //
// Wi-Fi event handler
// event : event
// ===================================================== //
void WiFiEvent(WiFiEvent_t event) {
IS_WIFI = event == SYSTEM_EVENT_STA_GOT_IP; // Wi-Fi 接続中フラグ
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP: // IP アドレス取得完了
debug_print(F("Wi-Fi 接続完了 IP address : "), false);
Serial.println(WiFi.localIP()); // IP アドレス表示
// ************************************ //
if (MDNS.begin(my_MDNS.c_str())) { // http://my_MDNS
debug_print(F("MDNS responder started :"), false);
debug_print(my_MDNS, true);
} // if
server.on("/", hdRoot); // ルートアクセスレスポンス
server.onNotFound(hdNotFound); // File Not Found レスポンス
server.begin(); // Start TCP (HTTP) server
MDNS.addService("http", "tcp", 80); // ポート80 の TCP で HTTP
// マルチタスク起動
// タスク名,"タスク名",スタックメモリサイズ,
// NULL,タスク優先順位,タスクハンドルポインタ,Core ID
// main の loop() は Core ID = 1
xTaskCreatePinnedToCore(web_task,
"web_task",
4096,
NULL,
1,
NULL,
0);
// ************************************ //
break;
case SYSTEM_EVENT_STA_DISCONNECTED: // 切断
my_delay(30000UL);
break;
default: break;
} // switch
} // WiFiEvent
// ===================================================== //
// One Wire DS18B20 の温度取得
// *temp1 : DS18B20 の温度を返す
// ===================================================== //
void get_temp(String *temp1) {
DS18B_1.requestTemperatures(); // 温度取得要求
float tempC1 = DS18B_1.getTempCByIndex(0); // 温度取得(℃)
if (tempC1 == DEVICE_DISCONNECTED_C)
*temp1 = "-999"; // 取得失敗
else
*temp1 = String(tempC1, 1); // 取得成功
} // void get_temp()
// ===================================================== //
// ルートアクセスレスポンス
// ===================================================== //
void hdRoot() {
String mes = "\
<!DOCTYPE html>\n\
<html lang='ja'>\n\
<head>\n\
<meta charset='utf-8'/>\n\
<meta http-equiv='Pragma' content='no-cache'>\n\
<meta http-equiv='Cache-Control' content='no-cache'>\n\
<meta http-equiv='Expires' content='0'>\n\
<meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=yes' />\n\
<title>DS18B20</title>\n\
<style type='text/css'>\n\
textarea {\n\
font-family: monospace;\n\
width:80%;\n\
font-size:16px;\n\
padding: 5px;\n\
}\n\
</style>\n\
<script type='text/javascript'>\n\
window.onload = function() { // ページ読込み時に実行したい処理\n\
const intv = 60 * 1000;\n\
setInterval('refresh()', intv); // 指定ミリ秒毎に実行\n\
} // window.onload()\n\
\n\
function refresh() {\n\
location.reload();\n\
}\n\
</script>\n\
</head>\n\
<body>\n\
<table border='0' cellpadding='5' align='center' width='50%' >\n\
<tr align='center'>\n\
<td>\n\
<h3>DS18B20 温度センサ</h3>\n\
</td>\n\
</tr>\n\
<tr align='center'>\n\
<td>\n\
<textarea readonly id='id_id' name='id' rows='12'>*?*</textarea>\n\
</td>\n\
</tr>\n\
<tr align='center'>\n\
<td>\n\
<button name='ref' onClick='location.reload();'>ページ更新</button>\n\
</td>\
</tr>\n\
</table>\n\
</body>\n\
</html>\n\
\n";
// String mes
String temp1 = "";
get_temp(&temp1); // One Wire DS18B20 の温度取得
temp1 = "\n温度:" + temp1 + "℃";
temp1 = get_lt() + "\n\n" + temp1;
mes.replace("*?*", temp1); // センサ表示データ作成
server.send(200, "text/html", mes); // html 送信
} // void hdRoot()
// ===================================================== //
// File Not Found レスポンス
// ===================================================== //
void hdNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
} // for
server.send(404, "text/plain", message);
} // void hdNotFound()
/*
// ===================================================== //
// NTP 同期コールバック関数
// ===================================================== //
void timeavailable(struct timeval *t) {
Serial.println("Got time adjustment from NTP!");
timeset = true;
} // void timeavailable(struct timeval *t)
*/
// ===================================================== //
// 現在時刻取得
// 戻り値:現在時刻文字列
// ===================================================== //
String get_lt() {
struct tm tm;
if (!getLocalTime(&tm)) {
//sntp_set_time_sync_notification_cb(timeavailable); // コールバック関数設定
//configTime(JST, 0, "ntp.nict.jp", "ntp.jst.mfeed.ad.jp", "time.google.com");
configTzTime("JST-9", "ntp.nict.jp", "ntp.jst.mfeed.ad.jp", "time.google.com");
//while (!timeset) { // 正常な時間が取得できるまで
while (!getLocalTime(&tm)) {
delay(1000);
} // while
} // if
char dtstr[256];
static const char *wd[7] = { "日", "月", "火", "水", "木", "金", "土" };
sprintf(dtstr,
"%04d/%02d/%02d(%s) %02d:%02d:%02d",
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
wd[tm.tm_wday],
tm.tm_hour,
tm.tm_min,
tm.tm_sec);
Serial.println(dtstr);
return String(dtstr);
} // String get_lt()
コメントを残す