前回記事↑の続編です。
デジカメもどきを作成したものの、1回1回SDカードを外すのがめんどうになってきました。SDカードの内容をブラウザで確認するようにしたものです。
ESP32-S3_WROOM CAM3部作になります。
-
ESP32-S3 WROOM CAMでデジカメを作る
GPIO0ボタン押下で静止画撮影、SDカードに保存。EdgeImpulseでのトレーニングデータ収集の為。 -
SDカード画像をブラウザで確認
SDカードの取り外しが面倒なため - 画像識別ST7789でバウンディングボックス
EdgeImpulseでの学習モデルを元に画像識別
2.SDカード画像をブラウザで確認
/////////////////// 全ての画像を映すVer ///////////
#include <WiFi.h>
#include <SD_MMC.h>
#include <WebServer.h>
// Wi-FiのSSIDとパスワードを設定
const char* ssid = "XXXXXXXXX"; // 接続するWiFiのSSID
const char* password = "XXXXXXXXX"; // 接続するWiFiのパスワード
// Webサーバーをポート80で作成
WebServer server(80);
// SDカード用のピン定義
#define SD_MMC_CMD 38
#define SD_MMC_CLK 39
#define SD_MMC_D0 40
// ファイルのマウントステータスを示す変数
bool sd_init = false;
// Webサーバーのルートにアクセスされたときの処理
void handleRoot() {
if (!sd_init) {
server.send(500, "text/plain", "SD Card not initialized");
return;
}
String html = "<html><body><h1>All Images</h1><div>";
// SDカードからファイルを取得して表示
File root = SD_MMC.open("/");
File file = root.openNextFile();
while (file) {
if (!file.isDirectory()) {
String fileName = String(file.name());
if (fileName.endsWith(".jpg") || fileName.endsWith(".png")) {
// URLエンコードした画像ファイルをHTMLに追加して表示
html += "<div style=\"margin-bottom:20px;\"><img src=\"/image?name=" + urlencode(fileName) + "\" style=\"max-width:300px; display:block;\"><p>" + fileName + "</p></div>";
}
}
file = root.openNextFile();
}
html += "</div></body></html>";
server.send(200, "text/html", html);
}
// 画像ファイルにアクセスされたときの処理
void handleImageRequest() {
if (!sd_init) {
server.send(500, "text/plain", "SD Card not initialized");
return;
}
String fileName = server.arg("name");
// パスの先頭にスラッシュを追加(必要に応じて)
if (!fileName.startsWith("/")) {
fileName = "/" + fileName;
}
// 確認用のデバッグ出力
Serial.print("Requested file: ");
Serial.println(fileName);
if (SD_MMC.exists(fileName.c_str())) {
File file = SD_MMC.open(fileName.c_str(), FILE_READ);
if (fileName.endsWith(".jpg")) {
server.streamFile(file, "image/jpeg");
} else if (fileName.endsWith(".png")) {
server.streamFile(file, "image/png");
}
file.close();
} else {
Serial.println("File not found");
server.send(404, "text/plain", "File not found");
}
}
// SDカードの初期化処理
void initSDCard() {
SD_MMC.setPins(SD_MMC_CLK, SD_MMC_CMD, SD_MMC_D0);
if (!SD_MMC.begin("/sdcard", true, true, SDMMC_FREQ_DEFAULT, 5)) {
Serial.println("Card Mount Failed");
sd_init = false;
} else {
Serial.println("SD Card Initialized");
sd_init = true;
}
}
// Wi-Fiの接続設定
void connectWiFi() {
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
// Wi-Fi接続完了まで待機
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
// URLエンコード関数
String urlencode(String str) {
String encodedString = "";
char c;
char code0;
char code1;
char code2;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (c == ' ') {
encodedString += '+';
} else if (isalnum(c)) {
encodedString += c;
} else {
code1 = (c & 0xf) + '0';
if ((c & 0xf) > 9) {
code1 = (c & 0xf) - 10 + 'A';
}
c = (c >> 4) & 0xf;
code0 = c + '0';
if (c > 9) {
code0 = c - 10 + 'A';
}
code2 = '\0';
encodedString += '%';
encodedString += code0;
encodedString += code1;
}
yield();
}
return encodedString;
}
// サーバーの初期化とエンドポイントの設定
void setup() {
Serial.begin(115200);
// Wi-Fi接続
connectWiFi();
// SDカードの初期化
initSDCard();
// Webサーバーのルートにアクセスしたときの処理
server.on("/", handleRoot);
// 画像ファイルにアクセスされたときの処理
server.on("/image", handleImageRequest);
// サーバーを開始
server.begin();
Serial.println("HTTP server started");
}
// メインループでWebサーバーを処理
void loop() {
server.handleClient();
}
結果
http://192.168.1.xxでブラウザで確認します
続編はこちら↓