Diesmal wieder etwas mit dem ESP32-CAM.
Die Möglichkeit mit dieser preisgünstigen Lösung auch Fotos aufzunehmen, soll diesmal genutzt werden, um sofort nach Erkennung einer Bewegung, das aufgenommene Bild direkt per Mail im Anhang zu verschicken.
Die Kombination aus einem ESP32-CAM-Modul und einem HC-SR501-Bewegungssensor bietet eine Vielzahl von Anwendungsmöglichkeiten.
Hier sind einige Beispiele:
- Wildtierüberwachung: Wenn Sie in einer Gegend mit viel Wildtieren leben, können Sie dieses Setup verwenden, um Fotos von Tieren in Ihrem Garten aufzunehmen. Sie könnten überrascht sein, welche Tiere nachts herumstreifen!
- Automatisierte Türklingel: Sie könnten dieses Setup an Ihrer Haustür installieren. Wenn jemand an der Tür steht, wird ein Foto aufgenommen und an Ihre E-Mail gesendet. So wissen Sie immer, wer vor Ihrer Tür steht, auch wenn Sie nicht zu Hause sind.
- Heimsicherheit: Sie können dieses Setup verwenden, um ein kostengünstiges Heimsicherheitssystem zu erstellen. Wenn eine Bewegung erkannt wird, nimmt das ESP32-CAM ein Foto auf und sendet es sofort an Ihre E-Mail. So können Sie sofort auf potenzielle Sicherheitsbedrohungen reagieren.
- Fotobox: Bei Party für spaßige Momentaufnahmen sorgen.
- Fotofalle: Oder einfach nur mal so aus Spaß, das nächtliche Naschen am Kühlschrank protokollieren.
Um mit einem ESP32-CAM eine Fotofalle zu bauen und die aufgenommenen Bilder automatisch per E-Mail zu versenden, benötigst du folgende Hard und Software:

Hardware:
ESP32-CAM mit Erweiterungsmodul
HC-SR501-Bewegungssensor
Kabel
USB Netzteil
Für meine Fotofalle kommt der ESP32-Cam zusätzlich einen Bewegungssensor, der signalisiert wenn sich etwas vor der Kamera bewegt. Da nehme ich wieder den passive Infrarotsensor HC-SR501. Er muss lediglich mit 5 Volt versorgt werden und wenn dieser in seinem Erfassungswinkel von bis zu 130° eine bewegende warme Quelle entdeckt, gibt er am dritten Pin eine 3,3 Volt HIGH aus von vor eingestellter Länge. Dieses Signal kann der Microcontroller auswerten, um die weiteren Schritte wie im Video zu sehen, einzuleiten.
Details zum ESP32-Cam hatte ich hier vorgestellt:
Zu installierende Library´s im Bibliotheksmanager:
Es ist völlig ausreichend im den Namen der Library einzutragen und zu suchen. Gefundene Bibliothek dann per Klick installieren. Ich bin da eher ungeduldig. Ich lass mir über die „überprüfen“ Option anzeigen was noch fehlt. Könnte ja schon vorhanden sein.
Wer sich tiefer einlesen möchte, hier die Links zu den Quellen:
ESP-Mail-Client (Versand per SMTP)
FS (LittleFS) (Dateiverwaltung)
WiFi (Funk)
esp32-camera (Fotoaufnahme)
spi (Vorinstalliert) (ermöglicht die Kommunikation per SPI)
rtc_io.h (Real TimeClock-Treiber, kommt mit der Board Library)
Verdrahtung:

3D Druck Gehäuse:
Mit TinkerCAD habe ich ein zweiteiliges Gehäuse erstellt. Beide STL-Dateien können hier bei Thingiverse herunter geladen werden. Für den 3D Druck lediglich mit eurem Slicer passend zu eurem Gerät in eine gcode-Datei umwandeln.
Gehäusegröße: 44x63x30mm
Jetzt auch hier bei Makerworld

Netzteil:
Bitte beachtet, dass für die Verwendung des ESP32-CAM-Moduls, eine stabile Stromversorgung benötigen wird. Andernfalls kann das Modul unerwartet neu starten oder sich aufhängen. Bei mir läuft diese Fotofalle mit einem USB-A – 5 Volt – 2A Netzteil Sorgenfrei.
Quellcode:
#include "esp_camera.h"
#include "SPI.h"
#include "driver/rtc_io.h"
#include <ESP_Mail_Client.h>
#include <FS.h>
#include <WiFi.h>
// Accesspoint einrichten
#define WIFI_SSID "euer SSID Name"
#define WIFI_PASSWORD "supersicheresPasswort"
// EMAIL Versand per SMTP
#define emailSenderAccount "deineMail@domain.de"
#define emailSenderPassword "supersicheresPasswort"
//#define smtpServer "smtp.gmail.com" // Für Google Mail
//#define smtpServer "smtp-mail.outlook.com" // Für Microsoft Mail
#define smtpServer "smtp.web.de" // Für web.de
// #define smtpServerPort 465 // Für Google Mail
#define smtpServerPort 587 // Für Microsoft Mail und web.de
#define emailSubject "Bewegung erkannt, hier das Beweisfoto"
#define emailRecipient "mustermann@web.de" // Wer soll die Mail empfangen
// ESP32-Cam Typ - sollte anderes Model vorliegen, ggf nachfolgende GPIO PIn anpassen
#define CAMERA_MODEL_AI_THINKER // Mit PSRAM
#if defined(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
#else
#error "Kamera Typ passt nicht"
#endif
// Funktion zum Abrufen des E-Mail-Versandstatus
SMTPSession smtp;
void smtpCallback(SMTP_Status status);
// Dateiname und Pfad der Aufnahme
#define FILE_PHOTO "foto.jpg"
#define FILE_PHOTO_PATH "/foto.jpg"
// Der Out-Pin, an den Ihr Bewegungssensor HC_SR501 angeschlossen ist
int hcsr501Pin = 12;
void setup() {
// Setzen Sie den Bewegungssensor-Pin als Eingang
pinMode(hcsr501Pin, INPUT);
Serial.begin(115200);
Serial.println();
// Connect to Wi-Fi
//WiFi.begin(ssid, password);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("WiFi Verbindungsaufbau...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(400);
}
Serial.println();
// Bei erfolgreichem AP-Login die erhaltene IP-Adresse zeigen
Serial.print("IP Addresse: http://");
Serial.println(WiFi.localIP());
// Auswahl Filesystem
ESP_MAIL_DEFAULT_FLASH_FS.begin();
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.grab_mode = CAMERA_GRAB_LATEST;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 1;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Initialisiere Cam
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
}
void loop() {
// Lesen Sie den Zustand des Bewegungssensors
int sensorState = digitalRead(hcsr501Pin);
// Wenn der Sensor eine Bewegung erkennt
if (sensorState == HIGH) {
Serial.println("Bewegung erkannt!");
capturePhoto();
sendPhoto();
delay(30000); //Warten bis wieder aktiv
} else {
Serial.println("Keine Bewegung erkannt.");
delay(1000);
}
}
// Foto aufnehmen und zwischen speichern
void capturePhoto() {
// Erste Bilder wegen eventl. noch nicht korrektem Weißabgleich überspringen
camera_fb_t* fb = NULL;
// Die ersten 3 Bilder überspringen - ggf anpassen
for (int i = 0; i < 3; i++) {
fb = esp_camera_fb_get();
esp_camera_fb_return(fb); // lösche Puffer
fb = NULL;
}
// Neues Foto aufnehmen
fb = NULL;
fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Kamera Aufnahme fehlgeschlagen");
delay(500);
ESP.restart();
}
// Foto Dateiname
Serial.printf("Foto Dateiname: %s\n", FILE_PHOTO_PATH);
File file = LittleFS.open(FILE_PHOTO_PATH, FILE_WRITE);
// Erstellung Fotodatei
if (!file) {
Serial.println("Fehler - kann Datei nicht schreibend offnen");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.print("The picture has been saved in ");
Serial.print(FILE_PHOTO_PATH);
Serial.print(" - Size: ");
Serial.print(fb->len);
Serial.println(" bytes");
}
file.close();
esp_camera_fb_return(fb);// lösche Puffer
}
void sendPhoto() { //Senden des Foto per Mail
smtp.debug(1); // Deaktivieren (0) oder Aktivieren (1) der Fehlersuche über die serielle Schnittstelle
// Abrufen des E-Mail-Versandstatus
smtp.callback(smtpCallback);
Session_Config config;
// Network Time Protocol (NTP) je nach Standort anpassen (https://en.wikipedia.org/wiki/Time_in_Germany)
config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
config.time.gmt_offset = 1; // GMT-Zeitverschiebung für Mitteleuropa im Winter
config.time.day_light_offset = 2; // Sommerzeitverschiebung
config.server.host_name = smtpServer;
config.server.port = smtpServerPort;
config.login.email = emailSenderAccount;
config.login.password = emailSenderPassword;
config.login.user_domain = "";
SMTP_Message message;
//Aktivieren Sie die chunked data transfer Datenübertragung um große Nachrichten über eine Leitung zuübertragen, sofern Server dies unterstützt
message.enable.chunking = true;
// Mail Absender und Betreff
message.sender.name = "Vogelhaus";
message.sender.email = emailSenderAccount;
message.subject = emailSubject;
message.addRecipient("DeinName", emailRecipient);
String htmlMsg = "<h2>Fotoaufnahme der ESP32-CAM von dem Vogelhaeuschen</h2>";
message.html.content = htmlMsg.c_str();
message.html.charSet = "utf-8";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp;
message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal;
message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
SMTP_Attachment att; // Mit Anhang
att.descr.filename = FILE_PHOTO;
att.descr.mime = "image/png";
att.file.path = FILE_PHOTO_PATH;
att.file.storage_type = esp_mail_file_storage_type_flash;
att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64;
// Foto als Anlage anfügen
message.addAttachment(att);
// Verbindungsaufbau und Senden - MailServer
if (!smtp.connect(&config))
return;
if (!MailClient.sendMail(&smtp, &message, true))
Serial.println("Fehler beim senden der Email, " + smtp.errorReason());
}
// Empfangsbestaetigung Email
void smtpCallback(SMTP_Status status){
Serial.println(status.info());
if (status.success())
{
Serial.println("----------------");
Serial.printf("Message sendet OK: %d\n", status.completedCount());
Serial.printf("Message sendet Fehler: %d\n", status.failedCount());
Serial.println("----------------\n");
struct tm dt;
for (size_t i = 0; i < smtp.sendingResult.size(); i++){
SMTP_Result result = smtp.sendingResult.getItem(i);
time_t ts = (time_t)result.timestamp;
localtime_r(&ts, &dt);
ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients.c_str());
ESP_MAIL_PRINTF("Subject: %s\n", result.subject.c_str());
}
Serial.println("----------------\n");
// Löschen des Sendeergebnis
smtp.sendingResult.clear();
}
}
Video:
Zusammenfassung des Video:
Der ESP32-Cam wird mit einem Infrarot-Bewegungsmelder versehen, um automatisch Fotos aufzunehmen und per E-Mail zu verschicken.
Die Verdrahtung und Programmierung des ESP32-Cam für die Funktion wird detailliert erläutert.
Die Funktionen zum Aufnehmen, Versenden und Löschen der Fotos wird erklärt und durchgeführt.
Die Vorbereitungen für den Upload des Programmcodes und die finale Testdurchführung wird demonstriert.
Hinweis: Das Beitragsbild wurde mit Microsoft Copilot erstellt.