ESP32でネットワークから操作可能な赤外線リモコンを作った
概要
ESP32で赤外線リモコンを作ります。前作ったラズパイリモコンから部品は全て流用しました。
プログラム
ESP32
赤外線のコード自体はESP32に保存せず、POSTリクエストでESP32に送りつける感じにします。
これで新しいコードを追加するごとに書き込まなくて済みます。
#include <Arduino.h>
#include <WiFi.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <WebServer.h>
#include <ArduinoJson.h>
// WiFi credentials
const char* ssid = "SSID"; // Replace with your SSID
const char* password = "Pass"; // Replace with your Password
const IPAddress ip(192, 168, 100, 51); // 好きなIPに変えて
const IPAddress gateway(192, 168, 100, 1);
const IPAddress subnet(255, 255, 255, 0);
const IPAddress dns1(192, 168, 100, 1);
// Webserver
WebServer server(80);
// LED
const uint16_t kIrLed = 4; // LEDを刺したピン
IRsend irsend(kIrLed);
// コード受け取って発信
void sendIrCode(JsonArray rawData) {
uint16_t rawArray[rawData.size()];
for (size_t i = 0; i < rawData.size(); i++) {
rawArray[i] = rawData[i];
}
Serial.println("Sending IR code...");
irsend.sendRaw(rawArray, rawData.size(), 38); // 38kHzで送信
}
// POSTで送られてきたIRコードを処理
void handleSendIR() {
if (server.hasArg("plain")) {
String jsonString = server.arg("plain");
// JSONパース
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, jsonString);
if (error) {
server.sendHeader("Access-Control-Allow-Origin", "*"); // CORS対応
server.send(400, "application/json", "{\"error\":\"Invalid JSON\"}");
return;
}
// JSONからデータを取得
JsonArray rawData = doc["code"];
sendIrCode(rawData);
server.sendHeader("Access-Control-Allow-Origin", "*"); // CORS対応 ここらへんがないとHTMLでPOSTできない(CURLからはなくてもできた)
server.send(200, "application/json", "{\"status\":\"IR code sent\"}");
} else {
server.sendHeader("Access-Control-Allow-Origin", "*"); // CORS対応
server.send(400, "application/json", "{\"error\":\"No data provided\"}");
}
}
// CORS対応のプリフライトリクエスト(OPTIONS)ハンドラ
void handleOptions() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.sendHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
server.sendHeader("Access-Control-Allow-Headers", "Content-Type");
server.send(204);
}
void setup() {
// Connect to WiFi
if (!WiFi.config(ip,gateway,subnet,dns1)){
Serial.println("Failed to configure!");
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
// IR init
irsend.begin();
// POSTでJSONデータを受け取るエンドポイントを設定
server.on("/send_ir", HTTP_POST, handleSendIR);
// CORS対応のプリフライトリクエスト(OPTIONS)を処理
server.on("/send_ir", HTTP_OPTIONS, handleOptions);
// サーバーを開始
server.begin();
Serial.println("Server started");
}
void loop() {
server.handleClient();
delay(100); //最低限のdelayを入れたほうがいい
}
クライアント側(リモコン)
RawDataをjson形式でPOSTすれば発信してくれます。
$ curl -X POST http://192.168.100.51/send_ir -H "Content-Type: application/json" -d '{"code":[3499, 1736, 447, 424, 447, 424, 447, 1303, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447]}'
HTMLでPOSTするなら次のような感じ。フォームに出てきた[]内にRawData書いて送信します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IR Code Sender</title>
</head>
<body>
<h1>Send IR Code to ESP32</h1>
<form id="irForm">
<label for="irCode">Enter IR Code (JSON format):</label><br>
<textarea id="irCode" rows="10" cols="50">
{"code":[]}
</textarea><br><br>
<button type="submit">Send IR Code</button>
</form>
<p id="response"></p>
<script>
document.getElementById('irForm').addEventListener('submit', function(event) {
event.preventDefault();
const irCode = document.getElementById('irCode').value;
const url = 'http://192.168.100.51/send_ir'; // ESP32のIPアドレスに変更してください
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: irCode,
})
.then(response => response.json())
.then(data => {
document.getElementById('response').innerText = 'Response: ' + JSON.stringify(data);
})
.catch(error => {
document.getElementById('response').innerText = 'Error: ' + error;
});
});
</script>
</body>
</html>
即時に実行して自動でページ閉じてほしいならこっち
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ESP32 IR Sender</title>
</head>
<body>
<h1>Sending IR Code...</h1>
<script>
// ページを開いた時にすぐに実行される
window.onload = function() {
// 送信するIRコード
const irCode = [3499, 1736, 447, 424, 447, 424, 447, 1303, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 30170, 3499, 1736, 447, 424, 447, 424, 447, 1303, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447, 424, 447, 424, 447, 424, 447, 424, 447, 424, 447, 1303, 447];
// ESP32にPOSTリクエストを送る
fetch('http://192.168.100.51/send_ir', { // ESP32のIPアドレスに置き換えてください
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
code: irCode
})
})
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Network response was not ok.');
}
})
.then(data => {
console.log("IR code sent successfully:", data);
// 成功したらページを閉じる
window.close();
})
.catch(error => {
console.error("There was a problem with the fetch operation:", error);
// エラーがあってもページを閉じる
window.close();
});
};
</script>
</body>
</html>
GPT-4o ありがとう🥰

最近のコメント