//2026.4.29
#include <WiFi.h>
#include <WebServer.h>
#include <WebSocketsServer.h> // 「WebSockets」ライブラリをインストールしてください
// WiFi設定
const char* ssid = "OPPO Reno5 A";
const char* password = "x676eixd";
WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
const int ledPin = 2; // 内蔵LEDピン
unsigned long targetTime = 0; // 点灯予定時刻
bool isWaiting = false; // 点灯待機フラグ
// スマートフォンに配信するHTMLファイル
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
body, html { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; position: fixed; font-family: sans-serif; background: #f0f2f5; }
.container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; }
input { font-size: 24px; padding: 15px; width: 70%; text-align: center; border: 2px solid #ddd; border-radius: 10px; margin-bottom: 20px; }
.btn { font-size: 20px; padding: 15px 40px; color: white; border: none; border-radius: 10px; cursor: pointer; width: 60%; margin: 10px; }
#onBtn { background: #28a745; }
#offBtn { background: #dc3545; }
</style>
</head>
<body>
<div class="container">
<h2>LED Controller</h2>
<input type="number" id="secInput" placeholder="点灯までの秒数">
<button id="onBtn" class="btn" onclick="send('ON')">ON (タイマー)</button>
<button id="offBtn" class="btn" onclick="send('OFF')">OFF (即時消灯)</button>
<p id="status">接続待機中...</p>
</div>
<script>
// ブラウザからESP32のIPに対してWebSocket接続
const socket = new WebSocket('ws://' + location.hostname + ':81');
socket.onopen = () => { document.getElementById('status').innerText = '接続済み (Secure)'; };
function send(cmd) {
const sec = document.getElementById('secInput').value || 0;
// 「コマンド,秒数」の形式で送信
socket.send(cmd + ',' + sec);
document.getElementById('status').innerText = cmd === 'ON' ? sec + '秒後に点灯します' : '消灯しました';
}
// スクロール防止
document.addEventListener('touchmove', (e) => e.preventDefault(), { passive: false });
</script>
</body>
</html>
)rawliteral";
void handleRoot() {
server.send(200, "text/html", index_html);
}
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
if (type == WStype_TEXT) {
String msg = String((char*)payload);
int commaIndex = msg.indexOf(',');
String cmd = msg.substring(0, commaIndex);
int seconds = msg.substring(commaIndex + 1).toInt();
if (cmd == "ON") {
targetTime = millis() + (seconds * 1000);
isWaiting = true;
Serial.printf("%d秒後の点灯を予約しました\n", seconds);
} else if (cmd == "OFF") {
isWaiting = false;
targetTime = 0;
digitalWrite(ledPin, LOW);
Serial.println("即時消灯");
}
}
}
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
server.on("/", handleRoot);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
Serial.println("\nサーバー開始");
Serial.print("接続先IP: "); Serial.println(WiFi.localIP());
}
void loop() {
server.handleClient();
webSocket.loop();
// タイマー管理:待機フラグが立っており、予定時刻を過ぎたら点灯
if (isWaiting && millis() >= targetTime) {
digitalWrite(ledPin, HIGH);
isWaiting = false;
Serial.println("点灯します。");
}
}
0 件のコメント:
コメントを投稿