Indholdsfortegnelse:
- Forbrugsvarer
- Trin 1: Opbygning af robotplatformen
- Trin 2: Programmer robotten
- Trin 3: Sådan fungerer det
- Trin 4: Ideer og rester
Video: DuvelBot - ESP32 -CAM Beer Servering Robot: 4 trin (med billeder)
2024 Forfatter: John Day | [email protected]. Sidst ændret: 2024-01-30 08:26
Efter en hård dags arbejde er der intet i nærheden af at nippe til din yndlingsøl på sofaen. I mit tilfælde er det den belgiske blonde ale "Duvel". Imidlertid står vi trods alt sammen ved at kollapse med et yderst alvorligt problem: Køleskabet, der indeholder min Duvel, er en uoverstigelig 20 fod fjernet fra sofaen.
Mens en let tvang fra min side kan flytte en lejlighedsvis teenaged køleskab scavenger til at hælde min uges godtgørelse af Duvel, opgaven med faktisk at levere det til sin næsten udmattede stamfar er naturligvis et skridt for langt.
Tid til at bryde loddejernet og tastaturet ud …
DuvelBot er et problemfrit AI-Thinker ESP32-CAM-baseret kørewebcam, som du kan styre fra din smartphone, browser eller tablet.
Det er let at tilpasse eller udvide denne platform til mindre alkoholiske anvendelser (tænk SpouseSpy, NeighbourWatch, KittyCam …).
Jeg byggede denne robot hovedsageligt for at lære lidt om hele webprogrammeringen og IoT -ting, som jeg ikke vidste noget om. Så i slutningen af denne Instructable er en detaljeret forklaring på, hvordan det fungerer.
Mange dele af denne Instructable er baseret på de fremragende forklaringer, der findes på Random Nerd Tutorials, så giv dem et besøg!
Forbrugsvarer
Hvad du har brug for:
Delelisten er ikke hugget i sten, og mange dele kan fås i masser af forskellige versioner og fra mange forskellige steder. Jeg skaffede mest fra Ali-Express. Som Machete sagde: improvisere.
Hardware:
- AI-tænker ESP32-CAM-modul. Det kunne sandsynligvis fungere med andre ESP32-CAM-moduler, men det er det, jeg brugte
- L298N motor driver bord,
- En billig 4-hjulet robotplatform,
- Et hus med en stor flad overflade, såsom Hammond Electronics 1599KGY,
- USB-til-3.3V-TTL-konverter til programmering.
- Til belysningen: 3 hvide lysdioder, BC327 eller anden generel transistor NPN (Ic = 500mA), 4k7k modstand, 3 82Ohm modstande, perfboard, kabler (se skematisk og billeder).
- En tænd/sluk-switch og en normalt åben trykknap til programmering.
Valgfri:
- Et fiskeøje-kamera med længere fleksibilitet end standard OV2460-kameraet, der følger med ESP32-CAM-modulet,
- WiFi -antenne med passende langt kabel og Ultra Miniature Coax Connector, som denne. ESP32-CAM har en indbygget antenne, og kabinettet er af plast, så en antenne er ikke rigtig nødvendig, men jeg syntes, den så cool ud, så …
- Mærkatpapir, der kan udskrives i inkjet, til design af topdækslet.
De sædvanlige hardware værktøjer: loddejern, bor, skruetrækkere, tang …
Trin 1: Opbygning af robotplatformen
Skematisk:
Skematikken er ikke noget særligt. ESP32-cam styrer motorerne via L298N-motordriverkortet, som har to kanaler. Motorer på venstre og højre side er placeret parallelt, og hver side indtager en kanal. Fire små 10..100nF keramiske kondensatorer tæt på motorstifterne er som altid tilrådeligt for at modvirke RF -interferens. Også en stor elektrolytdæksel (2200… 4700uF) på forsyningen af motorbrættet som vist i skematisk, men ikke strengt nødvendigt, kan begrænse forsyningsspændingskrusningen lidt (hvis du vil se en gyserfilm, så sonde Vbat med et oscilloskop, mens motorerne er aktive).
Bemærk, at begge motorkanalers ENABLE-ben drives af den samme pulsbreddemodulerede (PWM) pin på ESP32 (IO12). Dette skyldes, at ESP32-CAM-modulet ikke har masser af GPIO'er (modulets skematik er inkluderet til reference). Robotens LED'er drives af IO4, som også driver den indbyggede flash -LED, så fjern Q1 for at forhindre, at flash -LED'en lyser i et lukket hus.
Programmeringsknap, tænd/sluk -knap, opladningsstik og programmeringsstik er tilgængelige under robotten. Jeg kunne have gjort et meget bedre stykke arbejde med programmeringsstikket (3,5 mm stik?), Men øllet kunne ikke vente mere. Også over-the-air-opdateringer (OTA) ville være rart at opsætte.
For at sætte robotten i programmeringstilstand skal du trykke på programmeringsknappen (dette trækker IO0 lavt) og derefter tænde den.
Vigtigt: For at oplade NiMH -batterierne i robotten skal du bruge et laboratorieforsyningssæt (ubelastet) til ca. 14V og strøm begrænset til 250mA. Spændingen tilpasser sig batteriernes spænding. Afbryd forbindelsen, hvis robotten føles varm, eller batterispændingen når omkring 12,5V. En oplagt forbedring her ville være at integrere en ordentlig batterioplader, men det er uden for omfanget af denne Instructable.
Hardwaren:
Se også noterne på billederne. Huset er monteret på robotbunden ved hjælp af 4 M4 bolte og selvlåsende møtrikker. Bemærk gummislangen, der bruges som afstandsstykker. Forhåbentlig giver dette også en vis suspension til Duvel, hvis turen skulle vise sig at være ujævn. ESP32-CAM-modulet og L298N-motorkortet er monteret i huset ved hjælp af plastikklæder (ikke sikker på det rigtige navn på engelsk), for at undgå at skulle bore ekstra huller. Også ESP32 er monteret på sit eget perfboard og stikbare stikhoveder. Dette gør det let at skifte ESP32.
Glem ikke: hvis du går med en ekstern WiFi-antenne i stedet for den indbyggede, så lod også antennevalg-jumperen på undersiden af ESP32-CAM-kortet.
Udskriv det øverste logo i filen DuvelBot.svg på inkjet -mærkatpapir (eller design dit eget), og du er klar til at gå!
Trin 2: Programmer robotten
Det er tilrådeligt at programmere robotten, før du lukker den, for at sikre, at alt fungerer, og at der ikke kommer magisk røg.
Du har brug for følgende softwareværktøjer:
- Arduino IDE,
- ESP32 -bibliotekerne, SPIFFS (serielt perifert flash -filsystem), ESPAsync Webserver -bibliotek.
Sidstnævnte kan installeres ved at følge denne randomnerdtutorial til og med afsnittet "organisering af dine filer". Jeg kunne virkelig ikke forklare det bedre.
Koden:
Min kode kan findes på:
- En Arduino -skitse DuvelBot.ino,
- En undermappe i data, der gemmer de filer, der skal uploades til ESP -flashen ved hjælp af SPIFFS. Denne mappe indeholder den webside, som ESP'en vil vise (index.html), et logo -billede, der er en del af websiden (duvel.png) og et kaskadformatark eller CSS -fil (style.css).
Sådan programmeres robotten:
- Tilslut USB-TTL-konverteren som vist i skematisk,
- Fil -> Åbn -> gå til mappe, hvor DuvelBot.ino er.
- Skift dine netværksoplysninger i skitsen:
const char* ssid = "yourNetworkSSIDHere"; const char* password = "yourPasswordHere";
- Værktøjer -> Board -> "AI -Thinker ESP -32 CAM" og vælg den passende serielle port til din pc (Værktøjer -> Port -> noget i stil med /dev /ttyUSB0 eller COM4),
- Åbn den serielle skærm i Arduino IDE, mens du trykker på PROG -knappen (der trækker IO0 lavt), tænder du for robotten,
- Kontroller på den serielle skærm, at ESP32 er klar til download,
- Luk den serielle skærm (ellers mislykkes SPIFFS -upload),
- Værktøjer -> "ESP32 Sketch Data Upload" og vent på, at det er færdigt,
- Sluk og tænd igen ved at holde PROG -knappen nede for at vende tilbage til programmeringstilstand,
- Tryk på "Upload" -pilen for at programmere skitsen, og vent på, at den er færdig,
- Åbn den serielle skærm, og nulstil ESP32 ved at slukke/tænde,
- Når den er startet, skal du notere ip-adressen (noget som 192.168.0.121) og afbryde robotten fra USB-TTL-konverteren,
- Åbn en browser på denne ip -adresse. Du skal se grænsefladen som på billedet.
- Valgfrit: indstil mac-adressen på ESP32 til en fast ip-adresse i din router (afhænger af routeren, hvordan du gør).
Det er det! Læs med, hvis du vil vide, hvordan det fungerer …
Trin 3: Sådan fungerer det
Nu kommer vi til den interessante del: hvordan fungerer det hele sammen?
Jeg vil prøve at forklare det trin for trin, men husk, at Kajnjaps ikke er specialist i webprogrammering. Faktisk var det at lære lidt af webprogrammering hele forudsætningen for at bygge DuvelBot. Hvis jeg laver åbenlyse fejl, bedes du efterlade en kommentar!
Ok, efter at ESP32 er tændt, initialiserer den som sædvanlig i opsætningen GPIO'erne, forbinder dem med PWM -timere til motor- og LED -styring. Se her for mere om motorstyringen, det er ret standard.
Derefter er kameraet konfigureret. Jeg holdt bevidst opløsningen ret lav (VGA eller 640x480) for at undgå træg reaktion. Bemærk, at AI-Thinker ESP32-CAM-kortet har en seriel ramchip (PSRAM), som det bruger til at gemme kamerarammer med større opløsning:
hvis (psramFound ()) {Serial.println ("PSRAM fundet."); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; // antal framebuffere se: https://github.com/espressif/esp32-camera} else {Serial.println ("ingen PSRAM fundet."); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }
Derefter initialiseres det serielle perifere flashfilsystem (SPIFFS):
// initialiser SPIFFS hvis (! SPIFFS.begin (true)) {Serial.println ("Der opstod en fejl under montering af SPIFFS!"); Vend tilbage; }
SPIFFS fungerer som et lille filsystem på ESP32. Her bruges den til at gemme tre filer: selve websiden index.html, et kaskadformatfilformatark.css og et-p.webp
Derefter opretter ESP32 forbindelse til din router (glem ikke at angive dine legitimationsoplysninger, før du uploader):
// ændre legitimationsoplysninger for din router hereconst char* ssid = "yourNetworkSSIDHere"; const char* password = "yourPasswordHere"; … // opret forbindelse til WiFi Serial.print ("Opretter forbindelse til WiFi"); WiFi.begin (ssid, adgangskode); mens (WiFi.status ()! = WL_CONNECTED) {Serial.print ('.'); forsinkelse (500); } // nu tilsluttet routeren: ESP32 har nu ip -adresse
For faktisk at gøre noget nyttigt starter vi en asynkron webserver:
// opret et AsyncWebServer -objekt på port 80AsyncWebServer -server (80); … server.begin (); // begynd at lytte efter forbindelser
Nu, hvis du indtaster ip -adressen, der blev tildelt ESP32 af routeren i en browsers adresselinje, får ESP32 en anmodning. Det betyder, at den skal svare klienten (dig eller din browser) ved at servere den noget, f.eks. En webside.
ESP32 ved, hvordan man reagerer, for i opsætningen er svarene på alle mulige tilladte anmodninger blevet registreret ved hjælp af server.on (). For eksempel håndteres hovedsiden eller indekset (/) således:
server.on ("/", HTTP_GET, (AsyncWebServerRequest *anmodning) {Serial.println ("/anmodning modtaget!"); anmodning-> send (SPIFFS, "/index.html", String (), falsk, processor);});
Så hvis klienten opretter forbindelse, reagerer ESP32 ved at sende filen index.html fra SPIFFS -filsystemet. Parameterprocessoren er navnet på en funktion, der forbehandler html'en og erstatter eventuelle særlige tags:
// Erstatter pladsholdere i HTML som %DATA %// med de variabler, du vil vise //
Data: %DATA %
Stringprocessor (const String & var) {if (var == "DATA") {//Serial.println("in processor! "); returstreng (dutyCycleNow); } return String ();}
Lad os nu deaktivere selve websiden index.html. Generelt er der altid tre dele:
- html -kode: hvilke elementer der skal vises (knapper/tekst/skydere/billeder osv.),
- stilkode, enten i en separat.css -fil eller i en … sektion: hvordan elementerne skal se ud,
- javascript a … sektion: hvordan websiden skal fungere.
Når index.html indlæses i browseren (som ved, at det er html på grund af DOCTYPE -linjen), løber den ind i denne linje:
Det er en anmodning om et css -stilark. Placeringen af dette ark er angivet i href = "…". Så hvad gør din browser? Højre, det lancerer en anden anmodning til serveren, denne gang for style.css. Serveren fanger denne anmodning, fordi den blev registreret:
server.on ("/style.css", HTTP_GET, (AsyncWebServerRequest *anmodning) {Serial.println ("css anmodning modtaget"); request-> send (SPIFFS, "/style.css", "text/css ");});
Pænt huh? Det kunne i øvrigt have været href = "/some/file/on/the/other/side/of/the/moon", for al din browser var bekymret. Det ville lige så lykkeligt hente den fil. Jeg vil ikke forklare om stilarket, da det bare styrer udseende, så det er ikke rigtig interessant her, men hvis du vil lære mere, kan du tjekke denne vejledning.
Hvordan fremstår DuvelBot -logoet? I index.html har vi:
hvortil ESP32 reagerer med:
server.on ("/duvel", HTTP_GET, (AsyncWebServerRequest *anmodning) {Serial.println ("anmodning om duvellogo modtaget!"); request-> send (SPIFFS, "/duvel.png", "image-p.webp
..en anden SPIFFS -fil, denne gang et komplet billede, som angivet med "image/png" i svaret.
Nu kommer vi til den virkelig interessante del: koden til knapperne. Lad os fokusere på knappen FREM:
FREM
Class = "…" -navnet er kun et navn for at linke det til stilarket for at tilpasse størrelse, farve osv. De vigtige dele er onmousedown = "toggleCheckbox ('fremad') 'og onmouseup =" toggleCheckbox (' stop ') ". Disse udgør knappens handlinger (det samme for ontouchstart/ontouchend, men for det er berøringsskærme/telefoner). Her kalder knappen handling en funktion toggleCheckbox (x) i javascript -sektionen:
funktion toggleCheckbox (x) {var xhr = ny XMLHttpRequest (); xhr.open ("GET", "/" + x, true); xhr.send (); // kunne også gøre noget med svaret, når vi var klar, men det gør vi ikke}
Så trykker du på fremad -knappen, resulterer det umiddelbart i, at afkrydsningsfeltet ('frem') bliver ringet op. Denne funktion lancerer derefter en XMLHttpRequest "GET", af placeringen "/forward", der fungerer ligesom hvis du ville have skrevet 192.168.0.121/forward i din browsers adresselinje. Når denne anmodning ankommer til ESP32, håndteres den af:
server.on ("/videresend", HTTP_GET, (AsyncWebServerRequest *anmodning) {Serial.println ("modtaget/videresendt"); actionNow = FORWARD; request-> send (200, "text/plain", "OK forward. ");});
Nu svarer ESP32 simpelthen med teksten "OK frem". Bemærk toggleCheckBox () gør ikke noget med (eller vent på) dette svar, men det kunne som vist senere i kamerakoden.
I sig selv under dette svar angiver programmet kun en variabel actionNow = FREM, som svar på at trykke på knappen. Nu i programmets hovedloop, overvåges denne variabel med det mål at rampe op/ned af motorernes PWM. Logikken er: så længe vi har en handling, der ikke er STOP, skal du øge motorerne i den retning, indtil et bestemt antal (dutyCycleMax) er nået. Hold derefter fast ved denne hastighed, så længe actionNow ikke har ændret sig:
void loop () {currentMillis = millis (); hvis (currentMillis - previousMillis> = dutyCycleStepDelay) {// gem den sidste gang du udførte løkken previousMillis = currentMillis; // mainloop er ansvarlig for at rampe op/ned af motorerne, hvis (actionNow! = previousAction) {// rampe ned, derefter stoppe, derefter ændre handling og rampe op dutyCycleNow = dutyCycleNow-dutyCycleStep; hvis (dutyCycleNow <= 0) {// hvis dc efter rampning ned er 0, indstilles til den nye retning, start ved min dutycycle setDir (actionNow); previousAction = actionNow; dutyCycleNow = dutyCycleMin; }} else // actionNow == previousAction rampe op, undtagen når retningen er STOP {if (actionNow! = STOP) {dutyCycleNow = dutyCycleNow+dutyCycleStep; hvis (dutyCycleNow> dutyCycleMax) dutyCycleNow = dutyCycleMax; } ellers dutyCycleNow = 0; } ledcWrite (pwmChannel, dutyCycleNow); // juster motorcyklen}}
Dette øger langsomt motorernes hastighed, i stedet for bare at starte med fuld hastighed og spilde den dyrebare dyrebare Duvel. En oplagt forbedring ville være at flytte denne kode til en timer -afbrydelsesrutine, men den fungerer som den er.
Hvis vi nu slipper knappen Videresend, kalder din browser toggleCheckbox ('stop'), hvilket resulterer i en anmodning om GET /stop. ESP32 sætter actionNow til STOP (og reagerer med "OK stop."), Som indleder mainloop til at dreje motorerne ned.
Hvad med lysdioderne? Samme mekanisme, men nu har vi en skyder:
I javascript overvåges indstillingen af skyderen, således at der ved hver ændring sker et opkald for at få "/LED/xxx", hvor xxx er den lysstyrkeværdi, som LED'erne skal indstilles til:
var slide = document.getElementById ('slide'), sliderDiv = document.getElementById ("sliderAmount"); slide.onchange = funktion () {var xhr = ny XMLHttpRequest (); xhr.open ("GET", "/LED/" + this.value, true); xhr.send (); sliderDiv.innerHTML = this.value; }
Bemærk, at vi brugte document.getElementByID ('slide') til at få selve skyderobjektet, som blev erklæret med, og at værdien sendes til et tekstelement med ved hver ændring.
Handleren i skitsen fanger alle anmodninger om lysstyrke ved at bruge "/LED/*" i handleregistreringen. Derefter deles den sidste del (et tal) af og støbes til en int:
server.on ("/LED/ *", HTTP_GET, (AsyncWebServerRequest *anmodning) {Serial.println ("led anmodning modtaget!"); setLedBrightness ((anmodning-> url ()). delstreng (5).tilInt ()); anmodning-> send (200, "tekst/almindelig", "OK lysdioder.");});
Ligesom beskrevet ovenfor kontrollerer radioknapperne variabler, der indstiller PWM -standarderne, således at DuvelBot kan køre langsomt hen til dig med øllet, omhyggelig med ikke at spilde det flydende guld og hurtigt tilbage til køkkenet for at hente noget mere.
… Så hvordan opdateres kamerabilledet, uden at du behøver at opdatere siden? Til det bruger vi en teknik kaldet AJAX (asynkron JavaScript og XML). Problemet er, at en klient-server-forbindelse normalt følger en fast procedure: Klient (browser) anmoder, server (ESP32) reagerer, sag lukket. Færdig. Intet sker mere. Hvis vi bare på en eller anden måde kunne narre browseren til regelmæssigt at anmode om opdateringer fra ESP32 … og det er præcis, hvad vi vil gøre med dette stykke javascript:
setInterval (funktion () {var xhttp = ny XMLHttpRequest (); xhttp.open ("GET", "/CAMERA", true); xhttp.responseType = "blob"; xhttp.timeout = 500; xhttp.ontimeout = function () {}; xhttp.onload = funktion (e) {if (this.readyState == 4 && this.status == 200) {// se: https://stackoverflow.com/questions/7650587/using… // https://www.html5rocks.com/da/tutorials/file/xhr2/ var urlCreator = window. URL || window.webkitURL; var imageUrl = urlCreator.createObjectURL (this.response); // opret et objekt fra bloben document.querySelector ("#camimage"). src = imageUrl; urlCreator.revokeObjectURL (imageurl)}}; xhttp.send ();}, 250);
setInterval tager som parameter en funktion og udfører den så ofte (her en gang pr. 250 ms, hvilket resulterer i 4 billeder/sekund). Funktionen, der udføres, anmoder om en binær "klat" på adressen /CAMERA. Dette håndteres af ESP32-CAM i skitsen som (fra Randomnerdtutorials):
server.on ("/CAMERA", HTTP_GET, (AsyncWebServerRequest * anmodning) {Serial.println ("kameraanmodning modtaget!"); 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 (); hvis (! fb) {Serial.println ("Frame buffer kunne ikke erhverves"); return;} if (fb-> format! = PIXFORMAT_JPEG)/ /allerede i dette format fra config {bool jpeg_converted = frame-j.webp
De vigtige dele er at få rammen fb = esp_camera_fb_get () til at konvertere den til en-j.webp
Javascript -funktionen venter derefter på, at dette billede ankommer. Så tager det bare lidt arbejde at konvertere den modtagne "blob" til en url, der kan bruges som kilde til at opdatere billedet med i html -siden.
Puha, vi er færdige!
Trin 4: Ideer og rester
Målet med dette projekt for mig var at lære lige nok webprogrammering til at interface hardware til internettet. Flere udvidelser til dette projekt er mulige. Her er et par ideer:
- Implementér 'rigtig' kamerastreaming som forklaret her og her, og flyt den til en 2. server som forklaret her på den samme ESP32, men på den anden CPU -kerne, importer derefter kamerastrømmen til html, der serveres af den 1. server ved hjælp af en …. Dette bør resultere i hurtigere kameraopdateringer.
- Brug adgangspunkt (AP) -tilstand, så robotten er mere selvstændig som forklaret her.
- Udvid med batterispændingsmåling, dyb søvnfunktioner osv. Dette er lidt svært i øjeblikket, fordi AI-Thinker ESP32-CAM ikke har mange GPIO'er; har brug for ekspansion via uart og for eksempel en slave arduino.
- Konverter til en kattesøgende robot, der fra tid til anden skubber kattegodt ud med et tryk på en stor knap, stream masser af flotte kattebilleder i løbet af dagen …
Kommenter venligst, hvis du kunne lide eller har spørgsmål, og tak fordi du læste!
Anbefalede:
The Ultimate Beer Pong Machine - PongMate CyberCannon Mark III: 6 trin (med billeder)
The Ultimate Beer Pong Machine - PongMate CyberCannon Mark III: Introduktion PongMate CyberCannon Mark III er det nyeste og mest avancerede stykke ølpongteknologi, der nogensinde er blevet solgt til offentligheden. Med den nye CyberCannon kan enhver person blive den mest frygtede spiller ved ølpongbordet. Hvordan er dette p
Beer Tøndevægte: 7 trin (med billeder)
Beer Tøndevægte: Jeg kom tilbage til Australien i 2016 efter nogle år at have boet i Thailand, og jeg kunne ikke tro prisen på en karton øl, omkring $ 50. Så jeg oprettede mit eget bryggeri igen, denne gang ved hjælp af fustager i stedet for flasker . Ingen sekundær gæring, ingen tidsforbrug
Sådan adskilles en computer med nemme trin og billeder: 13 trin (med billeder)
Sådan adskilles en computer med nemme trin og billeder: Dette er en instruktion om, hvordan du adskiller en pc. De fleste af de grundlæggende komponenter er modulopbyggede og nemme at fjerne. Det er dog vigtigt, at du er organiseret omkring det. Dette hjælper med at forhindre dig i at miste dele og også ved at lave genmonteringen til
Neopixel Light Up Sushi Servering Board: 6 trin (med billeder)
Neopixel Light Up Sushi Serving Board: En maker skal lave. &Ldquo; Men en af de ting, som folk vil komme efter, er, at alle skal spise. &Rdquo; Christy Canida om Instructables I skæringspunktet mellem mad, teknologi og sultzonen gør denne sushi serveringsbræt lys til at bette
Servér O'Beer med iPhone til den perfekte hældning: 7 trin (med billeder)
Servér O'Beer med iPhone til den perfekte skænkning: Da nytår nærmer sig med hastige skridt, ville jeg lave et projekt, der giver mulighed for den perfekte hældning og fjerner alt det fysiske arbejde. Ved at bruge Construx som den mekaniske platform, en servo, der driver handlingen, og ioBridge, der kontrollerer systemet, blev jeg