Inhaltsverzeichnis:

DuvelBot - ESP32-CAM Bierservierroboter - Gunook
DuvelBot - ESP32-CAM Bierservierroboter - Gunook

Video: DuvelBot - ESP32-CAM Bierservierroboter - Gunook

Video: DuvelBot - ESP32-CAM Bierservierroboter - Gunook
Video: Голубая стрела (1958) фильм 2024, Dezember
Anonim
DuvelBot - ESP32-CAM Bierausschankroboter
DuvelBot - ESP32-CAM Bierausschankroboter

Nach einem harten Arbeitstag kommt nichts an Ihr Lieblingsbier auf der Couch heran. In meinem Fall ist das das belgische Blond Ale "Duvel". Nach dem Zusammenbruch stehen wir jedoch vor einem äußerst ernsten Problem: Der Kühlschrank mit meinem Duvel ist unüberbrückbare 6 Meter von der Couch entfernt.

Während ein leichter Zwang von meiner Seite einen gelegentlichen Teenager-Kühlschrank-Reiniger dazu bewegen könnte, mein Wochengeld an Duvel auszuschütten, ist die Aufgabe, es tatsächlich an seinen fast erschöpften Vorfahren zu liefern, offensichtlich ein Schritt zu weit.

Zeit, Lötkolben und Tastatur auszubrechen…

DuvelBot ist eine schnörkellose AI-Thinker ESP32-CAM-basierte Fahr-Webcam, die Sie von Ihrem Smartphone, Browser oder Tablet aus steuern können.

Es ist einfach, diese Plattform für weniger alkoholische Anwendungen anzupassen oder zu erweitern (denken Sie an SpouseSpy, NeighbourWatch, KittyCam…).

Ich habe diesen Roboter hauptsächlich gebaut, um etwas über die gesamte Webprogrammierung und das IoT-Zeug zu lernen, von denen ich nichts wusste. Am Ende dieses Instructable ist eine ausführliche Erklärung, wie das funktioniert.

Viele Teile dieses Instructable basieren auf den ausgezeichneten Erklärungen in Random Nerd Tutorials, also besuchen Sie sie bitte!

Lieferungen

Was du brauchst:

Die Teileliste ist nicht in Stein gemeißelt und viele Teile können in einer Menge verschiedener Versionen und von vielen verschiedenen Orten bezogen werden. Das meiste habe ich von Ali-Express bezogen. Wie Machete sagte: improvisieren.

Hardware:

  • AI Thinker ESP32-CAM-Modul. Es könnte wahrscheinlich mit anderen ESP32-CAM-Modulen funktionieren, aber das habe ich verwendet
  • L298N Motortreiberplatine,
  • Eine billige 4-rädrige Roboterplattform,
  • Ein Gehäuse mit einer großen flachen Oberfläche wie das Hammond Electronics 1599KGY,
  • USB-auf-3.3V-TTL-Konverter zum Programmieren.
  • Für die Beleuchtung: 3 weiße LEDs, BC327 oder anderer Allzwecktransistor NPN (Ic=500mA), 4k7k Widerstand, 3 82Ohm Widerstände, Perfboard, Kabel (siehe Schaltplan und Bilder).
  • Ein Ein-/Aus-Kippschalter und ein Schließer zur Programmierung.

Optional:

  • Eine Fischaugenkamera mit längerem Flex als die Standardkamera OV2460, die mit dem ESP32-CAM-Modul geliefert wird,
  • WLAN-Antenne mit entsprechend langem Kabel und Ultra Miniature Coax Connector, so wie hier. Die ESP32-CAM hat eine Onboard-Antenne und das Gehäuse ist aus Kunststoff, eine Antenne wird also nicht wirklich benötigt, aber ich fand es cool, also…
  • Inkjet bedruckbares Aufkleberpapier für das Design der oberen Abdeckung.

Die üblichen Hardware-Werkzeuge: Lötkolben, Bohrer, Schraubendreher, Zange…

Schritt 1: Aufbau der Roboterplattform

Aufbau der Roboterplattform
Aufbau der Roboterplattform
Aufbau der Roboterplattform
Aufbau der Roboterplattform
Aufbau der Roboterplattform
Aufbau der Roboterplattform

Der Schaltplan:

Der Schaltplan ist nichts besonderes. Die ESP32-Cam steuert die Motoren über die L298N-Motortreiberplatine, die über zwei Kanäle verfügt. Motoren der linken und rechten Seite sind parallel geschaltet und jede Seite belegt einen Kanal. Vier kleine 10..100nF Keramikkondensatoren nahe den Motorpins sind wie immer empfehlenswert um HF-Störungen entgegenzuwirken. Auch eine große Elektrolytkappe (2200…4700uF) auf der Versorgung der Motorplatine, wie im Schaltplan gezeigt, kann, obwohl sie nicht unbedingt erforderlich ist, die Welligkeit der Versorgungsspannung etwas begrenzen (wenn Sie einen Horrorfilm sehen möchten, prüfen Sie Vbat mit einem Oszilloskop bei aktiven Motoren).

Beachten Sie, dass beide Motorkanäle ENABLE-Pins vom gleichen pulsweitenmodulierten (PWM) Pin des ESP32 (IO12) angesteuert werden. Dies liegt daran, dass das ESP32-CAM-Modul nicht über eine Menge GPIOs verfügt (Schema des Moduls als Referenz enthalten). Die LEDs des Roboters werden von IO4 angesteuert, das auch die Onboard-Blitz-LED ansteuert. Entfernen Sie daher Q1, um zu verhindern, dass die Blitz-LED in einem geschlossenen Gehäuse aufleuchtet.

Programmiertaste, Ein-/Ausschalter, Ladeanschluss und Programmieranschluss sind unter dem Roboter zugänglich. Für den Programmieranschluss (3,5mm Klinke?) hätte ich es viel besser machen können, aber das Bier konnte nicht mehr warten. Auch Over-the-Air-Updates (OTA) wären schön einzurichten.

Um den Roboter in den Programmiermodus zu versetzen, drücken Sie die Programmiertaste (dies zieht IO0 nach unten) und schalten Sie ihn dann ein.

Wichtig: Um die NiMH-Akkus des Roboters aufzuladen, verwenden Sie ein Laborversorgungsset (unbelastet) auf ca. 14V und einen auf 250mA begrenzten Strom. Die Spannung passt sich der Spannung der Akkus an. Trennen Sie die Verbindung, wenn sich der Roboter heiß anfühlt oder die Batteriespannung etwa 12,5 V erreicht. Eine offensichtliche Verbesserung wäre hier, ein richtiges Ladegerät zu integrieren, aber das liegt außerhalb des Rahmens dieses Instructable.

Die Hardware:

Bitte beachten Sie auch die Hinweise in den Bildern. Das Gehäuse wird mit 4 M4-Schrauben und selbstsichernden Muttern am Robotersockel befestigt. Beachten Sie den Gummischlauch, der als Abstandshalter verwendet wird. Hoffentlich gibt dies dem Duvel auch etwas Federung, sollte sich die Fahrt als holprig erweisen. Das ESP32-CAM-Modul und die L298N-Motorplatine werden mit Kunststoff-Klebefüßen (der richtigen Bezeichnung im Englischen nicht sicher) im Gehäuse befestigt, um zusätzliche Löcher bohren zu müssen. Auch der ESP32 ist auf einem eigenen Perfboard und steckbaren Stiftleisten montiert. Dies macht es einfach, den ESP32 auszutauschen.

Nicht vergessen: Wenn Sie statt der eingebauten eine externe WLAN-Antenne verwenden, dann löten Sie auch den Antennenauswahl-Jumper an der Unterseite des ESP32-CAM-Boards an.

Drucken Sie das Top-Logo in der Datei DuvelBot.svg auf Inkjet-Aufkleberpapier aus (oder entwerfen Sie Ihr eigenes), und schon können Sie loslegen!

Schritt 2: Programmieren Sie den Roboter

Programmieren Sie den Roboter
Programmieren Sie den Roboter

Es ist ratsam, den Roboter vor dem Schließen zu programmieren, um sicherzustellen, dass alles funktioniert und kein magischer Rauch auftaucht.

Sie benötigen folgende Softwaretools:

  • Die Arduino-IDE,
  • Die ESP32-Bibliotheken, SPIFFS (serielles peripheres Flash-Dateisystem), ESPAsync-Webserver-Bibliothek.

Letzteres kann installiert werden, indem Sie diesem randomnerdtutorial bis einschließlich des Abschnitts "Ihre Dateien organisieren" folgen. Ich könnte es wirklich nicht besser erklären.

Der Code:

Meinen Code finden Sie unter:

  • Eine Arduino-Skizze DuvelBot.ino,
  • Ein Datenunterordner, der die Dateien enthält, die mit SPIFFS auf den ESP-Flash hochgeladen werden. Dieser Ordner enthält die Webseite, die vom ESP bereitgestellt wird (index.html), ein Logobild, das Teil der Webseite ist (duvel.png) und ein kaskadiertes Stylesheet oder eine CSS-Datei (style.css).

Um den Roboter zu programmieren:

  • Schließen Sie den USB-TTL-Konverter wie im Schaltplan gezeigt an,
  • Datei -> Öffnen -> gehe in den Ordner, in dem sich DuvelBot.ino befindet.
  • Ändern Sie Ihre Netzwerkanmeldeinformationen in der Skizze:

const char* ssid = "yourNetworkSSIDHere";const char* password = "yourPasswordHere";

  • Tools -> Board -> "AI-Thinker ESP-32 CAM" und wählen Sie den entsprechenden seriellen Port für Ihren PC aus (Tools -> Port -> so etwas wie /dev/ttyUSB0 oder COM4),
  • Öffnen Sie den seriellen Monitor in der Arduino IDE, während Sie die PROG-Taste drücken (die IO0 nach unten zieht), schalten Sie den Roboter ein.
  • Überprüfen Sie auf dem seriellen Monitor, ob der ESP32 zum Download bereit ist,
  • Schließen Sie den seriellen Monitor (sonst schlägt der SPIFFS-Upload fehl),
  • Tools -> "ESP32 Sketch Data Upload" und warten Sie, bis der Vorgang abgeschlossen ist.
  • Aus- und wieder einschalten bei gedrückter PROG-Taste, um in den Programmiermodus zurückzukehren,
  • Drücken Sie den "Upload"-Pfeil, um die Skizze zu programmieren und warten Sie, bis sie abgeschlossen ist.
  • Öffnen Sie den seriellen Monitor und setzen Sie den ESP32 durch Aus-/Einschalten zurück,
  • Notieren Sie sich nach dem Booten die IP-Adresse (etwa 192.168.0.121) und trennen Sie den Roboter vom USB-TTL-Konverter.
  • Öffnen Sie einen Browser unter dieser IP-Adresse. Sie sollten die Schnittstelle wie auf dem Bild sehen.
  • Optional: Stellen Sie die Mac-Adresse des ESP32 auf eine feste IP-Adresse in Ihrem Router ein (abhängig vom Router, wie vorzugehen ist).

Das ist es! Lesen Sie weiter, wenn Sie wissen möchten, wie es funktioniert…

Schritt 3: Wie es funktioniert

Kommen wir nun zum interessanten Teil: Wie funktioniert das alles zusammen?

Ich werde versuchen, es Schritt für Schritt zu erklären, aber bitte bedenken Sie, dass Kajnjaps kein Spezialist für Webprogrammierung ist. Tatsächlich war das Erlernen von Webprogrammierung die ganze Prämisse bei der Entwicklung von DuvelBot. Wenn ich offensichtliche Fehler mache, hinterlasse bitte einen Kommentar!

Ok, nach dem Einschalten des ESP32 werden wie im Setup üblich die GPIOs initialisiert, mit PWM-Timern für Motor- und LED-Steuerung verknüpft. Siehe hier für mehr über die Motorsteuerung, es ist ziemlich Standard.

Anschließend wird die Kamera konfiguriert. Die Auflösung habe ich bewusst recht niedrig gehalten (VGA oder 640x480), um eine träge Reaktion zu vermeiden. Beachten Sie, dass das AI-Thinker ESP32-CAM-Board über einen seriellen RAM-Chip (PSRAM) verfügt, der zum Speichern von Kamerabildern mit höherer Auflösung verwendet wird:

if (psramFound ()) {Serial.println ("PSRAM gefunden."); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; // Anzahl der Framebuffer siehe: https://github.com/espressif/esp32-camera} else {Serial.println("kein PSRAM gefunden."); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }

Dann wird das Serial Peripheral Flash File System (SPIFFS) initialisiert:

// SPIFFS initialisieren if (! SPIFFS.begin (true)) { Serial.println ("Beim Mounten von SPIFFS ist ein Fehler aufgetreten!"); Rückkehr; }

SPIFFS verhält sich auf dem ESP32 wie ein kleines Dateisystem. Hier wird es verwendet, um drei Dateien zu speichern: die Webseite selbst index.html, eine kaskadierte Datei stylesheet style.css und ein PNG-Bildlogo duvel.png. Diese Dateien werden vom ESP32 an jeden bereitgestellt, der sich als Client mit ihm verbindet. Während es möglich und einfach ist, die gesamte Webseite aus dem Sketch heraus bereitzustellen, indem man server.send(…) ausführt, sehr ähnlich wie serial.println() für eine große Textzeichenfolge, ist es einfacher, stattdessen einfach eine Datei bereitzustellen, da dies auch für Bilder und andere Nicht-Text-Daten funktioniert.

Als nächstes verbindet sich der ESP32 mit Ihrem Router (vergessen Sie nicht, Ihre Zugangsdaten vor dem Hochladen festzulegen):

//Anmeldeinformationen Ihres Routers ändern const char* ssid = "yourNetworkSSIDHere";const char* password = "yourPasswordHere"; … // mit WiFi verbinden Serial.print ("Verbindung mit WiFi"); WiFi.begin(ssid, Passwort); Während (WiFi.status () != WL_CONNECTED) { Serial.print ('.'); Verzögerung (500); } // jetzt mit dem Router verbunden: ESP32 hat jetzt eine IP-Adresse

Um tatsächlich etwas Nützliches zu tun, starten wir einen asynchronen Webserver:

//Erzeuge ein AsyncWebServer-Objekt auf Port 80AsyncWebServer-Server (80); … server.begin(); // fang an nach Verbindungen zu lauschen

Wenn Sie nun die IP-Adresse, die dem ESP32 vom Router zugewiesen wurde, in die Adressleiste eines Browsers eingeben, bekommt der ESP32 eine Anfrage. Dies bedeutet, dass es auf den Client (Sie oder Ihren Browser) reagieren sollte, indem es ihm etwas bereitstellt, zum Beispiel eine Webseite.

Der ESP32 weiß, wie er antwortet, da im Setup die Antworten auf alle möglichen erlaubten Anfragen mit server.on() registriert wurden. Beispielsweise wird die Hauptwebseite oder der Index (/) wie folgt behandelt:

server.on("/", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println(" / Anfrage erhalten!"); request->send(SPIFFS, "/index.html", String(), false, Prozessor); });

Wenn sich der Client also verbindet, antwortet der ESP32, indem er die Datei index.html aus dem SPIFFS-Dateisystem sendet. Der Parameterprozessor ist der Name einer Funktion, die den HTML-Code vorverarbeitet und alle speziellen Tags ersetzt:

// Ersetzt Platzhalter im HTML wie %DATA%// durch die Variablen, die Sie anzeigen möchten//

Daten: %DATA%

String-Prozessor (const String& var) { if (var == "DATA") { // Serial.println ("im Prozessor!"); Return String (DutyCycleNow); } String() zurückgeben;}

Lassen Sie uns nun die Webseite index.html selbst analysieren. Im Allgemeinen gibt es immer drei Teile:

  1. HTML-Code: Welche Elemente sollen angezeigt werden (Schaltflächen/Text/Schieberegler/Bilder etc.),
  2. Style-Code, entweder in einer separaten.css-Datei oder in einem … Abschnitt: wie die Elemente aussehen sollen,
  3. javascript a … Abschnitt: wie sich die Webseite verhalten soll.

Sobald index.html in den Browser geladen wurde (der aufgrund der DOCTYPE-Zeile weiß, dass es sich um HTML handelt), läuft es in diese Zeile:

Das ist eine Anforderung für ein CSS-Stylesheet. Die Position dieses Blattes wird in href="…" angegeben. Was macht Ihr Browser? Richtig, es startet eine weitere Anfrage an den Server, diesmal für style.css. Der Server erfasst diese Anfrage, weil sie registriert wurde:

server.on("/style.css", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println(" CSS-Anfrage erhalten"); request->send(SPIFFS, "/style.css", "text/css "); });

Ordentlich oder? Übrigens könnte es href="/some/file/on/the/other/side/of/the/moon" gewesen sein, egal was Ihr Browser interessiert. Es würde diese Datei genauso glücklich holen. Ich werde das Stylesheet nicht erklären, da es nur das Aussehen steuert, also ist es hier nicht wirklich interessant, aber wenn Sie mehr erfahren möchten, sehen Sie sich dieses Tutorial an.

Wie erscheint das DuvelBot-Logo? In index.html haben wir:

worauf der ESP32 antwortet mit:

server.on("/duvel", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println("Duvel-Logo-Anfrage erhalten!"); request->send(SPIFFS, "/duvel.png", "image-p.webp

..eine weitere SPIFFS-Datei, diesmal ein vollständiges Bild, wie durch "image/png" in der Antwort angegeben.

Kommen wir nun zum eigentlich interessanten Teil: dem Code für die Buttons. Konzentrieren wir uns auf den FORWARD-Button:

NACH VORNE

Der Name ist nur ein Name, um ihn mit dem Stylesheet zu verknüpfen, um die Größe, Farbe usw. anzupassen. Die wichtigen Teile sind onmousedown="toggleCheckbox('forward')" und onmouseup="toggleCheckbox('stop') ". Diese stellen die Aktionen der Schaltfläche dar (dasselbe für ontouchstart/ontouchend, aber für Touchscreens/Telefone). Hier ruft die Schaltflächenaktion eine Funktion toggleCheckbox(x) im Abschnitt Javascript auf:

Funktion toggleCheckbox(x){ var xhr = new XMLHttpRequest(); xhr.open("GET", "/" + x, wahr); xhr.senden(); // könnte auch etwas mit der Antwort machen, wenn sie fertig ist, aber wir tun es nicht }

Das Drücken der Vorwärts-Taste führt also sofort dazu, dass toggleCheckbox('forward') aufgerufen wird. Diese Funktion startet dann einen XMLHttpRequest "GET" mit dem Speicherort "/forward", der sich so verhält, als ob Sie 192.168.0.121/forward in die Adressleiste Ihres Browsers eingegeben hätten. Sobald diese Anfrage beim ESP32 eintrifft, wird sie bearbeitet von:

server.on("/forward", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println("received /forward"); actionNow = FORWARD; request->send(200, "text/plain", "OK forward."); });

Nun antwortet der ESP32 einfach mit einem Text "OK forward". Beachten Sie, dass toggleCheckBox() nichts mit dieser Antwort macht (oder darauf wartet), aber es könnte wie später im Kameracode gezeigt werden.

An sich setzt das Programm bei dieser Reaktion nur eine Variable actionNow = FORWARD, als Reaktion auf das Drücken der Taste. Jetzt wird diese Variable in der Hauptschleife des Programms mit dem Ziel überwacht, die PWM der Motoren hoch-/herunterzufahren. Die Logik ist: Solange wir eine Aktion haben, die nicht STOP ist, fahren Sie die Motoren in diese Richtung hoch, bis eine bestimmte Anzahl (dutyCycleMax) erreicht ist. Dann behalten Sie diese Geschwindigkeit bei, solange sich actionNow nicht geändert hat:

Void Schleife () { currentMillis = millis (); if (currentMillis - previousMillis >= DutyCycleStepDelay) { // Speichern Sie das letzte Mal, als Sie die Schleife ausgeführt haben previousMillis = currentMillis; // mainloop ist verantwortlich für das Hoch- und Herunterfahren der Motoren if(actionNow!= previousAction) { //Ramp down, dann stoppen, dann Aktion ändern und hochfahren DutyCycleNow = DutyCycleNow-dutyCycleStep; if (dutyCycleNow <= 0) {// Wenn nach dem Herunterfahren von DC 0 ist, auf die neue Richtung setzen, bei min. Dutycycle starten setDir (actionNow); vorherigeAktion = AktionJetzt; DutyCycleNow = DutyCycleMin; } } else //actionNow == previousAction ramp up, außer wenn die Richtung STOP ist { if (actionNow != STOP) { DutyCycleNow = DutyCycleNow+dutyCycleStep; if (dutyCycleNow > dutyCycleMax) dutyCycleNow = dutyCycleMax; } else DutyCycleNow = 0; } ledcWrite (pwmChannel, DutyCycleNow); // Passen Sie die Einschaltdauer des Motors an }}

Dies erhöht langsam die Geschwindigkeit der Motoren, anstatt nur mit voller Geschwindigkeit zu starten und das kostbare kostbare Duvel zu verschütten. Eine offensichtliche Verbesserung wäre, diesen Code in eine Timer-Interrupt-Routine zu verschieben, aber er funktioniert so, wie er ist.

Wenn wir jetzt die Weiterleitungstaste loslassen, ruft Ihr Browser toggleCheckbox('stop') auf, was zu einer Anfrage an GET /stop führt. Der ESP32 setzt actionNow auf STOP (und antwortet mit "OK stop."), was die Hauptschleife zum Herunterfahren der Motoren einleitet.

Was ist mit den LEDs? Gleicher Mechanismus, aber jetzt haben wir einen Schieberegler:

Im Javascript wird die Einstellung des Schiebereglers überwacht, so dass bei jeder Änderung ein Aufruf zum Abrufen von "/LED/xxx" erfolgt, wobei xxx der Helligkeitswert ist, auf den die LEDs eingestellt werden sollen:

var slide = document.getElementById('slide'), sliderDiv = document.getElementById("sliderAmount"); slide.onchange = function() { var xhr = new XMLHttpRequest(); xhr.open("GET", "/LED/" + this.value, true); xhr.senden(); sliderDiv.innerHTML = this.value; }

Beachten Sie, dass wir document.getElementByID('slide') verwendet haben, um das Slider-Objekt selbst zu erhalten, das mit deklariert wurde und dass der Wert bei jeder Änderung an ein Textelement ausgegeben wird.

Der Handler in der Skizze fängt alle Helligkeitsanforderungen ab, indem er "/LED/*" in der Handler-Registrierung verwendet. Dann wird der letzte Teil (eine Zahl) geteilt und in ein int umgewandelt:

server.on("/LED/*", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println("LED-Anfrage erhalten!"); setLedBrightness((request->url()).substring(5).toInt ()); request->send(200, "text/plain", "OK Leds."); });

Ähnlich wie oben beschrieben steuern die Radiobuttons Variablen, die die PWM-Standardeinstellungen festlegen, sodass DuvelBot langsam mit dem Bier zu Ihnen fahren kann, darauf achtend, dass kein flüssiges Gold verschüttet wird, und schnell zurück in die Küche, um etwas mehr zu holen.

…Wie wird also das Kamerabild aktualisiert, ohne dass Sie die Seite aktualisieren müssen? Dazu verwenden wir eine Technik namens AJAX (Asynchronous JavaScript and XML). Das Problem ist, dass normalerweise eine Client-Server-Verbindung einem festen Ablauf folgt: Client (Browser) stellt Anfrage, Server (ESP32) antwortet, Fall geschlossen. Fertig. Nichts passiert mehr. Wenn wir den Browser nur irgendwie dazu bringen könnten, regelmäßig Updates vom ESP32 anzufordern … und genau das werden wir mit diesem Javascript-Stück tun:

setInterval(function(){ var xhttp = new XMLHttpRequest(); xhttp.open("GET", "/CAMERA", true); xhttp.responseType = "blob"; xhttp.timeout = 500; xhttp.ontimeout = function(){}; xhttp.onload = function(e){ if (this.readyState == 4 && this.status == 200) { //siehe: https://stackoverflow.com/questions/7650587/using… // https://www.html5rocks.com/en/tutorials/file/xhr2/ var urlCreator = window. URL || window.webkitURL; var imageUrl = urlCreator.createObjectURL(this.response); //Erzeuge ein Objekt aus dem Blob document.querySelector("#camimage").src = imageUrl; urlCreator.revokeObjectURL(imageurl) } }; xhttp.send(); }, 250);

setInterval nimmt als Parameter eine Funktion und führt sie von Zeit zu Zeit aus (hier einmal pro 250ms, was 4 Frames/Sekunde ergibt). Die ausgeführte Funktion fordert einen binären "Blob" an der Adresse /CAMERA an. Dies wird von der ESP32-CAM in der Skizze als (aus Randomnerdtutorials) behandelt:

server.on("/CAMERA", HTTP_GET, (AsyncWebServerRequest *request){ Serial.println("Kameraanfrage erhalten!"); camera_fb_t * fb = NULL; //esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; uint8_t * _jpg_buf = NULL; //einen Frame aufnehmen fb = esp_camera_fb_get(); if (!fb) {Serial.println("Framebuffer konnte nicht erfasst werden");return;} if(fb->format != PIXFORMAT_JPEG)/ /already in diesem Format von config{ bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len); esp_camera_fb_return(fb); fb = NULL; if(!jpeg_converted){Serial.println("JPEG-Komprimierung fehlgeschlagen");return; } } else{ _jpg_buf_len = fb->len; _jpg_buf = fb->buf; } //Serial.println(_jpg_buf_len); //formatierte Bildanfrage senden->send_P(200, "image/jpg", _jpg_buf, _jpg_buf_len); //Aufräumen if(fb){ esp_camera_fb_return(fb); fb = NULL; _jpg_buf = NULL; } else if(_jpg_buf){free(_jpg_buf); _jpg_buf = NULL; } });

Die wichtigen Teile sind das Beschaffen des Frames fb = esp_camera_fb_get(), das Konvertieren in ein-j.webp

Die Javascript-Funktion wartet dann auf das Eintreffen dieses Bildes. Dann ist es nur ein wenig Arbeit, den empfangenen "Blob" in eine URL zu konvertieren, die als Quelle zum Aktualisieren des Bildes auf der HTML-Seite verwendet werden kann.

Puh, wir sind fertig!

Schritt 4: Ideen & Reste

Ideen & Reste
Ideen & Reste

Das Ziel dieses Projekts war für mich, gerade genug Webprogrammierung zu lernen, um Hardware mit dem Web zu verbinden. Mehrere Erweiterungen dieses Projekts sind möglich. Hier sind ein paar Ideen:

  • Implementieren Sie 'echtes' Kamerastreaming wie hier und hier beschrieben und verschieben Sie es wie hier beschrieben auf einen zweiten Server auf demselben ESP32, aber auf dem anderen CPU-Kern, importieren Sie dann den Kamerastream in den HTML-Code des ersten Servers mit einem …. Dies sollte zu schnelleren Kamera-Updates führen.
  • Verwenden Sie den Access Point (AP)-Modus, damit der Roboter wie hier beschrieben eigenständiger ist.
  • Erweitern Sie mit Batteriespannungsmessung, Deep-Sleep-Funktionen usw. Dies ist im Moment etwas schwierig, da der AI-Thinker ESP32-CAM nicht viele GPIOs hat; braucht eine Erweiterung über uart und zum Beispiel ein Slave-Arduino.
  • Verwandeln Sie sich in einen katzensuchenden Roboter, der von Zeit zu Zeit Katzenleckerlis auf einen großen Knopfdruck ausstößt, und streamen Sie tagsüber tonnenweise schöne Katzenbilder …

Bitte kommentieren, wenn es Ihnen gefallen hat oder Fragen und danke fürs Lesen!