Die ESP32-Cam als WLAN-IP-Kamera anschließen, einrichten und konfigurieren
Eine Lösung für eine WLAN-IP-Kamera hatte ich euch in meinem Artikel Raspberry Pi und RaspiCam zur Videoüberwachung nutzen mit MotionEyeOs ja schon vorgestellt. Das klappt ja auch alles ganz toll mit dem Raspberry Pi und kostete zu normalen Zeiten auch "nur" 40 Euro, aber das Problem ist, dass momentan für Raspberry Pis wahre Mondpreise aufgerufen werden.Auf einem meiner Streifzüge durch die chinesische Elektronik-Welt auf eBay, AliExpress, amazon und Co. bin ich dann allerdings auf eine günstigere Option gestoßen, die ESP32-Cam, oder vollständig das "ESP32-CAM Development Board mit OV2640 Kameramodul".
Der Hammer dabei ist der Preis. Ein komplettes Modul inklusive Kamera kostet aus China um die 6 Euro inklusive Versand und auch aus Deutschland kriegt man die Teile inzwischen schon für 9 Euro plus Versand. Aus China bestellen lohnt deshalb nicht mehr groß.
Damit reiht sich die ESP32 Cam als weiteres spezialisiertes Board in meine Sammlung von ESP32-Boards ein.
Die Features
Wahnsinn, was man alles fürs Geld bekommt:
- ESP32 Board mit ESP32-S Modul
- Kameramodul OV2640 mit 2 Megapixel
- Kameramodulanschluss auf dem Board
- Micro-SD-Kartenleser on Board
- Print-WLAN-Antenne auf der Platine
- Antennenanschluss für externe WLAN-Antenne
- leistungsfähige Blitz-LED zur Ausleuchtung
WLAN, Bluetooth, alles wie von einem ESP32 gewohnt.
Zusammenbau der Hardware
Das ESP32-Cam Board muss noch zusammengebaut werden, bevor wir es weiter benutzen können.
Bei mir waren die Zusammenpacker so "intelligent", den Kameralinsen-Schutzaufkleber nicht über die Kameralinse zu kleben, sondern auf das Flachbandkabel der Kamera. Da muss es selbstverständlich vor dem Anschließen entfernt werden, sonst passt es nicht in die vorgesehene Buchse.
Auf dem Board gibt es auf der Seite, auf der auch der silberne, große Micro-SD-Karten-Einschub ist, einen beigen Anschluss für das Flachbandkabel. Der wird geöffnet, indem man ihn um 90 Grad nach oben klappt. Bitte vorsichtig sein, damit nichts abbricht, das Teil ist empfindlich!
Dann das Flexkabel mit den goldenen Kontakten nach unten tief in die Buchse einführen und dann langsam den schwarzen Verschluss nach unten drücken und einschnappen lassen. Das Flachbandkabel ist jetzt eingeklemmt und hält fest.
Nun noch die Schutzfolie vom Aufkleber auf der Rückseite der Cam abziehen und die Cam möglichst gerade auf das silbernen Micro-SD-Karten-Slot-Gehäuse kleben und zwar so, dass kein Zug auf dem Kabel ist, es also weder gestaucht und gezogen wird.
Dann nur noch den Schutzaufkleber von der Kamera entfernen und am besten irgendwo auf die Platine kleben, wo frei ist, falls man den doch noch einmal brauchen sollte.
Pinout ESP32-Cam
Wenn wir uns die ESP32-Cam-Platine so anschauen, fallen uns zwei Dinge auf: Erstens die große LED rechts nebem dem Flachbandkabelanschluss. Die ist an Pin IO4 angeschlossen und die hat ordentlich Power, so dass man damit auch etwas ausleuchten kann, zum Beispiel, wenn man innerhalb eines Nistkastens alle Stunde ein Foto schießen will. Wegen der Stromaufnahme und auch wegen der armen Vögel im Beispiel die LED immer nur kurz anmachen. Also: LED an, Foto machen, LED wieder aus.Und zweitens: Wo ist denn nur der gewohnte USB-Port zum Anschluss an den PC? Kurze Antwort: es gibt keinen. Lange Antwort: Wir müssen die ESP32 Cam über den seriellen Port (UART) programmieren. Wie das geht, steht weiter unten.
Schauen wir uns das Pinout einmal an: auf der linken Seite (siehe Grafik rechts) haben wir 5 Volt und Ground. Die restlichen Pins auf dieser Seite sind bereits für die Ansteuerung der SD-Karte belegt. Wollen wir die Micro-SD-Karte benutzen, um zum Beispiel Bilder zu speichern, dann sollten wir diese nicht für eigene Zwecke benutzen. Braucht man den SD-Karten-Slot nicht, spricht nichts dagegen.
Auf der rechten Seite haben wir 3.3 Volt und nochmal Ground. IO 0 ist reserviert für den Programmiermodus. Wenn dieser Pin mit GND verbunden wird, dann geht der ESP32 in den Programmiermodus und man ein neues Programm aufspielen / flashen. Zieht man das Kabel dann wieder ab, ist die MCU im Run-Modus und das aufgespielte Programm wird gestartet.
VCC ist zur externen Spannungsversorgung. Dieser Pin geht zu den Jumpern, die klein mit 5V und 3V3 auf der Platine beschriftet sind. Hier kann man jumpern, wieviel Volt die angelegte Versorgungsspannung hat, indem man den 0 Ohm-Widerstand ggf. umlötet. Bei mir war die Konfiguration auf 3.3V. Legt hier also bitte keine 5 Volt an. Nehmt dafür lieber den 5V-Pin oben links.
Als letztes wäre da noch die Pins IO 3 und IO 1. Hier ist der UART-Bus herausgeführt, also die serielle Schnittstelle. Und hierüber werden wir auch den ESP32 Cam neu programmieren und den Serail Monitor abfragen.
Anschließen an den PC via seriellem Adapter
Um mit der ESP32 Cam über die serielle Schnittstelle sprechen zu können, brauchen wir einen Adapter für den USB-Port. Diese Adapter heißen FTDI-Adapter nach dem bekannstesten Hersteller des seriellen Chips auf der Platine im Adapter. Es gibt aber auch andere Chips wie den CH340, der in meinem seriellen Adapter verbaut ist.
Da steht bei meinem jetzt "STC Auto Programmer USB-TTL" drauf, aber drin ist eigentlich immer das gleiche: Ein serieller Chip, ggf. Spannungswandler auf 5V und 3.3V, ein USB-Port für den PC und zwei serielle Leitungen zum Anschluss an das zu programmierende Board. Das funktioniert mit den allermeisten Microcontrollern so, auch für die von STC. Ich mag meinen Adapter, weil der ein chices blaues Metallgehäuse hat und praktische Ausgangspins, auf das man einfach Jumper-Kabel (female/female) stecken kann.
RXD steht für Read Data, also Lesen. TXD steht für Transmit Data, also schreiben. Was der Adapter schreibt (TXD) muss der ESP32 Cam lesen (RXD), also kommt das RXD-Kabel vom Adapter ans TXD-Kabel vom ESP32 und umgekehrt. Dann muss noch GND und die Stromversorgung verbunden werden. Ich nehme hier 5V.
Die Verkabelung ist also:
Adapter Pin ESP32 Cam Pin
RXD (3) --> TXD (IO 1 / UnR)
TXD (5) --> RXD (IO 3 / UOT)
GND (1) --> GND
5V0 (7) --> 5V (oben links)
Bei mir ist COM17 hinzugekommen. Auf diesen Port können wir schon einmal mit einem Terminalprogramm oder dem Serial Monitor aus der Arduino IDE zugreifen.
Konfigurieren wir den Port in unserem Terminalürogramm also auf 8N1 und 115200 baud und schauen mal, was die ESP32 Cam so zu vermelden hat:
eher uninteressante Meldungen (klicken, um diesen Abschnitt aufzuklappen)
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:6416
ho 0 tail 12 room 4
load:0x40078000,len:11308
load:0x40080400,len:6732
entry 0x40080764
I (30) boot: ESP-IDF v3.3-beta1-506-gebdcbe8c6 2nd stage bootloader
I (30) boot: compile time 11:42:18
I (30) boot: Enabling RNG early entropy source...
I (36) boot: SPI Speed : 40MHz
I (41) boot: SPI Mode : DIO
I (45) boot: SPI Flash Size : 4MB
I (49) boot: Partition Table:
I (52) boot: ## Label Usage Type ST Offset Length
I (60) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (67) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (74) boot: 2 factory factory app 00 00 00010000 00100000
I (82) boot: End of partition table
I (86) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x1c404 (115716) map
I (136) esp_image: segment 1: paddr=0x0002c42c vaddr=0x3ffb0000 size=0x02ed0 ( 11984) load
I (141) esp_image: segment 2: paddr=0x0002f304 vaddr=0x40080000 size=0x00400 ( 1024) load
I (143) esp_image: segment 3: paddr=0x0002f70c vaddr=0x40080400 size=0x00904 ( 2308) load
I (152) esp_image: segment 4: paddr=0x00030018 vaddr=0x400d0018 size=0x71ff4 (466932) map
I (324) esp_image: segment 5: paddr=0x000a2014 vaddr=0x40080d04 size=0x10b54 ( 68436) load
I (363) boot: Loaded app from partition at offset 0x10000
I (363) boot: Disabling RNG early entropy source...
I (363) cpu_start: Pro cpu up.
I (367) cpu_start: Application information:
I (372) cpu_start: Project name: esp32-cam-demo
I (377) cpu_start: App version: 1
I (382) cpu_start: Compile time: Mar 5 2019 11:42:22
I (388) cpu_start: ELF file SHA256: 88a3a0e577233ee2...
I (394) cpu_start: ESP-IDF: v3.3-beta1-506-gebdcbe8c6
I (400) cpu_start: Starting app cpu, entry point is 0x40081100
I (0) cpu_start: App cpu up.
I (411) heap_init: Initializing. RAM available for dynamic allocation:
I (417) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (424) heap_init: At 3FFB8E68 len 00027198 (156 KiB): DRAM
I (430) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (436) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (443) heap_init: At 40091858 len 0000E7A8 (57 KiB): IRAM
I (449) cpu_start: Pro cpu start user code
I (19) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (65) I2S: DMA Malloc info, datalen=blocksize=256, dma_buf_count=8
I (65) I2S: PLL_D2: Req RATE: 39062, real rate: 39062.000, BITS: 16, CLKM: 16, BCK: 8, MCLK: 10000000.000, SCLK: 1249984.000000, diva: 64, divb: 0
...
...
I (75) camera_xclk: PIN_CTRL before:3ff,39062
I (75) camera_xclk: PIN_CTRL after:7fff
I (4145) camera_demo: Detected OV2640 camera, using JPEG format
test_mode=1
I (4485) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (4485) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (4605) phy: phy_version: 4100, 6fa5e27, Jan 25 2019, 17:02:06, 0, 0
I (4605) camera_demo: Please connect to "ESP32_CAM"
I (4615) camera_demo: Open http://192.168.4.1/jpg for single image/jpg image
I (4615) camera_demo: Open http://192.168.4.1/jpg_stream for multipart/x-mixed-replace stream of JPEGs
I (4625) camera_demo: Free heap: 76068
I (4625) camera_demo: Camera demo ready
Installierte Firmware
Scheinbar soll ich mich wohl mit dem WLAN "ESP32_CAM" verbinden. Ich mach das mal über mein Smartphone, das ist bequemer für mich...Okay. Und dann im Browser "http://192.168.4.1/jpg" für ein Cam-Bild eingeben...
Tadaa! Unser erstes Bild - von meinem Schreibtisch. Die ESP32 Cam funktioniert also schonmal.
Beispiel Firmware ESP32 CameraWebServer
Nur so das NonPlusUltra ist das ja noch nicht. Da geht doch bestimmt noch mehr.Da gab es doch was in den ESP32-Beispielen in der Arduino-IDE...
Wer die Arduino IDE noch nicht installiert hat, oder nicht weiß, was das ist, sollte einen kleinen Abstecher machen und sich erst einmal hier einlesen: Arduino - Ersteinrichtung. Da geht es zwar um den Arduino Uno und nicht den ESP32, aber die Programmierumgebung ist dieselbe, eben Arduino IDE.
Danach muss noch in den Einstellungen die Boardverwalter-URL für die ESP32 Familie eingetragen werden. Wie das genau geht, könnt in im Artikel ESP32 - ESPDUINO-32 Ersteinrichtung nachlesen.
Ja wirklich. Unter Beispiele/ESP32/Camera/CameraWebServer gibt es etwas:
Als erstes ändere ich den Source-Code für mein ESP32 Cam Modell um. Das sieht dann so aus:
// Select camera model
////#define CAMERA_MODEL_WROVER_KIT // Has PSRAM
//#define CAMERA_MODEL_ESP_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_AI_THINKER // Has PSRAM
//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM
Dann wähle ich als Board "ESP32 Wrover Module" in der Arduino IDE unter Tools aus und meinen seriellen Port sowie das Partitions-Schema "Huge App".
Nicht das "AI Thinker ESP32-CAM" Board nehmen, auch wenn das vom Namen her naheliegend ist. Dann denkt der ESP32 Cam nämlich, er hätte kein PSRAM und fängt es bereits bei SVGA (800x600) extrem das Ruckeln an, weil er nicht im PSRAM zwischenbuffert. Wenn bei euch nur max. VGA geht, dann habt ihr das falsche Board gewählt!
Danach ziehe ich meinen Programmier-Adapter ab und verbinde IO 0 und GND auf dem ESP32 Cam-Board.
Am einfachsten geht das mit einem Jumper, wie die alten Haudegen von euch das noch von der Festplattenkonfiguration her kennen. Es geht aber auch ein einfaches Jumper-Kabel.
Den Adapter wieder angesteckt meldet sich der ESP32 Cam über den Serial Monitor, dass er auf einen Download wartet. Es kann losgehen: Kompilieren und hochladen:
Fertig. Adapter abziehen. Jumper abziehen. Adapter wieder einstecken. Serial Monitor an und da steht jetzt:
.........
WiFi connected
Starting web server on port: '80'
Starting stream server on port: '81'
Camera Ready! Use 'http://192.168.0.37' to connect
Was mich ein bisschen wundert ist, dass es keinen Knopf zum Ein- und Ausschalten der LED gibt. Das sollte doch eigentlich das einfachste überhaupt sein zu programmieren. Seltsam.
Dafür gibt es jede Menge Knöpfe, von denen man eigentlich alle so lassen kann, wie sie sind. Wessen Bild auf dem Kopf steht, kann das mit "H-Mirror" und "V-Flip" wieder gerade rücken.
Oben kann man noch höhere Auflösungen einstellen, auch wenn das Vorschaubild rechts nicht so richtig dazu passt. Stelle ich VGA (640x480) ein, hat das Bild nur 400x296 Pixel (CIF). Bei SVGA (eigentlich 800x600) sind es nur 480x320. Erst bei XGA mit eigentlich 1024x768 erhalte ich VGA-Auflösung von 640x480 in der Vorschau rechts. Die Einstellung SXGA (1280x1024) bringt dann 800x600 Pixel. Alles recht seltsam...
Und bei UXGA (eigentlich 1600x1200, aber in der Vorschau nur 1024x768) ruckelt es grausam und es gibt üble Verzögerungen.
Und außerdem hätte ich angenommen, dass das aktuelle Bild in angegebener Auflösung auf der SD-Karte gespeichert wird, wenn ich "Get Still" anklicke. Aber die SD-Karten (Sony 64 GB und Symsung 128 GB) bleiben leer, obwohl sie mit FAT32 formatiert ist. Hier wird wohl nur lediglich ein Standbild von der Kamera geholt und im Browser angezeigt, mehr nicht. Schon etwas enttäuschend.
Unter http://192.168.0.37:81/ wartet sich entweder der Browser einen Wolf (wenn ich vorher auf Start Stream geklickt hatte) oder ich bekomme nur ein "This URI does not exist" (wenn nicht). Ich hatte gehofft, hier wenigstens die vollen 640x480 zu sehen, aber Pustekuchen.
Irgendwann bin ich dann darauf gestoßen, dass es http://192.168.0.37:81/stream heißen muss. Na, dass hätte man auch gleich in die Debug-Meldung schreiben können. Aber helfen tut das auch nichts, die Auflösung ist immer noch gefaked und im Grunde genommen erreiche ich das gleiche Ergebnis, wenn ich im normalen Interface oben auf die drei Striche, das Hamburger Menü, klicke. Das blendet dann die Konfiguration aus und ist dann bis auf die Überschrift haargenau dasselbe.
Wenigstens startet der Stream bei Eingabe der Stream-URL automatisch. Wäre ja auch total sinnfrei, wenn man vorher im Interface auf "Start Stream" klicken müsste.
Das scheint alles nicht sonderlich performant zu sein. Gesichtserkennung kennt schon mal gar nicht mit VGA, dafür darf es höchstens CIF (400x296) sein. Das kenne ich noch aus Zeiten, wo die Handys zum klappen waren und die Spiele darauf mit Java liefen.
Da hatte die Cam auf dem Raspberry Pi Zero V1 aber mehr Dampf. Da war das alles kein großes Problem mit der Objekterkennung mit MotionEye. Dabei gilt der Raspi Zero V1 doch als lahm. Naja, okay, ist eine andere Liga.
Obwohl: zum beobachten reicht es eben so. Aber es gibt Funktionen die ich vermisse:
- mache Bilder und speichere sie auf SD auf Knopfdruck
- speichere Bilder alle x Sekunden
- ... und schalte dafür die Blitz-LED an
- speichere Video-Schnippsel
- speichere Video-Schnippsel bei Bewegungen
Firmware selbst erweitern
Man kann aber natürlich auch selbst etwas programmieren und den Source-Code je nach eigenen Bedürfnissen erweitern oder abändern.Dazu kann man sich an den Beispielen in esp_camera.h orientieren. Zum Beispiel, um etwas zu basteln, was alle paar Sekunden den Blitz anmacht und ein Foto auf der SD-Karte speichert:
Fotos abrufen, um sie dann auf SD-Karte zu speichern (klicken, um diesen Abschnitt aufzuklappen)
esp_err_t camera_example_capture(){
//capture a frame
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAG, "Frame buffer could not be acquired");
return ESP_FAIL;
}
//replace this with your own function
display_image(fb->width, fb->height, fb->pixformat, fb->buf, fb->len);
//return the frame buffer back to be reused
esp_camera_fb_return(fb);
return ESP_OK;
}
Blitz-LED an und aus (klicken, um diesen Abschnitt aufzuklappen)
pinMode(4, OUTPUT); // im Setup()
...
digitalWrite(4, HIGH); //Blitz-LED an
...
digitalWrite(4, LOW); //Blitz-LED aus
Oder man schließt einen PIR-Bewegungssensor an und macht immer ein Bild, wenn jemand vorbeikommt.
Um ganze Videos-Schnippsel zu speichern, dafür wird wohl leider die Performance des ESP32 nicht ausreichen. Man wird sich wohl auf Bilder beschränken müssen. Flüssiges Video wird es wohl nicht werden.
Da man ja eigentlich nur noch IO 16 frei hat, empfiehlt sich ein IO-Expander-Board, mit dem man dann zum Beispiel 8 Pins auf zwei via I2C legen kann.
Dann kann man noch mehr, etwa mit einem Lichtsensor (bzw. Fotowiderstand) schauen, ob es nicht schon hell genug ist und man den Blitz gar nicht braucht. Oder einen Beschleunigungssensor, der Fotos schießt, wenn es im Auto kracht. Oder oder oder... da sind der Kreativität kaum Grenzen gesetzt.
Nachdem alles getestet ist und die ESP32 Cam nicht mehr neu programmiert werden muss - man also den Serial Monitor nicht mehr braucht - , kann man natürlich auf den Serial Adapter verzichten und zum Beispiel ein USB-Ladegerät oder eine Powerbank direkt an 5V und GND anschließen. Gesteuert wird ja alles übers WLAN.
Video
Ich habe wieder ein kleines Video über das Thema gemacht:Fazit
Als günstige Beobachtungskamera taugt die ESP32 Cam schon zusammen mit der Beispielsoftware "CameraWebServer".Nutzt man PSRAM auf dem ESP32 und stellt die Auflösung auf SXGA (1280x1024) erhält man ein SVGA Bild mit 800 x 600 Pixeln, auf dem man durchaus etwas erkennen kann und das Dinge auch ohne große Verzögerung und ohne große Ruckler oder Aussetzer im Browser darstellt.
Dabei habe ich beim Dauerstreaming in dieser Auflösung eine Stromaufnahme von etwa 200 mA bei 5 V gemessen, was 1 Watt entspricht. Mit einer großen 20'000 mAh Powerbank sollte die Cam also für rund 20000*3,7/5/200 = 74 Stunden durchhalten. Für Dauerbetrieb müsste man also alle 3 Tage die Powerbank austauschen. Da empfiehlt sich dann doch eher ein USB-Ladegerät mit 5 Volt. Da eh das Haus-WLAN zum Empfang in Reichweite sein muss, wird in den meisten Fällen eine Steckdose vorhanden sein.
Dann kann man sich auch mehrere ESP32 Cams installieren und die Streams der unterschiedlichen IPs nebeneinander per IFrame in einem Browserfenster anzeigen lassen. Damit könnte man dann 8 oder auch 16 ESP32 Cams gleichzeitig im Blick haben. Wer sein Haus also rundum überwachen mit geringem Budget will...
Der ausschlaggebende Punkt für die ESP32 Cam wird aber der unschlagbare Preis sein. Und wer ein bisschen programmieren kann, kann sie für eigene Zwecke anpassen. Das bietet keine fertige Consumer-IP Kamera, die nebenbei erwähnt alle sehr viel teurer sind.
Damit man seine Webcam auch schnell wiederfindet, sollte man ihrer Mac-Adresse in seinem WLAN-Router eine feste IP zuweisen, damit man immer die gleiche IP einzugeben hat. Ansonsten würde die eventuell bei jeder WLAN-Trennung wechseln.