前掲の諸兄のスケッチ眺めてみましたが,ハンドラーの部分の記述と,html の javascript の部分がいま
いちわかりません。youtbe をあれこれ検索していましたら,別の諸兄の記事がめにとまりました。この諸兄の
スケッチなら,私用に改変できそうです。諸兄は,超音波を使ってますが,超音波だと,タンクに穴を開ける
必要がある気がしますので,超音波は使わないで当初の予定のように水位センサーを使ってやります。
ひとまず,諸兄のプログラムのオリジナルをインストールしてみます。
ところが,ところが,インストールに必要な,プラグインをIDEに取り込めません。一日,あれこれやりまし
たがやっとできました。
原因は,arduino IDE のバージョンで,使っていたV2.**ではだめで,v1.**で,やっとできました。
これが,分かるのに丸一日,インストールしていたarduino IDE 関係のフォルダーも全削除して,何回か
インストール,つかれました。
おかげで,やっと,下記の諸兄のスケッチをesp32に書き込み,テストできました。
// 必要なライブラリのインクルード
#include <WiFi.h>
#include <WebServer.h>
#include <SPIFFS.h>
// ピンの定義
#define trigPin 5 // 超音波センサのトリガーピン
#define echoPin 18 // 超音波センサのエコーピン
// WiFi接続情報
const char* ssid = "Your SSID";
const char* password = "Your Password";
// WebServerオブジェクトの初期化
WebServer server(80);
// セットアップ関数
void setup() {
Serial.begin(115200); // シリアル通信の開始
pinMode(trigPin, OUTPUT); // トリガーピンを出力として設定
pinMode(echoPin, INPUT); // エコーピンを入力として設定
// SPIFFSの初期化
if(!SPIFFS.begin(true)){
Serial.println("SPIFFSのマウントに失敗しました");
return;
}
// WiFi接続
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Webサーバーのルート設定
server.on("/", HTTP_GET, []() {
server.send(200, "text/html", SPIFFS.open("/index.html", "r").readString());
});
// '/distance'で距離を返す設定
server.on("/distance", HTTP_GET, []() {
server.send(200, "text/plain", String(measureDistance()));
});
server.begin(); // サーバーの開始
}
// メインループ
void loop() {
server.handleClient(); // クライアントのリクエストを処理
}
// 距離測定関数
float measureDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
float distance = (duration * 0.0343) / 2;
return distance;
}
スケッチは簡単ですが,HP掲載用のhtmlとjavascritpがやっかいのようですが,これもあまり手を加えずに済みそうです。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>水位計</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
<style>
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-family: Arial, sans-serif;
font-size: 20px;
}
#container {
width: 90%;
height: 50%;
}
.settings {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.settings > div {
margin: 0 10px;
}
.alert {
display: none;
color: red;
text-align: center;
position: absolute;
width: 100%;
bottom: 10%;
}
#title {
display: flex;
justify-content: center;
align-items: center;
font-size: 50px;
}
</style>
</head>
<body>
<div id="title">Water Level monitoring</div>
<div class="settings">
<div>
<label for="minDistance">0% Distance (cm): </label>
<input type="number" id="minDistance" value="2">
</div>
<div>
<label for="maxDistance">100% Distance (cm): </label>
<input type="number" id="maxDistance" value="15">
</div>
</div>
<div id="container"></div>
<div id="alert" class="alert">Alert: The value is below 20%</div>
<script>
var minDistance = parseFloat(document.getElementById('minDistance').value);
var maxDistance = parseFloat(document.getElementById('maxDistance').value);
document.getElementById('minDistance').addEventListener('change', function() {
minDistance = parseFloat(this.value);
updateChart();
});
document.getElementById('maxDistance').addEventListener('change', function() {
maxDistance = parseFloat(this.value);
updateChart();
});
// Highchartsのゲージオプション設定
var gaugeOptions = {
chart: {
type: 'solidgauge',
},
title: null,
pane: {
startAngle: -120,
endAngle: 120,
background: {
backgroundColor: '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
yAxis: {
stops: [
[0.1, '#DF5353'], // 高い値で青系
[0.5, '#DDDF0D'], // 中間値で黄色
[0.9, '#55BF3B'] // 低い値で赤系
],
lineWidth: 0,
minorTickInterval: null,
tickAmount: 2,
min: 0,
max: 100,
title: null,
labels: {
y: 16
}
},
credits: {
enabled: false
},
series: [{
name: 'Distance',
data: [100], // 初期値
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:30px">{y}%</span></div>'
}
}]
};
// Highchartsのゲージを作成
var chart = Highcharts.chart('container', Highcharts.merge(gaugeOptions, {
series: [{
data: [100] // シリーズにも初期値をセット
}]
}));
// ゲージの値を更新する関数
function updateGauge(value) {
// minDistanceとmaxDistanceを使用して値を計算
var newVal = ((maxDistance - value) / (maxDistance - minDistance)) * 100;
// newValが0未満の場合は0に、100を超える場合は100に制限する
newVal = Math.max(0, Math.min(newVal, 100));
newVal = Math.round(newVal); // 小数点以下を四捨五入して整数に
chart.series[0].points[0].update(newVal);
// 値が20以下の場合、アラートを表示
if (newVal <= 20) {
document.getElementById('alert').style.display = 'block';
} else {
document.getElementById('alert').style.display = 'none';
}
}
// ESP32からデータを取得してゲージを更新する
// HTML内のJavaScriptの一部
// HTML内のJavaScriptの一部
setInterval(function () {
fetch('/distance')
.then(response => response.text())
.then(distance => {
var dist = parseFloat(distance);
updateGauge(dist); // ゲージを更新する関数に距離データを渡す
})
.catch(function (error) {
console.error('Error fetching distance:', error);
});
}, 1000); // 1秒ごとに更新
</script>
</body>
</html>
この諸兄のいいところは,スケッチにhtmlの部分を含めるのではなく,htmlは別途esp32にアップロードでき
るところでしょうか。そのため,デバックのために,htmlを抜き出す必要もなく,htmlをそのままデバックで
きます。