Veröffentlicht: 03. Feb 2024
ESP32 Cam

ESP32 Cam + PlatformIO: Überwachungskamera mit Live Video Stream per Webserver

Von: René Aye
Jetzt neu

Meine eBooks

Melde dich am RAYDIY Newsletter an und du bekommst ein kostenloses eBook!

Zum RAYDIY Newsletter

ESP32 Cam Video Streaming in 20 Sekunden

Wie funktioniert Video Streaming mit der ESP32 Cam

  • Die ESP32 Cam ist ein ESP32 Mikrocontroller-Board mit einer eingebauten Kamera, die Fotos und Videos aufnehmen kann.
  • Um den Video Stream der ESP32 Cam in einem Browser darzustellen, wird ein vorhandenes WLAN benötigt
  • Ausserdem wird ein Webserver benötigt – diese Rolle wird auch die ESP32 Cam übernehmen
  • In diesem Code-Beispiel verwenden wir nur Bibliotheken, die Espressif bereits in seine Version des Arduino-Frameworks integriert hat – keine zusätzlichen 3rd-Party Bibliotheken werden benötigt
  • Die Stromversorgung kann über eine Powerbank gelöst werden, die direkt an 5V und Ground angeschlossen wird
ESP32 Cam OV2640 und SD Karten Slot
Das weit verbreitete ESP32 Cam Modell von Ai Thinker

Inhaltsverzeichnis

Das sind die Themen in diesem Artikel:


Ziel dieses Tutorials

ESP32 Cam Video Streaming

Beim letzten Mal haben wir uns angeschaut, wie man die ESP32 Cam mit PlatformIO und VS Code verbindet. Und wir haben ein erstes kleines "Hello World"-Projekt auf das Modul geladen, mit dem wir das Blitzlicht auf dem Board zum Blinken gebracht haben.

Jetzt wollen wir endlich die Kamera verwenden. Wir bauen uns eine kleine "Überwachungskamera" – wir streamen das Video-Live-Bild der Kamera auf eine lokale Webseite, die wir mit unserem Endgerät abrufen können.

Dafür ist folgendes zu tun:

  • die ESP32 Cam mit deinem WLAN verbinden
  • einen Webserver auf dem ESP32 Cam einrichten
  • eine lokale Webseite mit dem Live-Video-Stream der Kamera ausgeben

Vorraussetzungen für dieses Tutorial

Wenn du noch nie etwas mit der ESP32 Cam gemacht hast, schaue dir unbedingt die folgenden Artikel an, da die ESP32 Cam ein paar Besonderheiten hat und du die Grundlagen lernst, um Code mit PlatformIO + VS Code auf dein ESP32 Cam Board zu laden:

Weiterhin benötigst du ein WLAN in Reichweite, dessen Zugangsdaten du kennst. Denn deine ESP32 Cam muss sich ebenfalls am WLAN anmelden.


Der Code und dieses Tutorial beziehen sich auf das weit verbreitete ESP32 Cam Board von Ai-Thinker*.

Für andere Boards muss der Code entsprechend angepasst werden, da diese u.a. eine andere Pin-Belegung haben.

Unten im Artikel habe ich noch Pin-Belegungen anderer Boards rausgesucht.

ESP32 Cam + ESP32-CAM-MB Combo Pack*

XTVTX ESP32-CAM WiFi Bluetooth Board ESP32-CAM-MB Micro USB auf Serial Port mit OV2640 2MP Kameramodul Dual Mode kompatibel mit Arduino

Amazon Link*
* Bei dem Link handelt es sich um einen Affiliate Link. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen.

ESP32 Cam + WLAN

Wie verbinde ich meine ESP32 Cam mit dem WLAN?

Damit wir am Ende eine Webseite mit dem Kamera Live-Stream im Browser öffnen können, muss sich dein ESP32 Cam zunächst mal mit deinem WLAN verbinden.

Erstelle ein neues Projekt in PlatformIO für die ESP32 Cam. Wie das genau geht, habe ich bereits in diesem Artikel beschrieben.

Ich wähle in diesem Fall das AI Thinker ESP32-CAM Board aus. Und wir verwenden natürlich wieder das Arduino Framework.


ESP32 Cam Projekt einrichten

Nun öffne im Datei Explorer (1) die Datei main.cpp (2), die im Verzeichnis src liegt.

Image

Ersetze den Standard-Code des neuen Projekts mit diesem Programm:

#include <Arduino.h>
#include <WiFi.h>

// Replace with your network credentials
const char* ssid = "WLAN-SSID";
const char* password = "WLAN-PASSWORT";

void setup() {
  Serial.begin(9600);

  // Connect to Wi-Fi
  Serial.print("Connecting to WiFi ...");

 WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

  // Print ESP Local IP Address
  Serial.println(" connected!");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
}

void loop() {}

In den Zeilen 5+6 musst du noch den Namen (SSID) und das Passwort deines WLANs eintragen.

Lade den Code nun auf die ESP32 Cam. Verwende dazu am Besten Upload & Monitor. Klicke dazu auf das PlatformIO Icon (1) links im Menu, um das PlatformIO-Menu einzublenden, falls es nicht schon eingeblendet ist.

Unter Project Tasks werden alle deine Boards aufgelistet, in diesem Fall also nur unser esp23cam Board. Darunter findest du den Menu-Punkt Upload and Monitor (2).


PlatformIO Upload and Monitor
PlatformIO: Upload & Monitor

Was macht Upload and Monitor?

Upload and Monitor lädt dein Programm Code auf das angeschlossene Board und aktiviert direkt danach die Konsole im unteren Bereich von VS Code, um alle Log-Ausgaben, die z.B. mit Serial.print() ausgegeben werden, anzuzeigen.

Manchmal passiert es, dass man mehrere Konsolen geöffnet hat, die versuchen auf das gleiche Board zuzugreifen und dadurch ein Upload fehlschlägt oder Fehlermeldungen in der Konsole angezeigt werden. In dem Fall schließe einfach alle Konsolen mit dem Mülleimer-Icon wie im Bild zu sehen und probiere es erneut


PlaltformIO Konsole schließen
PlatformIO: Mehrere Konsolen schließen, wenn es Probleme beim Upload gibt

ESP32 Cam Reboot

ESP32 Cam neu starten

Starte nun das Board neu (Reboot). Ziehe dafür das Jumper-Kabel ab und drücke die Boot-Taste auf dem Board.

Falls du nicht weisst, wofür dieses Jumper-Kabel ist: im Artikel ESP32 Cam FTDI – So verkabelst du einen Mikrocontroller, wenn er keinen USB-Port besitzt habe ich es ausführlich beschrieben.


Image
Jumper-Kabel um die ESP32 Cam zu programmieren

In der Konsole sollten wir nun sehen, ob sich das Modul mit deinem WLAN verbindet. Wenn ja, sollte die entsprechende Meldung ausgegeben werden.

Außerdem wird angezeigt, welche IP-Adresse dein ESP32 Cam von deinem Router zugewiesen wurde. Da ist wichtig, da wir diese IP-Adresse später noch benötigen – das ist die Adresse, unter der wir die Webseite mit dem Live Video-Stream aufrufen können.


ESP32 Cam mit WLAN verbunden
ESP32 Cam ist mit dem WLAN verbunden

ESP32 Cam + Webserver

WebServer auf ESP32 Cam einrichten

Wir sind nun mit dem WLAN verbunden. Nun benötigen wir noch einen Webserver, der uns eine Webseite liefert auf der wir dann das Video-Bild sehen können.

Espressif hat in ihrer Version des Arduino-Frameworks ein paar Bibliotheken eingebaut, die wir nun benötigen. Das sind u.a.  esp_camera und esp_http_server Bibliothek.

esp_camera liefert uns Funktionen, um das Kamerabild zu erfassen. Und mit esp_http_server können wir einen Webserver erstellen um eine Webseite zu servieren, auf der z.B. unser Video-Stream zu sehen ist.

Ich habe die üblichen Beispiele im Netz angeschaut und alles was wir nicht benötigen entfernt. Von daher ist dies so ziemlich das minimalste Beispiel für einen Video-Stream-Server mit der ESP32 Cam.

Hier der finale Code:

#include "Arduino.h"
#include <WiFi.h>
#include "esp_camera.h"
#include "esp_http_server.h"

const char *ssid = "WLAN-SSID";
const char *password = "WLAN-PASSWORD";


#define PART_BOUNDARY "123456789000000000000987654321"
static const char *_STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char *_STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char *_STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\nX-Timestamp: %d.%06d\r\n\r\n";

httpd_handle_t stream_httpd = NULL;

static esp_err_t stream_handler(httpd_req_t *req)
{
    camera_fb_t *fb = NULL;
    struct timeval _timestamp;
    esp_err_t res = ESP_OK;
    size_t _jpg_buf_len = 0;
    uint8_t *_jpg_buf = NULL;
    char *part_buf[128];

    static int64_t last_frame = 0;
    if (!last_frame)
    {
        last_frame = esp_timer_get_time();
    }

    res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
    if (res != ESP_OK)
    {
        return res;
    }

    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "X-Framerate", "60");

    while (true)
    {
        fb = esp_camera_fb_get();
        if (!fb)
        {
            Serial.println("Camera capture failed");
            res = ESP_FAIL;
        }
        else
        {
            _timestamp.tv_sec = fb->timestamp.tv_sec;
            _timestamp.tv_usec = fb->timestamp.tv_usec;
            if (fb->format != PIXFORMAT_JPEG)
            {
                bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
                esp_camera_fb_return(fb);
                fb = NULL;
                if (!jpeg_converted)
                {
                    Serial.println("JPEG compression failed");
                    res = ESP_FAIL;
                }
            }
            else
            {
                _jpg_buf_len = fb->len;
                _jpg_buf = fb->buf;
            }
        }

        if (res == ESP_OK)
        {
            res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
        }
        if (res == ESP_OK)
        {
            size_t hlen = snprintf((char *)part_buf, 128, _STREAM_PART, _jpg_buf_len, _timestamp.tv_sec, _timestamp.tv_usec);
            res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
        }
        if (res == ESP_OK)
        {
            res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
        }
        if (fb)
        {
            esp_camera_fb_return(fb);
            fb = NULL;
            _jpg_buf = NULL;
        }
        else if (_jpg_buf)
        {
            free(_jpg_buf);
            _jpg_buf = NULL;
        }
        if (res != ESP_OK)
        {
            Serial.println("Send frame failed");
            break;
        }

        int64_t fr_end = esp_timer_get_time();
        int64_t frame_time = fr_end - last_frame;
        frame_time /= 1000;
    }

    return res;
}

void startCameraServer()
{
    Serial.println("startCameraServer()");

    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    config.server_port = 80;

    httpd_uri_t index_uri = {
        .uri = "/",
        .method = HTTP_GET,
        .handler = stream_handler,
        .user_ctx = NULL};

    Serial.printf("Starting stream server on port: '%d'", config.server_port);
    if (httpd_start(&stream_httpd, &config) == ESP_OK)
    {
        httpd_register_uri_handler(stream_httpd, &index_uri);
    }
}



////////////////////////////// SETUP()
void setup()
{
    Serial.begin(9600);
    Serial.println();

    // #define CAMERA_MODEL_AI_THINKER // Has PSRAM
    camera_config_t config;
    config.ledc_channel = LEDC_CHANNEL_0;
    config.ledc_timer = LEDC_TIMER_0;
    config.pin_d0 = 5; //Y2_GPIO_NUM
    config.pin_d1 = 18; //Y3_GPIO_NUM
    config.pin_d2 = 19; //Y4_GPIO_NUM
    config.pin_d3 = 21; //Y5_GPIO_NUM
    config.pin_d4 = 36; //Y6_GPIO_NUM
    config.pin_d5 = 39; //Y7_GPIO_NUM
    config.pin_d6 = 34; //Y8_GPIO_NUM
    config.pin_d7 = 35; //Y9_GPIO_NUM
    config.pin_xclk = 0; //XCLK_GPIO_NUM
    config.pin_pclk = 22; //PCLK_GPIO_NUM
    config.pin_vsync = 25; //VSYNC_GPIO_NUM
    config.pin_href = 23; //HREF_GPIO_NUM
    config.pin_sscb_sda = 26; //SIOD_GPIO_NUM
    config.pin_sscb_scl = 27; //SIOC_GPIO_NUM
    config.pin_pwdn = 32; //PWDN_GPIO_NUM
    config.pin_reset = -1; //RESET_GPIO_NUM
    config.xclk_freq_hz = 20000000;
    config.frame_size = FRAMESIZE_UXGA;
    config.pixel_format = PIXFORMAT_JPEG; // for streaming
    config.grab_mode = CAMERA_GRAB_LATEST;
    config.fb_location = CAMERA_FB_IN_PSRAM;
    config.jpeg_quality = 12;
    config.fb_count = 1;

    if(psramFound()){
      config.frame_size = FRAMESIZE_UXGA; // 1600x1200
      config.jpeg_quality = 10;
      config.fb_count = 2;
    } else {
      config.frame_size = FRAMESIZE_SVGA; // 800x600
      config.jpeg_quality = 12;
      config.fb_count = 1;
    }

    // camera init
    esp_err_t err = esp_camera_init(&config);
    if (err != ESP_OK)
    {
        Serial.printf("Camera init failed with error 0x%x", err);
        return;
    }

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
        Serial.print(".");
    }
    Serial.println(" connected!");
    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());

    /* Start the camera streaming server */
    startCameraServer();
}

////////////////////////////// LOOP()
void loop() {}

In Zeilen 6+7 müsst ihr natürlich wieder eure WLAN Zugangsdaten eingeben.

Die Zeilen 10–13 sind ein paar Strings, die für das HTTP-Protokoll benötigt werden.

Die stream_handler() Funktion ab Zeile 17  hat es in sich – das ist schon sehr fortgeschritten und ganz ehrlich ... das Meiste davon verstehe ich nicht. Dafür müsste man sich zum Einen tiefer mit dem inneren Code des Frameworks auseinandersetzen und zum Anderen auch mit Streaming allgemein und das HTTP-Protokoll genau verstehen. Das müssen wir einfach so hinnehmen.

In startCameraServer() ab Zeile 109 ist der übliche Code, um einen Webserver zu konfigurieren. Hier wird gesagt, dass der Webserver auf dem Port 80 erreichbar sein soll (also der Standardport im Browser, wenn kein Port angegeben werden muss). Und wir sagen, wenn root (also "/" bzw. nur die IP-Adresse ohne "/") im Browser aufgerufen wird, dann liefere das Ergebnis der Funktion stream_handler() zurück – in diesem Fall also den Video-Stream der ESP32 Kamera.

In der setup() Methode wird zunächst ab Zeile 138 die Kamera konfiguriert. Wenn du ein anderes ESP32-Cam-Board als das von Ai-Thinker verwenden willst, musst du hier entsprechende Anpassungen machen. Ich habe unten ein paar Settings für andere Modelle notiert, die ich im Netz gefunden habe.

Ab Zeile 165 wird noch geprüft, ob das ESP32 Cam Board zusätzlichen PSRAM hat. Falls ja, wird die Auflösung auf UXGA (1600x1200) gestellt.

Ab Zeile 176 wird geprüft, ob die Kamera initialisiert werden konnte.

Ab Zeile 183 verbinden wir uns wieder mit dem WLAN.

Und am Ende in Zeile 193 starten wir schließlich den Webserver.

Andere ESP32 Cam Modelle

Pin-Belegung verschiedener ESP32-Cam Board-Modelle

Hier habe ich die Pin-Belegung anderer ESP32 Cam Modelle herausgesucht. Falls du ein solches Board besitzt, musst die Pins und Einstellungen entsprechend anpassen.

// ===================
// Camera models
// ===================
//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
//#define CAMERA_MODEL_ESP_EYE // Has PSRAM
//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM
//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM
//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM
//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM
//#define CAMERA_MODEL_AI_THINKER // Has PSRAM
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM
//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM


//
// AI Thinker
// https://github.com/SeeedDocument/forum_doc/raw/master/reg/ESP32_CAM_V1.6.pdf
//
#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
#define FLASHLIGHT_PIN     4 // LED Flashlight

//
// ESP WROVER
// https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-2.pdf
//
#define PWDN_GPIO_NUM    -1
#define RESET_GPIO_NUM   -1
#define XCLK_GPIO_NUM    21
#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      19
#define Y4_GPIO_NUM      18
#define Y3_GPIO_NUM       5
#define Y2_GPIO_NUM       4
#define VSYNC_GPIO_NUM   25
#define HREF_GPIO_NUM    23
#define PCLK_GPIO_NUM    22


//
// ESP-EYE
// https://twitter.com/esp32net/status/1085488403460882437
#define PWDN_GPIO_NUM    -1
#define RESET_GPIO_NUM   -1
#define XCLK_GPIO_NUM     4
#define SIOD_GPIO_NUM    18
#define SIOC_GPIO_NUM    23
#define Y9_GPIO_NUM      36
#define Y8_GPIO_NUM      37
#define Y7_GPIO_NUM      38
#define Y6_GPIO_NUM      39
#define Y5_GPIO_NUM      35
#define Y4_GPIO_NUM      14
#define Y3_GPIO_NUM      13
#define Y2_GPIO_NUM      34
#define VSYNC_GPIO_NUM    5
#define HREF_GPIO_NUM    27
#define PCLK_GPIO_NUM    25
#define FLASHLIGHT_PIN   22 // LED Flashlight
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);

//
// ESP32 M5STACK
//
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    15
#define XCLK_GPIO_NUM     27
#define SIOD_GPIO_NUM     25
#define SIOC_GPIO_NUM     23
#define Y9_GPIO_NUM       19
#define Y8_GPIO_NUM       36
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       39
#define Y5_GPIO_NUM        5
#define Y4_GPIO_NUM       34
#define Y3_GPIO_NUM       35
#define Y2_GPIO_NUM       32
#define VSYNC_GPIO_NUM    22
#define HREF_GPIO_NUM     26
#define PCLK_GPIO_NUM     21

//
// ESP32 M5STACK V2
//
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    15
#define XCLK_GPIO_NUM     27
#define SIOD_GPIO_NUM     22
#define SIOC_GPIO_NUM     23
#define Y9_GPIO_NUM       19
#define Y8_GPIO_NUM       36
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       39
#define Y5_GPIO_NUM        5
#define Y4_GPIO_NUM       34
#define Y3_GPIO_NUM       35
#define Y2_GPIO_NUM       32
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     26
#define PCLK_GPIO_NUM     21

//
// ESP32 M5STACK WIDE
//
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    15
#define XCLK_GPIO_NUM     27
#define SIOD_GPIO_NUM     22
#define SIOC_GPIO_NUM     23
#define Y9_GPIO_NUM       19
#define Y8_GPIO_NUM       36
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       39
#define Y5_GPIO_NUM        5
#define Y4_GPIO_NUM       34
#define Y3_GPIO_NUM       35
#define Y2_GPIO_NUM       32
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     26
#define PCLK_GPIO_NUM     21
#define FLASHLIGHT_PIN     2 // LED Flashlight

//
// M5STACK UNITCAM
//
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    15
#define XCLK_GPIO_NUM     27
#define SIOD_GPIO_NUM     25
#define SIOC_GPIO_NUM     23
#define Y9_GPIO_NUM       19
#define Y8_GPIO_NUM       36
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       39
#define Y5_GPIO_NUM        5
#define Y4_GPIO_NUM       34
#define Y3_GPIO_NUM       35
#define Y2_GPIO_NUM       32
#define VSYNC_GPIO_NUM    22
#define HREF_GPIO_NUM     26
#define PCLK_GPIO_NUM     21

//
// Common M5STACK ESP32 Cam
//
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    15
#define XCLK_GPIO_NUM     27
#define SIOD_GPIO_NUM     25
#define SIOC_GPIO_NUM     23
#define Y9_GPIO_NUM       19
#define Y8_GPIO_NUM       36
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       39
#define Y5_GPIO_NUM        5
#define Y4_GPIO_NUM       34
#define Y3_GPIO_NUM       35
#define Y2_GPIO_NUM       17
#define VSYNC_GPIO_NUM    22
#define HREF_GPIO_NUM     26
#define PCLK_GPIO_NUM     21

//
// LilyGO TTGO T-Journal 
//
#define PWDN_GPIO_NUM      0
#define RESET_GPIO_NUM    15
#define XCLK_GPIO_NUM     27
#define SIOD_GPIO_NUM     25
#define SIOC_GPIO_NUM     23
#define Y9_GPIO_NUM       19
#define Y8_GPIO_NUM       36
#define Y7_GPIO_NUM       18
#define Y6_GPIO_NUM       39
#define Y5_GPIO_NUM        5
#define Y4_GPIO_NUM       34
#define Y3_GPIO_NUM       35
#define Y2_GPIO_NUM       17
#define VSYNC_GPIO_NUM    22
#define HREF_GPIO_NUM     26
#define PCLK_GPIO_NUM     21

//
// XIAO ESP32S3
//
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM     10
#define SIOD_GPIO_NUM     40
#define SIOC_GPIO_NUM     39
#define Y9_GPIO_NUM       48
#define Y8_GPIO_NUM       11
#define Y7_GPIO_NUM       12
#define Y6_GPIO_NUM       14
#define Y5_GPIO_NUM       16
#define Y4_GPIO_NUM       18
#define Y3_GPIO_NUM       17
#define Y2_GPIO_NUM       15
#define VSYNC_GPIO_NUM    38
#define HREF_GPIO_NUM     47
#define PCLK_GPIO_NUM     13

//
// ESP32S3 EYE
//
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 4
#define SIOC_GPIO_NUM 5
#define Y2_GPIO_NUM 11
#define Y3_GPIO_NUM 9
#define Y4_GPIO_NUM 8
#define Y5_GPIO_NUM 10
#define Y6_GPIO_NUM 12
#define Y7_GPIO_NUM 18
#define Y8_GPIO_NUM 17
#define Y9_GPIO_NUM 16
#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM 7
#define PCLK_GPIO_NUM 13

//
// DFRobot FireBeetel2 ESP32S3
// DFRobot Romeo ESP32S3
//
#define PWDN_GPIO_NUM     -1
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM     45
#define SIOD_GPIO_NUM     1
#define SIOC_GPIO_NUM     2
#define Y9_GPIO_NUM       48
#define Y8_GPIO_NUM       46
#define Y7_GPIO_NUM       8
#define Y6_GPIO_NUM       7
#define Y5_GPIO_NUM       4
#define Y4_GPIO_NUM       41
#define Y3_GPIO_NUM       40
#define Y2_GPIO_NUM       39
#define VSYNC_GPIO_NUM    6
#define HREF_GPIO_NUM     42
#define PCLK_GPIO_NUM     5

Stromversorgung

Stromversorgung der ESP32 Cam

Um die Kamera autark mit Strom zu versorgen verwende ich eine Powerbank. Da die ESP32 Cam allerdings keinen USB-Port hat, den wir für die Stromversorgung verwenden können, müssen wir den Strom über den 5V und den GND Pin liefern.

Dazu benötigst du ein USB-Kabel, das du selbst herstellen kannst. Nimm ein USB Kabel, das du opfern möchtest. Prüfe, ob du es an deiner Powerbank anschließen kannst. Den anderen Stecker, der nicht an der Powerbank angeschlossen wird, schneidest du ab. In der Regel sind die stromführenden Leitungen rot (5 Volt) und schwarz (Ground). Prüfe das aber nochmal mit dem Messgerät nach, da es auch Hersteller gibt, die es mit den Farben nicht so genau nehmen.

Entferne die Isolierung so, dass du an die 5 Volt und die Ground Leitung herankommst. Sollte Dein USB Kabel noch mehr Leitungen für den USB-Datentransfer besitzen, kannst du diese einfach abschneiden, die benötigen wir nicht.

ESP32 Cam USB Kabel Stromversorgung
Fertiges Kabel – nicht wundern: ich habe an der 5 Volt Leitung zwei verschiedene Stecker angelötet
ESP32 Cam Stromversorgung
ESP32 Cam mit Stromversorgung – so kann die "Überwachungskamera" überall autark aufgestellt werden

Wenn dein USB-Kabel nur zwei Leitungen besitzt, ist dieses Kabel eh nicht für den Datentransfer zu gebrauchen. Dann ist es ein reines Strom-Ladekabel – als im Grunde genau das, was wir benötigen.

Am besten crimpst du an die 5 Volt und an die Ground Leitung einen Dupont Stecker. Dann kannst du die Stromversorgung einfach stecken, falls an deiner ESP32 Cam die Steckerleisten drangelötet sind. Falls du selber crimpen möchtest: in diesem Artikel zeige ich dir, wie du selbst Stecker crimpen kannst.

Zusammenfassung

Du hast gesehen, wie wir zuerst die ESP32 Cam mit deinem WLAN verbunden haben. Das ist im übrigen beim ESP32 (ohne Cam) genau der gleiche Vorgang.

Anschließend haben wir den Code erweitert und eine WebServer hinzugefügt, der den live Video-Kamera-Stream über einen WebServer ausliefert.

Und am Ende haben wir uns noch eine Möglichkeit angeschaut, wie man unsere Überwachungskamera mit einer Powerbank autark betreiben kann.

Es ist schon grandios (und erschreckend), dass mit wenig Aufwand ein Video-Überwachungssystem gebaut werden kann.

Übrigens: wenn du an neuen Artikeln, Tutorials und Projekten auf meiner Seite interessiert bist, melde dich gerne an meinem Newsletter an – dann bekommst du eine E-Mail sobald ich einen neuen Schwung Artikel veröffentlicht habe.