DESIGN III / IV / PROJECT NOTES

テスト進捗

このページの内容
  1. テスト進捗
  2. 説明
  3. cppファイル
  4. jsファイル
  5. iniファイル
  6. htmlファイル
  7. cssファイル
  8. csvファイル

テスト進捗

説明

最終的なプログラミングは、VS CodeとPLATFORMIOプラグインを使用して行いました。
環境内にウェブファイルをアップロードすることで、アクセス時にウェブページが表示され、ページ上からデバイスの制御も可能となります。
合計で35時間以上の試行錯誤を重ね、多数の方法を試したため、今回は最終的な成果のみを公開しています。
なお、カメラの起動には成功しませんでした。原因としては、ESP32-CAMのフラッシュメモリ容量不足が疑われます。
今後、技術的なスキルが向上した際には、あらためてカメラ機能の実装に挑戦する予定です。

cppファイル

#include #include #include #include // 超音波センサーのピン #define TRIG1 13 #define ECHO1 12 #define TRIG2 15 #define ECHO2 14 #define TRIG3 4 #define ECHO3 16 const char* ssid = "ESP32-Radar"; const char* password = "12345678"; WebServer server(80); bool radarActive = false; int carWidth = 180; // 超音波測定 long readDistanceCM(int trigPin, int echoPin) { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration = pulseIn(echoPin, HIGH, 30000); return duration * 0.0343 / 2; } long filterDistance(long current, long previous) { if (abs(current - previous) > 30) return previous; return current; } // レスポンス: index.html void handleRoot() { File file = SPIFFS.open("/index.html", "r"); if (!file) { server.send(500, "text/plain", "index.html not found"); return; } server.streamFile(file, "text/html"); file.close(); } // レスポンス: main.js void handleJS() { File file = SPIFFS.open("/main.js", "r"); if (!file) { server.send(404, "text/plain", "main.js not found"); return; } server.streamFile(file, "application/javascript"); file.close(); } // レスポンス: style.css void handleCSS() { File file = SPIFFS.open("/style.css", "r"); if (!file) { server.send(404, "text/plain", "style.css not found"); return; } server.streamFile(file, "text/css"); file.close(); } // レスポンス: 距離データ(JSON) void handleDistance() { if (!radarActive) { server.send(200, "application/json", "{\"status\":\"inactive\"}"); return; } static long prevD1 = 0, prevD2 = 0, prevD3 = 0; long d1 = filterDistance(readDistanceCM(TRIG1, ECHO1), prevD1); long d2 = filterDistance(readDistanceCM(TRIG2, ECHO2), prevD2); long d3 = filterDistance(readDistanceCM(TRIG3, ECHO3), prevD3); prevD1 = d1; prevD2 = d2; prevD3 = d3; if (d1 < 0 || d1 > 500) d1 = -1; if (d2 < 0 || d2 > 500) d2 = -1; if (d3 < 0 || d3 > 500) d3 = -1; String json = "{\"d1\":" + String(d1) + ",\"d2\":" + String(d2) + ",\"d3\":" + String(d3) + "}"; server.send(200, "application/json", json); } // レーダーON void handleRadarStart() { radarActive = true; server.send(200, "text/plain", "Radar ON"); } // レーダーOFF void handleRadarStop() { radarActive = false; server.send(200, "text/plain", "Radar OFF"); } // 車幅設定 void handleSetWidth() { if (server.hasArg("width")) { carWidth = server.arg("width").toInt(); carWidth = constrain(carWidth, 160, 200); } server.send(200, "text/plain", "幅: " + String(carWidth)); } void setup() { Serial.begin(115200); delay(1000); Serial.println("起動中..."); // SPIFFS if (!SPIFFS.begin(true)) { Serial.println("SPIFFSマウント失敗"); return; } // SPIFFS一覧 File root = SPIFFS.open("/"); File file = root.openNextFile(); while (file) { Serial.printf(" %s (%d バイト)\n", file.name(), file.size()); file = root.openNextFile(); } // 超音波初期化 pinMode(TRIG1, OUTPUT); pinMode(ECHO1, INPUT); pinMode(TRIG2, OUTPUT); pinMode(ECHO2, INPUT); pinMode(TRIG3, OUTPUT); pinMode(ECHO3, INPUT); digitalWrite(TRIG1, LOW); digitalWrite(TRIG2, LOW); digitalWrite(TRIG3, LOW); Serial.println("超音波センサー準備完了"); // WiFi WiFi.softAP(ssid, password); Serial.print("WiFi AP開始、IPアドレス: "); Serial.println(WiFi.softAPIP()); // ハンドラ登録 server.on("/", handleRoot); server.on("/index.html", handleRoot); server.on("/main.js", handleJS); server.on("/style.css", handleCSS); server.on("/distance", handleDistance); server.on("/radar/start", handleRadarStart); server.on("/radar/stop", handleRadarStop); server.on("/setwidth", handleSetWidth); server.onNotFound([]() { server.send(404, "text/plain", "未対応のURL"); }); server.begin(); Serial.println("HTTPサーバー起動完了"); } void loop() { server.handleClient(); }

jsファイル

#include #include #include #include // 超音波センサーのピン #define TRIG1 13 #define ECHO1 12 #define TRIG2 15 #define ECHO2 14 #define TRIG3 4 #define ECHO3 16 const char* ssid = "ESP32-Radar"; const char* password = "12345678"; WebServer server(80); bool radarActive = false; int carWidth = 180; // 超音波測定 long readDistanceCM(int trigPin, int echoPin) { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration = pulseIn(echoPin, HIGH, 30000); return duration * 0.0343 / 2; } long filterDistance(long current, long previous) { if (abs(current - previous) > 30) return previous; return current; } // レスポンス: index.html void handleRoot() { File file = SPIFFS.open("/index.html", "r"); if (!file) { server.send(500, "text/plain", "index.html not found"); return; } server.streamFile(file, "text/html"); file.close(); } // レスポンス: main.js void handleJS() { File file = SPIFFS.open("/main.js", "r"); if (!file) { server.send(404, "text/plain", "main.js not found"); return; } server.streamFile(file, "application/javascript"); file.close(); } // レスポンス: style.css void handleCSS() { File file = SPIFFS.open("/style.css", "r"); if (!file) { server.send(404, "text/plain", "style.css not found"); return; } server.streamFile(file, "text/css"); file.close(); } // レスポンス: 距離データ(JSON) void handleDistance() { if (!radarActive) { server.send(200, "application/json", "{\"status\":\"inactive\"}"); return; } static long prevD1 = 0, prevD2 = 0, prevD3 = 0; long d1 = filterDistance(readDistanceCM(TRIG1, ECHO1), prevD1); long d2 = filterDistance(readDistanceCM(TRIG2, ECHO2), prevD2); long d3 = filterDistance(readDistanceCM(TRIG3, ECHO3), prevD3); prevD1 = d1; prevD2 = d2; prevD3 = d3; if (d1 < 0 || d1 > 500) d1 = -1; if (d2 < 0 || d2 > 500) d2 = -1; if (d3 < 0 || d3 > 500) d3 = -1; String json = "{\"d1\":" + String(d1) + ",\"d2\":" + String(d2) + ",\"d3\":" + String(d3) + "}"; server.send(200, "application/json", json); } // レーダーON void handleRadarStart() { radarActive = true; server.send(200, "text/plain", "Radar ON"); } // レーダーOFF void handleRadarStop() { radarActive = false; server.send(200, "text/plain", "Radar OFF"); } // 車幅設定 void handleSetWidth() { if (server.hasArg("width")) { carWidth = server.arg("width").toInt(); carWidth = constrain(carWidth, 160, 200); } server.send(200, "text/plain", "幅: " + String(carWidth)); } void setup() { Serial.begin(115200); delay(1000); Serial.println("起動中..."); // SPIFFS if (!SPIFFS.begin(true)) { Serial.println("SPIFFSマウント失敗"); return; } // SPIFFS一覧 File root = SPIFFS.open("/"); File file = root.openNextFile(); while (file) { Serial.printf(" %s (%d バイト)\n", file.name(), file.size()); file = root.openNextFile(); } // 超音波初期化 pinMode(TRIG1, OUTPUT); pinMode(ECHO1, INPUT); pinMode(TRIG2, OUTPUT); pinMode(ECHO2, INPUT); pinMode(TRIG3, OUTPUT); pinMode(ECHO3, INPUT); digitalWrite(TRIG1, LOW); digitalWrite(TRIG2, LOW); digitalWrite(TRIG3, LOW); Serial.println("超音波センサー準備完了"); // WiFi WiFi.softAP(ssid, password); Serial.print("WiFi AP開始、IPアドレス: "); Serial.println(WiFi.softAPIP()); // ハンドラ登録 server.on("/", handleRoot); server.on("/index.html", handleRoot); server.on("/main.js", handleJS); server.on("/style.css", handleCSS); server.on("/distance", handleDistance); server.on("/radar/start", handleRadarStart); server.on("/radar/stop", handleRadarStop); server.on("/setwidth", handleSetWidth); server.onNotFound([]() { server.send(404, "text/plain", "未対応のURL"); }); server.begin(); Serial.println("HTTPサーバー起動完了"); } void loop() { server.handleClient(); }

iniファイル

[env:esp32cam] platform = espressif32 board = esp32cam framework = arduino monitor_speed = 115200 upload_speed = 115200 upload_port = COM4 lib_deps = bblanchon/ArduinoJson@^6.21.3 board_build.partitions = min_spiffs.csv board_upload.flash_size = 4MB board_upload.maximum_size = 4194304 board_build.filesystem = spiffs upload_protocol = esptool platform_packages = platformio/tool-mkspiffs@^2.230.0 monitor_filters = esp32_exception_decoder

htmlファイル

htmlファイル

cssファイル

body { background-color: #2c3e50; color: #ecf0f1; font-family: Arial, sans-serif; padding: 20px; margin: 0; } .container { max-width: 600px; margin: 0 auto; background-color: #34495e; border-radius: 10px; padding: 20px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); } h1 { text-align: center; color: #3498db; margin-bottom: 20px; } #systemStatus { background-color: #2c3e50; padding: 15px; border-radius: 8px; text-align: center; font-weight: bold; margin-bottom: 20px; } .sensor-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 20px; } .sensor { background-color: #27ae60; /* 安全距離:緑 */ border-radius: 8px; padding: 15px; text-align: center; transition: background-color 0.3s; } .sensor-label { font-weight: bold; margin-bottom: 5px; } .distance { font-size: 20px; font-weight: bold; } .control-panel { background-color: #2c3e50; border-radius: 8px; padding: 15px; } .form-group { margin-bottom: 15px; } label { display: block; margin-bottom: 5px; } select { width: 100%; padding: 10px; border-radius: 5px; border: none; background-color: #ecf0f1; font-size: 16px; } .button-group { display: flex; gap: 10px; } .btn { flex: 1; padding: 10px; border: none; border-radius: 5px; background-color: #3498db; color: white; font-size: 16px; cursor: pointer; } #stopBtn { background-color: #e74c3c; } /* 距離状態色分け */ .sensor-warning { background-color: #f39c12; /* 警告距離:橙 */ } .sensor-danger { background-color: #e74c3c; /* 危険距離:赤 */ } .sensor-safe { background-color: #27ae60; /* 通常距離:緑 */ } /* モバイル対応 */ @media (max-width: 600px) { .sensor-grid { grid-template-columns: 1fr; } .container { padding: 10px; } }

csvファイル

# Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x1F0000, spiffs, data, spiffs, 0x200000,0x1F0000,
戻る