Innholdsfortegnelse:

DuvelBot - ESP32 -CAM ølserveringsrobot: 4 trinn (med bilder)
DuvelBot - ESP32 -CAM ølserveringsrobot: 4 trinn (med bilder)

Video: DuvelBot - ESP32 -CAM ølserveringsrobot: 4 trinn (med bilder)

Video: DuvelBot - ESP32 -CAM ølserveringsrobot: 4 trinn (med bilder)
Video: Голубая стрела (1958) фильм 2024, Juni
Anonim
DuvelBot - ESP32 -CAM ølserveringsrobot
DuvelBot - ESP32 -CAM ølserveringsrobot

Etter en hard arbeidsdag kommer ingenting i nærheten av å nippe til favorittølet ditt på sofaen. I mitt tilfelle er det den belgiske blonde ale "Duvel". Imidlertid konfronteres vi med et alvorlig problem: kjøleskapet som inneholder min Duvel, er nesten 20 fot fjernet fra sofaen.

Selv om en liten tvang fra min side kan bevege en og annen tenåring i kjøleskapet for å helle ut ukes godtgjørelse av Duvel, er oppgaven med å faktisk levere den til sin nesten utmattede stamfar åpenbart et skritt for langt.

På tide å bryte ut loddejernet og tastaturet …

DuvelBot er et problemfritt AI-Thinker ESP32-CAM-basert kjørewebkamera, som du kan kontrollere fra smarttelefonen, nettleseren eller nettbrettet.

Det er enkelt å tilpasse eller utvide denne plattformen til mindre alkoholholdige bruksområder (tenk SpouseSpy, NeighbourWatch, KittyCam …).

Jeg bygde denne roboten hovedsakelig for å lære litt om hele webprogrammeringen og IoT -ting, som jeg ikke visste noe om. Så på slutten av denne instruksjonsboken er en forseggjort forklaring på hvordan det fungerer.

Mange deler av denne instruksjonsboken er basert på de utmerkede forklaringene som finnes på Random Nerd Tutorials, så vær så snill å gi dem et besøk!

Rekvisita

Hva trenger du:

Delelisten er ikke hugget i stein, og mange deler kan fås i massevis av forskjellige versjoner og fra mange forskjellige steder. Jeg kjøpte det meste fra Ali-Express. Som Machete sa: improvisere.

Maskinvare:

  • AI-tenker ESP32-CAM-modul. Det kan sannsynligvis fungere med andre ESP32-CAM-moduler, men det er det jeg brukte
  • L298N motorførerkort,
  • En billig 4-hjulet robotikkplattform,
  • Et hus med en stor flat overflate som Hammond Electronics 1599KGY,
  • USB-til-3.3V-TTL-omformer for programmering.
  • For belysning: 3 hvite lysdioder, BC327 eller annen generell transistor NPN (Ic = 500mA), 4k7k motstand, 3 82Ohm motstander, perfboard, kabler (se skjema og bilder).
  • En av/på-bryter og en normalt åpen trykknapp for programmering.

Valgfri:

  • Et fiskeøyekamera med lengre fleksibilitet enn standard OV2460-kamera som følger med ESP32-CAM-modulen,
  • WiFi -antenne med passende lang kabel og Ultra Miniature Coax Connector, som denne. ESP32-CAM har en innebygd antenne og huset er av plast, så en antenne er egentlig ikke nødvendig, men jeg syntes det så kult ut, så …
  • Blekkskriver som kan skrives ut med klistremerke for toppdekselet.

De vanlige maskinvareverktøyene: loddejern, bor, skrutrekkere, tang …

Trinn 1: Bygg robotplattformen

Å bygge robotplattformen
Å bygge robotplattformen
Å bygge robotplattformen
Å bygge robotplattformen
Å bygge robotplattformen
Å bygge robotplattformen

Skjematisk:

Skjematikken er ikke noe spesielt. ESP32-cam styrer motorene via L298N-motordriverkortet, som har to kanaler. Motorer på venstre og høyre side er plassert parallelt, og hver side opptar en kanal. Fire små 10..100nF keramiske kondensatorer nær motorpinnene er som alltid tilrådelig for å motvirke RF -forstyrrelser. Også en stor elektrolytisk hette (2200… 4700uF) på motorens bord som vist i skjemaet, men ikke strengt nødvendig, kan begrense forsyningsspenningen litt (hvis du vil se en skrekkfilm, så undersøk Vbat med et oscilloskop mens motorene er aktive).

Vær oppmerksom på at begge motorkanalene ENABLE-pinner drives av den samme pulsbreddemodulerte (PWM) pinnen på ESP32 (IO12). Dette er fordi ESP32-CAM-modulen ikke har massevis av GPIO (modulskjema inkludert som referanse). Robotens lysdioder drives av IO4, som også driver innebygd blits -LED, så fjern Q1 for å forhindre at blitslysdioden lyser i et lukket hus.

Programmeringsknapp, av/på -bryter, ladekontakt og programmeringskontakt er tilgjengelig under roboten. Jeg kunne ha gjort en mye bedre jobb for programmeringskontakten (3,5 mm jack?), Men ølet kunne ikke vente lenger. Også over-the-air-oppdateringer (OTA) ville være fint å sette opp.

For å sette roboten i programmeringsmodus, trykk på programmeringsknappen (dette trekker IO0 lavt) og slå den deretter på.

Viktig: For å lade NiMH -batteriene til roboten, bruk et laboratorieforsyningssett (ubelastet) til ca 14V og strøm begrenset til 250mA. Spenningen vil tilpasse seg batteriene. Koble fra hvis roboten føles varm eller batterispenningen når omtrent 12,5V. En åpenbar forbedring her ville være å integrere en skikkelig batterilader, men det er utenfor omfanget av denne instruksjonsboken.

Maskinvaren:

Se også notatene på bildene. Huset er montert på robotbasen ved hjelp av 4 M4 bolter og selvlåsende muttere. Legg merke til gummislangen som brukes som avstandsstykker. Forhåpentligvis gir dette også noe fjæring til Duvel, hvis turen skulle vise seg å være humpete. ESP32-CAM-modulen og L298N-motorkortet er montert i huset ved hjelp av klebrige føtter av plast (ikke sikker på riktig navn på engelsk), for å forhindre at du må bore ekstra hull. Også ESP32 er montert på sitt eget perfboard og pluggbare pinheaders. Dette gjør det enkelt å bytte ut ESP32.

Ikke glem: hvis du går med en ekstern WiFi-antenn i stedet for den innebygde, så lodd også antennevalgshopperen på undersiden av ESP32-CAM-kortet.

Skriv ut den øverste logoen i filen DuvelBot.svg på blekkskriverpapir (eller design ditt eget), så er du klar.

Trinn 2: Programmer roboten

Programmer roboten
Programmer roboten

Det er lurt å programmere roboten før du lukker den, for å sikre at alt fungerer og at det ikke vises magisk røyk.

Du trenger følgende programvareverktøy:

  • Arduino IDE,
  • ESP32 -bibliotekene, SPIFFS (serielt perifert flash -filsystem), ESPAsync Webserver -bibliotek.

Sistnevnte kan installeres ved å følge denne tilfeldige opplæringen til og med delen "organisering av filene dine". Jeg kunne virkelig ikke forklare det bedre.

Koden:

Koden min finner du på:

  • En Arduino -skisse DuvelBot.ino,
  • En dataundermappe som inneholder filene som skal lastes opp til ESP -blitsen ved hjelp av SPIFFS. Denne mappen inneholder nettsiden som ESP vil vise (index.html), et logobilde som er en del av websiden (duvel.png) og et kaskadert stilark eller CSS -fil (style.css).

Slik programmerer du roboten:

  • Koble USB-TTL-omformeren som vist i skjematisk
  • Fil -> Åpne -> gå til mappen der DuvelBot.ino er.
  • Endre nettverkslegitimasjonen din i skissen:

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

  • Verktøy -> Kort -> "AI -Thinker ESP -32 CAM" og velg riktig seriell port for din PC (Verktøy -> Port -> noe som /dev /ttyUSB0 eller COM4),
  • Åpne den serielle skjermen i Arduino IDE, mens du trykker på PROG -knappen (som trekker IO0 lavt), slår du på roboten,
  • Kontroller på seriell skjerm at ESP32 er klar for nedlasting,
  • Lukk den serielle skjermen (hvis ikke SPIFFS -opplastingen mislykkes),
  • Verktøy -> "ESP32 Sketch Data Upload" og vent til den er ferdig,
  • Slå av og på igjen og hold inne PROG -knappen for å gå tilbake til programmeringsmodus,
  • Trykk på "Last opp" -pilen for å programmere skissen og vent til den er ferdig,
  • Åpne den serielle skjermen og tilbakestill ESP32 ved å slå den av/på,
  • Når den har startet, noterer du ned ip-adressen (noe som 192.168.0.121) og kobler roboten fra USB-TTL-omformeren,
  • Åpne en nettleser på denne ip -adressen. Du bør se grensesnittet som på bildet.
  • Valgfritt: angi mac-adressen til ESP32 til en fast ip-adresse i ruteren (avhenger av ruteren hvordan du gjør).

Det er det! Les videre hvis du vil vite hvordan det fungerer …

Trinn 3: Slik fungerer det

Nå kommer vi til den interessante delen: hvordan fungerer alt sammen?

Jeg vil prøve å forklare det trinn for trinn, men vær oppmerksom på at Kajnjaps ikke er en spesialist på programmering av nett. Faktisk var det å lære litt webprogrammering hele forutsetningen for å bygge DuvelBot. Hvis jeg gjør åpenbare feil, vennligst legg igjen en kommentar!

Ok, etter at ESP32 er slått på, initialiserer den som vanlig i oppsettet GPIO -ene, knytter dem til PWM -tidtakere for motor- og LED -kontroll. Se her for mer om motorstyringen, den er ganske standard.

Deretter er kameraet konfigurert. Jeg holdt bevisst oppløsningen ganske lav (VGA eller 640x480) for å unngå treg respons. Vær oppmerksom på at AI-Thinker ESP32-CAM-kortet har en seriell rambrikke (PSRAM) som den bruker til å lagre kamerarammer med større oppløsning:

if (psramFound ()) {Serial.println ("PSRAM funnet."); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; // antall rammebuffere se: https://github.com/espressif/esp32-camera} annet {Serial.println ("ingen PSRAM funnet."); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }

Deretter initialiseres det serielle perifere flashfilsystemet (SPIFFS):

// initialiser SPIFFS hvis (! SPIFFS.begin (true)) {Serial.println ("Det oppstod en feil under montering av SPIFFS!"); komme tilbake; }

SPIFFS fungerer som et lite filsystem på ESP32. Her brukes den til å lagre tre filer: selve websiden index.html, et kaskadert stilstilark.css og en-p.webp

Deretter kobles ESP32 til ruteren din (ikke glem å angi legitimasjon før du laster opp):

// endre legitimasjon for ruteren hereconst char* ssid = "yourNetworkSSIDHere"; const char* password = "yourPasswordHere"; … // koble til WiFi Serial.print ("Koble til WiFi"); WiFi.begin (ssid, passord); mens (WiFi.status ()! = WL_CONNECTED) {Serial.print ('.'); forsinkelse (500); } // nå koblet til ruteren: ESP32 har nå ip -adresse

For å faktisk gjøre noe nyttig, starter vi en asynkron webserver:

// opprett et AsyncWebServer -objekt på port 80AsyncWebServer -server (80); … server.begin (); // begynn å lytte etter tilkoblinger

Hvis du skriver inn ip -adressen som ble tildelt ESP32 av ruteren i adressefeltet i nettleseren, får ESP32 en forespørsel. Dette betyr at den skal svare på klienten (deg eller nettleseren din) ved å servere den noe, for eksempel en webside.

ESP32 vet hvordan de skal svare, for ved oppsett har svarene på alle mulige tillatte forespørsler blitt registrert ved hjelp av server.on (). For eksempel håndteres hovedsiden eller indeksen (/) slik:

server.on ("/", HTTP_GET, (AsyncWebServerRequest *forespørsel) {Serial.println ("/forespørsel mottatt!"); forespørsel-> send (SPIFFS, "/index.html", String (), false, prosessor);});

Så hvis klienten kobler seg til, svarer ESP32 ved å sende filen index.html fra SPIFFS -filsystemet. Parameterprosessoren er navnet på en funksjon som forhåndsbehandler HTML -filen og erstatter eventuelle spesielle tagger:

// Erstatter plassholdere i HTML som %DATA %// med variablene du vil vise //

Data: %DATA %

Stringprosessor (const String & var) {if (var == "DATA") {//Serial.println("in prosessor! "); returstreng (dutyCycleNow); } return String ();}

La oss nå deaktivere selve websiden index.html. Generelt er det alltid tre deler:

  1. html -kode: hvilke elementer som skal vises (knapper/tekst/glidebrytere/bilder etc.),
  2. stilkode, enten i en egen.css -fil eller i en … seksjon: hvordan elementene skal se ut,
  3. javascript a … seksjon: hvordan nettsiden skal fungere.

Når index.html lastes inn i nettleseren (som vet at det er html på grunn av DOCTYPE -linjen), kjører den inn på denne linjen:

Det er en forespørsel om et css -stilark. Plasseringen av dette arket er angitt i href = "…". Så hva gjør nettleseren din? Høyre, det lanserer en annen forespørsel til serveren, denne gangen for style.css. Serveren fanger opp denne forespørselen fordi den ble registrert:

server.on ("/style.css", HTTP_GET, (AsyncWebServerRequest *forespørsel) {Serial.println ("css-forespørsel mottatt"); request-> send (SPIFFS, "/style.css", "text/css ");});

Ryddig va? Forresten, det kunne ha vært href = "/some/file/on/the/other/side/of/the/moon", for all nettleseren din brydde seg. Det ville like gjerne hentet den filen. Jeg vil ikke forklare om stilarket siden det bare kontrollerer utseende, så det er egentlig ikke interessant her, men hvis du vil lære mer, sjekk denne opplæringen.

Hvordan vises DuvelBot -logoen? I index.html har vi:

som ESP32 svarer med:

server.on ("/duvel", HTTP_GET, (AsyncWebServerRequest *forespørsel) {Serial.println ("forespørsel om duvellogo mottatt!"); forespørsel-> send (SPIFFS, "/duvel.png", "image-p.webp

..en annen SPIFFS -fil, denne gangen et komplett bilde, som angitt av "image/png" i svaret.

Nå kommer vi til den virkelig interessante delen: koden for knappene. La oss fokusere på FORWARD -knappen:

FRAMOVER

Class = "…" -navnet er bare et navn for å koble det til stilarket for å tilpasse størrelse, farge osv. De viktige delene er onmousedown = "toggleCheckbox ('forward')" og onmouseup = "toggleCheckbox ('stop') ". Disse utgjør handlingene til knappen (samme for ontouchstart/ontouchend, men for det er berøringsskjerm/telefon). Her kaller knapphandlingen en funksjon toggleCheckbox (x) i javascript -delen:

function toggleCheckbox (x) {var xhr = ny XMLHttpRequest (); xhr.open ("GET", "/" + x, true); xhr.send (); // kan gjøre noe med responsen også når vi er klare, men vi gjør det ikke}

Så hvis du trykker på fremoverknappen, resulterer det umiddelbart i at av / på -avkrysningsboksen ('fremover') blir ringt. Denne funksjonen starter deretter en XMLHttpRequest "GET", av plasseringen "/forward" som fungerer akkurat som hvis du ville ha skrevet 192.168.0.121/forward i nettleserens adresselinje. Når denne forespørselen kommer til ESP32, håndteres den av:

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

Nå svarer ESP32 ganske enkelt med teksten "OK fremover". Merk toggleCheckBox () gjør ikke noe med (eller vent på) dette svaret, men det kan som vist senere i kamerakoden.

I seg selv under dette svaret, setter programmet bare en variabel actionNow = FORWARD, som svar på å trykke på knappen. Nå i programmets hovedløyfe, blir denne variabelen overvåket med målet om å øke/senke motorens PWM. Logikken er: så lenge vi har en handling som ikke er STOPP, skal du øke motorene i den retningen til et visst antall (dutyCycleMax) er nådd. Oppretthold deretter den hastigheten, så lenge actionNow ikke har endret seg:

void loop () {currentMillis = millis (); if (currentMillis - previousMillis> = dutyCycleStepDelay) {// lagre den siste gangen du utførte løkken previousMillis = currentMillis; // mainloop er ansvarlig for å rampe opp/ned motorene hvis (actionNow! = previousAction) {// rampe ned, deretter stoppe, deretter endre handling og rampe opp dutyCycleNow = dutyCycleNow-dutyCycleStep; hvis (dutyCycleNow <= 0) {// hvis etter nedstigning dc er 0, sett til den nye retningen, start med min dutycycle setDir (actionNow); previousAction = actionNow; dutyCycleNow = dutyCycleMin; }} else // actionNow == previousAction ramp opp, bortsett fra når retningen er STOP {if (actionNow! = STOP) {dutyCycleNow = dutyCycleNow+dutyCycleStep; if (dutyCycleNow> dutyCycleMax) dutyCycleNow = dutyCycleMax; } ellers dutyCycleNow = 0; } ledcWrite (pwmChannel, dutyCycleNow); // juster motorens sykkel}}

Dette øker sakte motorens hastighet, i stedet for bare å starte i full fart og søl den dyrebare dyrebare Duvel. En åpenbar forbedring ville være å flytte denne koden til en tidsavbruddsrutine, men den fungerer som den er.

Hvis vi slipper viderekoblingsknappen, ringer nettleseren din toggleCheckbox ('stopp'), noe som resulterer i en forespørsel om å få /stoppe. ESP32 setter actionNow til STOPP (og svarer med "OK stopp."), Som bruker hovedløkken til å spinne ned motorene.

Hva med lysdiodene? Samme mekanisme, men nå har vi en glidebryter:

I javascript overvåkes innstillingen til glidebryteren, slik at det ved hver endring skjer et anrop for å få "/LED/xxx", der xxx er lysstyrkeverdien som lysdiodene skal settes til:

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

Vær oppmerksom på at vi brukte document.getElementByID ('lysbilde') for å få selve skyveobjektet, som ble deklarert med, og at verdien sendes til et tekstelement med hver endring.

Behandleren i skissen fanger opp alle lysstyrkeforespørsler ved å bruke "/LED/*" i handleregistreringen. Så deles den siste delen (et tall) av og kastes til en int:

server.on ("/LED/ *", HTTP_GET, (AsyncWebServerRequest *forespørsel) {Serial.println ("ledet forespørsel mottatt!"); setLedBrightness ((forespørsel-> url ()). delstreng (5).toInt ()); request-> send (200, "text/plain", "OK Leds.");});

På samme måte som beskrevet ovenfor, kontrollerer radioknappene variabler som setter PWM -standardene, slik at DuvelBot kan kjøre sakte til deg med ølet, forsiktig så du ikke søler det flytende gullet, og raskt tilbake til kjøkkenet for å hente litt mer.

… Så hvordan oppdateres kamerabildet uten at du trenger å oppdatere siden? For det bruker vi en teknikk kalt AJAX (asynkron JavaScript og XML). Problemet er at en klient-server-tilkobling vanligvis følger en fast prosedyre: klient (nettleser) sender forespørsel, server (ESP32) reagerer, saken avsluttes. Ferdig. Ingenting skjer lenger. Hvis vi bare på en eller annen måte kunne lure nettleseren til regelmessig å be om oppdateringer fra ESP32 … og det er akkurat det vi vil gjøre med dette stykke javascript:

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) {// se: 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); // lag et objekt fra bloben document.querySelector ("#camimage"). src = imageUrl; urlCreator.revokeObjectURL (imageurl)}}; xhttp.send ();}, 250);

setInterval tar som parameter en funksjon og utfører den så ofte (her en gang per 250 ms, noe som resulterer i 4 bilder/sekund). Funksjonen som utføres sender en forespørsel om en binær "blob" på adressen /CAMERA. Dette håndteres av ESP32-CAM i skissen som (fra Randomnerdtutorials):

server.on ("/CAMERA", HTTP_GET, (AsyncWebServerRequest * forespørsel) {Serial.println ("kameraforespørsel mottatt!"); camera_fb_t * fb = NULL; // esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; uint8_ * _jpg_buf = NULL; // fange en ramme fb = esp_camera_fb_get (); if (! fb) {Serial.println ("Frame buffer kunne ikke anskaffes"); return;} if (fb-> format! = PIXFORMAT_JPEG)/ /allerede i dette formatet fra config {bool jpeg_converted = frame-j.webp

De viktige delene er å få rammen fb = esp_camera_fb_get () til å konvertere den til en-j.webp

Javascript -funksjonen venter deretter på at dette bildet skal komme. Da tar det bare litt arbeid å konvertere den mottatte "bloben" til en url som kan brukes som kilde for å oppdatere bildet med i html -siden.

puh, vi er ferdige!

Trinn 4: Ideer og rester

Ideer og rester
Ideer og rester

Målet med dette prosjektet for meg var å lære akkurat nok webprogrammering til å koble maskinvare til nettet. Flere utvidelser av dette prosjektet er mulig. Her er noen ideer:

  • Implementér "ekte" kamerastrømming som forklart her og her, og flytt den til en andre server som forklart her på samme ESP32, men på den andre CPU -kjernen, og importer deretter kamerastrømmen til html som serveres av den første serveren ved hjelp av en …. Dette bør resultere i raskere kameraoppdateringer.
  • Bruk tilgangspunkt (AP) -modus slik at roboten er mer frittstående som forklart her.
  • Utvid med batterispenningsmåling, dyp søvnmuligheter etc. Dette er litt vanskelig for øyeblikket fordi AI-Thinker ESP32-CAM ikke har mange GPIO-er; trenger utvidelse via uart og for eksempel en slave -arduino.
  • Konverter til en kattesøkende robot som av og til kaster ut godbiter fra katter med et tastetrykk på en stor knapp, strøm tonnevis med fine kattebilder i løpet av dagen …

Kommenter gjerne hvis du liker eller har spørsmål, og takk for at du leser!

Anbefalt: