
この記事は、ESP32 CAMモジュール、FTDIプログラマ、PIRセンサーで構成されています。ESP32 CAMは画像をキャプチャし、WiFi経由で送信するために使用されます。FTDIプログラマはESP32 CAMのプログラミングに使用され、PIRセンサーは動き検出に使用されます。ESP32 CAMは、動きを検知すると画像をキャプチャし、分析のためにサーバーに送信するようにプログラムされています。
コンポーネントリスト
ESP32 CAM
- 説明 : カメラモジュールを統合したマイクロコントローラ。
- ピン : 5V、GND、GPIO12、GPIO13、GPIO15、GPIO14、GPIO2、GPIO4、3.3V、GPIO16、GPIO0、3.3V / 5V / P_OUT、GPIO3 / RX、GPIO1 / TX
FTDI PROGRAMMER
- 説明 : ESP32 CAM のプログラミングに使用される USB-シリアル アダプター。
- ピン : DTR、RX、TX、VCC、CTS、GND
PIRセンサー
- 説明 : 動きを検出するために使用されるセンサー。
- ピン : VDD、SIG、GND
配線の詳細
ESP32 CAM
- 5V : FTDIプログラマVCCに接続
- GND : FTDIプログラマGNDとPIRセンサーGNDに接続
- GPIO13 : PIRセンサーSIGに接続
- 3.3V / 5V / P_OUT : PIRセンサーVDDに接続
- GPIO3 / RX : FTDIプログラマTXに接続
- GPIO1 / TX : FTDIプログラマRXに接続
FTDI PROGRAMMER
- VCC : ESP32 CAM 5Vに接続
- GND : ESP32 CAM GNDに接続
- TX : ESP32 CAM GPIO3 / RXに接続
- RX : ESP32 CAM GPIO1 / TXに接続
PIRセンサー
- VDD : ESP32 CAM 3.3V / 5V / P_OUTに接続
- SIG : ESP32 CAM GPIO13に接続
- GND : ESP32 CAM GNDに接続
コード
ESP32 CAMのコードはArduinoで記述されており、WiFi、HTTP、カメラ制御、WebSocket用のライブラリが含まれています。主な機能は、カメラとWiFiの初期化、PIRセンサーによる動きの検知、画像のキャプチャ、そして分析用サーバーへの送信です。
初期化処理
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <esp_camera.h>
#include <base64.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <WebSocketsClient.h>
// WiFi Configuration
#define WIFI_SSID "Gagan A Ayi"
#define WIFI_PASSWORD "29842984"
#define WEBSOCKET_SERVER "ws://localhost:12345"
#define SERVER_URL "http://localhost/fras/api"
// ESP32-CAM Pin Configuration
#define CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// Sensor Configurations
#define PIR_SENSOR_PIN 13
#define LED_INDICATOR_PIN 4
// System Configuration
#define CONFIDENCE_THRESHOLD 0.7
#define NO_MOTION_TIMEOUT 5000 // 5 seconds to confirm no motion
// Global Variables
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");
WebSocketsClient webSocket;
String currentClassroom = "";
String currentSubject = "";
String assignedTeacher = "";
unsigned long lastMotionTime = 0;
bool isCameraActive = false;
関数プロトタイプ
bool initializeCamera();
bool initializeWiFi();
void captureAndSendFrame();
bool noHumansInFrame();
void syncClassroomContext();
セットアップ機能
void setup() {
Serial.begin(115200);
// Initialize Pins
pinMode(PIR_SENSOR_PIN, INPUT);
pinMode(LED_INDICATOR_PIN, OUTPUT);
// Initialize Components
if (!initializeCamera()) {
Serial.println("Camera initialization failed!");
return;
}
if (!initializeWiFi()) {
Serial.println("WiFi connection failed!");
return;
}
// Initialize Time Client
timeClient.begin();
timeClient.setTimeOffset(19800); // Indian Standard Time
// Initialize WebSocket
String host = "localhost";
uint16_t port = 12345;
String url = "/";
String protocol = "arduino";
webSocket.begin(host, port, url, protocol);
}
ループ機能
void loop() {
// Periodically sync classroom context
static unsigned long lastContextSync = 0;
if (millis() - lastContextSync > 300000) { // Every 5 minutes
syncClassroomContext();
lastContextSync = millis();
}
// Motion Detection
if (!isCameraActive && digitalRead(PIR_SENSOR_PIN) == HIGH) {
// Turn on the camera and LED indicator
lastMotionTime = millis();
digitalWrite(LED_INDICATOR_PIN, HIGH);
isCameraActive = true;
captureAndSendFrame();
}
// Check for turning off the camera and LED indicator
if (isCameraActive && millis() - lastMotionTime > NO_MOTION_TIMEOUT) {
if (noHumansInFrame()) {
digitalWrite(LED_INDICATOR_PIN, LOW);
isCameraActive = false;
Serial.println("No humans detected, turning off camera and LED");
} else {
lastMotionTime = millis(); // Reset the timer if a human is detected
}
}
webSocket.loop();
}
カメラ機能の初期化
bool initializeCamera() {
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 10;
config.fb_count = 2;
return esp_camera_init(&config) == ESP_OK;
}
WiFi機能の初期化
bool initializeWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
return WiFi.status() == WL_CONNECTED;
}
フレームキャプチャおよび送信機能
void captureAndSendFrame() {
camera_fb_t* fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return;
}
// Base64 encode image
String encodedImage = base64::encode(fb->buf, fb->len);
// Send to server
webSocket.sendTXT(encodedImage);
esp_camera_fb_return(fb);
}
フレーム機能に人間がいない場合の処理
bool noHumansInFrame() {
camera_fb_t* fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return false;
}
// Base64 encode image
String encodedImage = base64::encode(fb->buf, fb->len);
esp_camera_fb_return(fb);
// Send to server for analysis
HTTPClient http;
http.begin(SERVER_URL + String("/analyze"));
http.addHeader("Content-Type", "application/json");
DynamicJsonDocument payload(512);
payload["image"] = encodedImage;
以上