Cuprins:

DuvelBot - Robot de servire a berii ESP32-CAM: 4 pași (cu imagini)
DuvelBot - Robot de servire a berii ESP32-CAM: 4 pași (cu imagini)
Anonim
DuvelBot - Robot de servire a berii ESP32-CAM
DuvelBot - Robot de servire a berii ESP32-CAM

După o zi grea de muncă, nimic nu se apropie de sorbirea berii preferate pe canapea. În cazul meu, acesta este blondul belgian "Duvel". Cu toate acestea, în cele din urmă, în afară de prăbușire, ne confruntăm cu o problemă foarte gravă: frigiderul care conține Duvel-ul meu este de 20 de picioare, care nu poate fi îndepărtat, îndepărtat de pe canapeaua menționată.

În timp ce o constrângere ușoară din partea mea ar putea muta un frigider ocazional adolescent pentru a-mi vărsa alocația săptămânală pentru Duvel, sarcina de a-l livra de fapt către progenitorul său aproape epuizat este evident un pas prea departe.

E timpul să izbucnim lipirea și tastatura …

DuvelBot este o cameră web de conducere bazată pe AI-Thinker ESP32-CAM, pe care o puteți controla de pe smartphone, browser sau tabletă.

Este ușor să adaptați sau să extindeți această platformă la utilizări mai puțin alcoolice (gândiți-vă la SpouseSpy, NeighbourWatch, KittyCam …).

Am construit acest robot în principal pentru a afla un pic despre întreaga programare web și lucrurile IoT, despre care nu știam nimic. Deci, la sfârșitul acestui Instructable este o explicație elaborată a modului în care funcționează.

Multe părți ale acestui instructabil se bazează pe explicațiile excelente găsite la Tutorialele Random Nerd, așa că vă rugăm să le vizitați!

Provizii

De ce ai nevoie:

Lista pieselor nu este sculptată în piatră și multe piese pot fi obținute într-o tonă de versiuni diferite și din multe locuri diferite. Am procurat cel mai mult de la Ali-Express. Așa cum spunea Machete: improvizează.

Hardware:

  • Modulul AI Thinker ESP32-CAM. Ar putea funcționa probabil cu alte module ESP32-CAM, dar asta am folosit
  • Placa driverului motorului L298N,
  • O platformă ieftină de robotică cu 4 roți,
  • O carcasă cu o suprafață plană mare, cum ar fi Hammond Electronics 1599KGY,
  • Convertor USB-la-3.3V-TTL pentru programare.
  • Pentru iluminat: 3 LED-uri albe, BC327 sau alt tranzistor de uz general NPN (Ic = 500mA), rezistor 4k7k, 3 rezistențe 82Ohm, placă de perfecționare, cabluri (vezi schema și imaginile).
  • Un comutator de pornire / oprire și un buton normal deschis pentru programare.

Opțional:

  • O cameră cu ochi de pește cu flexie mai lungă decât camera standard OV2460 furnizată cu modulul ESP32-CAM,
  • Antena WiFi cu un cablu lung adecvat și conector coaxial ultra miniatural, ca acesta. ESP32-CAM are o antenă la bord, iar carcasa este din plastic, deci nu este necesară o antenă, totuși am crezut că arăta bine, așa că …
  • Hârtie autocolant imprimabilă cu jet de cerneală pentru designul capacului superior.

Instrumentele hardware obișnuite: lipitor, burghie, șurubelnițe, clește …

Pasul 1: Construirea platformei robot

Construirea platformei robotului
Construirea platformei robotului
Construirea platformei robotului
Construirea platformei robotului
Construirea platformei robotului
Construirea platformei robotului

Schema:

Schema nu este nimic special. ESP32-cam controlează motoarele prin placa driverului motorului L298N, care are două canale. Motoarele din partea stângă și cea dreaptă sunt plasate în paralel și fiecare parte ocupă un canal. Patru condensatoare ceramice mici de 10..100nF, apropiate de știfturile motorului, sunt întotdeauna recomandate pentru a contracara interferențele RF. De asemenea, un capac electrolitic mare (2200 … 4700uF) pe alimentarea plăcii motorului, așa cum se arată în schemă, deși nu este strict necesar, poate limita un pic tensiunea de alimentare (dacă doriți să vedeți un film de groază, apoi testați Vbat cu osciloscop în timp ce motoarele sunt active).

Rețineți că ambele canale ale motorului ENABLE pin sunt acționate de același pin modulat la lățimea impulsului (PWM) al ESP32 (IO12). Acest lucru se datorează faptului că modulul ESP32-CAM nu are o mulțime de GPIO-uri (schema modulului este inclusă pentru referință). LED-urile robotului sunt acționate de IO4, care acționează și LED-ul blițului de la bord, deci scoateți Q1 pentru a preveni aprinderea LED-ului blițului într-o carcasă închisă.

Butonul de programare, comutatorul de pornire / oprire, conectorul de încărcare și conectorul de programare sunt accesibile sub robot. Aș fi putut face o treabă mult mai bună pentru conectorul de programare (jack de 3,5 mm?), Dar berea nu mai putea aștepta. De asemenea, actualizările over-the-air (OTA) ar fi frumos de configurat.

Pentru a pune robotul în modul de programare, apăsați butonul de programare (acesta scade IO0 jos) și apoi porniți-l.

Important: pentru a încărca bateriile NiMH ale robotului, utilizați un set de alimentare de laborator (descărcat) la aproximativ 14V și curent limitat la 250mA. Tensiunea se va adapta la tensiunea bateriilor. Deconectați-vă dacă robotul se simte fierbinte sau tensiunea bateriei ajunge la aproximativ 12,5V. O îmbunătățire evidentă aici ar fi integrarea unui încărcător de baterii adecvat, dar acest lucru nu intră în sfera acestui instructabil.

Hardware-ul:

Vă rugăm să consultați și notele din imagini. Carcasa este montată pe baza robotului folosind 4 șuruburi M4 și piulițe autoblocante. Rețineți tubulatura de cauciuc folosită ca distanțieri. Sperăm că acest lucru oferă și o suspensie pentru Duvel, în cazul în care călătoria se va dovedi accidentată. Modulul ESP32-CAM și placa motorului L298N sunt montate în carcasă folosind picioare lipicioase din plastic (nu sunt sigure numele corect în limba engleză), pentru a preveni nevoia de a face găuri suplimentare. De asemenea, ESP32 este montat pe propria placă de perfecționare și capete de pin conectabile. Acest lucru facilitează schimbarea ESP32.

Nu uitați: dacă mergeți cu o antenă WiFi externă în locul celei încorporate, lipiți și jumperul de selecție a antenei de pe partea inferioară a plăcii ESP32-CAM.

Imprimați sigla superioară din fișierul DuvelBot.svg pe hârtie cu autocolant cu jet de cerneală (sau creați-o pe a dvs.) și sunteți gata de plecare!

Pasul 2: Programați robotul

Programează robotul
Programează robotul

Este recomandabil să programați robotul înainte de al închide, pentru a vă asigura că totul funcționează și că nu apare fum magic.

Aveți nevoie de următoarele instrumente software:

  • ID-ul Arduino,
  • Bibliotecile ESP32, SPIFFS (sistem de fișiere flash periferice seriale), biblioteca ESPAsync Webserver.

Acesta din urmă poate fi instalat urmând acest tutorial randomner până la și incluzând secțiunea „organizarea fișierelor dvs.”. Chiar nu aș putea să o explic mai bine.

Codul:

Codul meu poate fi găsit la:

  • O schiță Arduino DuvelBot.ino,
  • Un subfolder de date care conține fișierele care urmează să fie încărcate pe blițul ESP utilizând SPIFFS. Acest folder conține pagina web pe care va servi ESP (index.html), o imagine de logo care face parte din pagina web (duvel.png) și o foaie de stil în cascadă sau un fișier CSS (style.css).

Pentru a programa robotul:

  • Conectați convertorul USB-TTL așa cum se arată în schemă,
  • Fișier -> Deschidere -> accesați dosarul în care se află DuvelBot.ino.
  • Schimbați acreditările de rețea în schiță:

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

  • Tools -> Board -> "AI-Thinker ESP-32 CAM" și selectați portul serial adecvat pentru computerul dvs. (Tools -> Port -> ceva de genul / dev / ttyUSB0 sau COM4),
  • Deschideți monitorul serial în Arduino IDE, în timp ce apăsați butonul PROG (care trage IO0 jos), porniți robotul,
  • Verificați pe monitorul serial dacă ESP32 este gata pentru descărcare,
  • Închideți monitorul serial (în caz contrar nu reușește încărcarea SPIFFS),
  • Instrumente -> „ESP32 Sketch Data Upload” și așteptați să se termine,
  • Opriți și porniți din nou apăsând butonul PROG pentru a reveni la modul de programare,
  • Apăsați săgeata „Încărcare” pentru a programa schița și așteptați să se termine,
  • Deschideți monitorul serial și resetați ESP32 prin oprire / pornire,
  • Odată ce a pornit, notați adresa IP (ceva de genul 192.168.0.121) și deconectați robotul de la convertorul USB-TTL,
  • Deschideți un browser la această adresă IP. Ar trebui să vedeți interfața ca în imagine.
  • Opțional: setați adresa Mac a ESP32 la o adresă IP fixă în router (depinde de modul de lucru al routerului).

Asta e! Citiți mai departe dacă doriți să știți cum funcționează …

Pasul 3: Cum funcționează

Acum ajungem la partea interesantă: cum funcționează toate împreună?

Voi încerca să-l explic pas cu pas … dar vă rugăm să rețineți că Kajnjaps nu este un specialist în programare web. De fapt, învățarea unui pic de programare web a fost întreaga premisă a construirii DuvelBot. Dacă fac greșeli evidente, vă rog să lăsați un comentariu!

Ok, după ce ESP32 este pornit, ca de obicei în configurare, inițializează GPIO-urile, le asociază cu temporizatoare PWM pentru controlul motorului și LED-urilor. Vedeți aici pentru mai multe despre comanda motorului, este destul de standard.

Apoi camera este configurată. Am menținut deliberat rezoluția destul de scăzută (VGA sau 640x480) pentru a evita răspunsul lent. Rețineți că placa AI-Thinker ESP32-CAM are un cip serial ram (PSRAM) pe care îl folosește pentru a stoca cadre de cameră cu rezoluție mai mare:

if (psramFound ()) {Serial.println ("PSRAM găsit."); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; // numărul de framebuffers vezi: https://github.com/espressif/esp32-camera} else {Serial.println ("nu s-a găsit PSRAM."); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }

Apoi, sistemul de fișiere flash periferice seriale (SPIFFS) este inițializat:

// inițializează SPIFFS if (! SPIFFS.begin (true)) {Serial.println ("A apărut o eroare la montarea SPIFFS!"); întoarcere; }

SPIFFS acționează ca un mic sistem de fișiere pe ESP32. Aici este folosit pentru a stoca trei fișiere: pagina web în sine index.html, un fișier în cascadă style.css și o imagine-p.webp

Apoi ESP32 se conectează la router (nu uitați să vă setați acreditările înainte de încărcare):

// modificați acreditările routerului dvs. hereconst char * ssid = "yourNetworkSSIDHere"; const char * password = "yourPasswordHere"; … // conectați-vă la WiFi Serial.print („Conectarea la WiFi”); WiFi.begin (ssid, parolă); while (WiFi.status ()! = WL_CONNECTED) {Serial.print ('.'); întârziere (500); } // acum conectat la router: ESP32 are acum adresa IP

Pentru a face ceva util, pornim un server web asincron:

// creați un obiect AsyncWebServer pe portul 80AsyncWebServer server (80); … server.begin (); // începeți să ascultați conexiunile

Acum, dacă introduceți adresa IP care a fost atribuită ESP32 de către router în bara de adrese a browserului, ESP32 primește o cerere. Acest lucru înseamnă că ar trebui să răspundă clientului (dvs. sau browserului dvs.) oferindu-i ceva, de exemplu o pagină web.

ESP32 știe cum să răspundă, deoarece în configurare răspunsurile la toate cererile permise posibile au fost înregistrate folosind server.on (). De exemplu, pagina principală sau indexul (/) este gestionat astfel:

server.on ("/", HTTP_GET, (cerere AsyncWebServerRequest *) {Serial.println ("/ cerere primită!"); request-> send (SPIFFS, "/index.html", String (), false, procesor);});

Deci, dacă clientul se conectează, ESP32 răspunde prin trimiterea fișierului index.html din sistemul de fișiere SPIFFS. Procesorul de parametri este numele unei funcții care preprocesează html și înlocuiește orice etichete speciale:

// Înlocuiește substituenții din html ca% DATA% // cu variabilele pe care doriți să le arătați //

Date:% DATA%

Procesor șir (const String & var) {if (var == "DATA") {//Serial.println("in procesor! "); return String (dutyCycleNow); } return String ();}

Acum, permiteți disecarea paginii web index.html în sine. În general, există întotdeauna trei părți:

  1. cod html: ce elemente ar trebui afișate (butoane / text / glisante / imagini etc.),
  2. cod de stil, fie într-un fișier separat.css, fie într-o secțiune …: cum ar trebui să arate elementele,
  3. javascript a … secțiune: cum ar trebui să acționeze pagina web.

Odată ce index.html se încarcă în browser (care știe că este html din cauza liniei DOCTYPE), acesta rulează în această linie:

Aceasta este o cerere pentru o foaie de stil CSS. Locația acestei foi este dată în href = "…". Deci, ce face browserul dvs.? Bine, lansează o altă cerere către server, de data aceasta pentru style.css. Serverul captează această solicitare, deoarece a fost înregistrată:

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

Neat nu? De altfel, ar fi putut fi href = "/ some / file / on / the / other / side / of / the / moon", pentru tot browserul tău. Ar fi preluat acel fișier la fel de fericit. Nu voi explica despre foaia de stil, deoarece controlează doar aspectele, deci nu este chiar interesant aici, dar dacă doriți să aflați mai multe, consultați acest tutorial.

Cum apare logo-ul DuvelBot? În index.html avem:

la care ESP32 răspunde cu:

server.on ("/ duvel", HTTP_GET, (cerere AsyncWebServerRequest *) {Serial.println ("s-a primit solicitarea logo duvel!"); ");});

..un alt fișier SPIFFS, de data aceasta o imagine completă, așa cum este indicat de „imagine / png” în răspuns.

Acum ajungem la partea cu adevărat interesantă: codul pentru butoane. Să ne concentrăm pe butonul FORWARD:

REDIRECŢIONA

Numele class = "…" este doar un nume care îl conectează la foaia de stil pentru a personaliza dimensiunea, culoarea etc. Părțile importante sunt onmousedown = "toggleCheckbox ('forward')" și onmouseup = "toggleCheckbox ('stop') ". Acestea constituie acțiunile butonului (același lucru pentru ontouchstart / ontouchend, dar pentru aceasta sunt ecranele tactile / telefoanele). Aici, acțiunea buton apelează o funcție toggleCheckbox (x) în secțiunea javascript:

funcție toggleCheckbox (x) {var xhr = new XMLHttpRequest (); xhr.open ("GET", "/" + x, adevărat); xhr.send (); // am putea face ceva și cu răspunsul când suntem gata, dar noi nu facem}

Prin urmare, apăsând butonul înainte, rezultă imediat apelarea toggleCheckbox („înainte”). Această funcție lansează apoi un XMLHttpRequest "GET", al locației "/ forward", care acționează exact ca și cum ați fi tastat 192.168.0.121/forward în bara de adrese a browserului. Odată ce această solicitare ajunge la ESP32, aceasta este tratată de:

server.. );});

Acum, ESP32 răspunde pur și simplu cu un text „OK înainte”. Rețineți că toggleCheckBox () nu face nimic cu (sau așteaptă) acest răspuns, totuși ar putea după cum se arată mai târziu în codul camerei.

În sine, în timpul acestui răspuns, programul setează doar o acțiune variabilă Now = FORWARD, ca răspuns la apăsarea butonului. Acum, în mainloop-ul programului, această variabilă este monitorizată cu scopul de a crește / descinde PWM-ul motoarelor. Logica este: atâta timp cât avem o acțiune care nu este STOP, ridicăm motoarele în acea direcție până când se atinge un anumit număr (dutyCycleMax). Apoi, mențineți această viteză, atâta timp cât actionNow nu s-a schimbat:

bucla void () {currentMillis = millis (); if (currentMillis - previousMillis> = dutyCycleStepDelay) {// salvați ultima dată când ați executat bucla previousMillis = currentMillis; // mainloop este responsabil pentru ascensiunea / coborârea motoarelor dacă (actionNow! = previousAction) {// ramp down, then stop, then change action and ramp up dutyCycleNow = dutyCycleNow-dutyCycleStep; if (dutyCycleNow <= 0) {// if after ramping down dc is 0, seted on the new direction, start from min dutycycle setDir (actionNow); action precedent = actionNow; dutyCycleNow = dutyCycleMin; }} else // actionNow == previousAction ramp up, exceptie cand directia este STOP {if (actionNow! = STOP) {dutyCycleNow = dutyCycleNow + dutyCycleStep; if (dutyCycleNow> dutyCycleMax) dutyCycleNow = dutyCycleMax; } else dutyCycleNow = 0; } ledcWrite (pwmChannel, dutyCycleNow); // reglați ciclul motor}}

Acest lucru crește încet viteza motoarelor, în loc să se lanseze la viteză maximă și să vărseze prețioasa și prețioasa Duvel. O îmbunătățire evidentă ar fi mutarea acestui cod într-o rutină de întrerupere a temporizatorului, dar funcționează așa cum este.

Acum, dacă eliberăm butonul de redirecționare, browserul dvs. apelează toggleCheckbox („oprire”), rezultând o solicitare de GET / stop. ESP32 setează actionNow să STOP (și răspunde cu „OK stop”), care deschide mainloop-ul pentru a roti motoarele.

Dar LED-urile? Același mecanism, dar acum avem un glisor:

În javascript, setarea glisorului este monitorizată, astfel încât la fiecare modificare apare un apel pentru a obține „/ LED / xxx”, unde xxx este valoarea luminozității la care LED-urile ar trebui să fie setate:

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; }

Rețineți că am folosit document.getElementByID ('slide') pentru a obține obiectul glisor în sine, care a fost declarat cu și că valoarea este trimisă unui element de text cu fiecare modificare.

Handlerul din schiță captează toate cererile de luminozitate utilizând „/ LED / *” în înregistrarea handlerului. Apoi ultima parte (un număr) este împărțită și aruncată într-un int:

server.on ("/ LED / *", HTTP_GET, (cerere AsyncWebServerRequest *) {Serial.println ("cerere led primită!"); setLedBrightness ((request-> url ()). substring (5).toInt ()); request-> send (200, "text / simplu", "OK Leds.");});

Similar cu cele descrise mai sus, butoanele radio controlează variabilele care stabilesc valorile implicite PWM, astfel încât DuvelBot să poată conduce încet către tine cu bere, având grijă să nu vărsăm aurul lichid și să revină rapid în bucătărie pentru a aduce mai multe.

… Deci, cum se actualizează imaginea camerei fără a fi nevoie să reîmprospătați pagina? Pentru aceasta folosim o tehnică numită AJAX (Asynchronous JavaScript și XML). Problema este că în mod normal o conexiune client-server urmează o procedură fixă: clientul (browserul) face cerere, serverul (ESP32) răspunde, cazul este închis. Terminat. Nu se mai întâmplă nimic. Dacă doar cumva am putea păcăli browserul să solicite în mod regulat actualizări de la ESP32 … și exact asta vom face cu această bucată de 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) {// vezi: 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); // creați un obiect din blob document.querySelector ("# camimage"). src = imageUrl; urlCreator.revokeObjectURL (imageurl)}}; xhttp.send ();}, 250);

setInterval ia ca parametru o funcție și o execută din când în când (aici o dată la 250 ms rezultând 4 cadre / secundă). Funcția care este executată face o cerere pentru un „blob” binar la adresa / CAMERA. Acest lucru este tratat de ESP32-CAM în schiță ca (de la Randomnerdtutorials):

server. * _jpg_buf = NULL; // capture a frame fb = esp_camera_fb_get (); if (! fb) {Serial.println ("Frame buffer could not be acquired"); return;} if (fb-> format! = PIXFORMAT_JPEG) / / deja în acest format din config {bool jpeg_converted = frame-j.webp

Părțile importante sunt obținerea cadrului fb = esp_camera_fb_get () convertirea acestuia într-un-j.webp

Funcția javascript așteaptă apoi să sosească această imagine. Apoi este nevoie de un pic de muncă pentru a converti „blob-ul” primit într-o adresă URL care poate fi utilizată ca sursă pentru a actualiza imaginea în pagina html.

uf, am terminat!

Pasul 4: Idei și resturi

Idei și resturi
Idei și resturi

Scopul acestui proiect pentru mine a fost să învăț suficientă programare web pentru a interfața hardware-ul pe web. Sunt posibile mai multe extensii la acest proiect. Iată câteva idei:

  • Implementați fluxul de camere „real” așa cum este explicat aici și aici și mutați-l pe un al doilea server așa cum este explicat aici pe același ESP32, dar pe celălalt nucleu CPU, apoi importați camera video în html servit de primul server folosind un … Acest lucru ar trebui să conducă la actualizări mai rapide ale camerei.
  • Utilizați modul punct de acces (AP), astfel încât robotul să fie mai independent, așa cum este explicat aici.
  • Extindeți-vă cu măsurarea tensiunii bateriei, capacități de somn profund etc. Acest lucru este puțin dificil în acest moment, deoarece AI-Thinker ESP32-CAM nu are multe GPIO-uri; are nevoie de expansiune prin uart și de exemplu un arduino sclav.
  • Transformați-vă într-un robot care caută pisici, care scoate din când în când mâncăruri de pisici, apăsând pe butonul unui buton mare, transmiteți în flux multe tone de poze frumoase ale pisicii în timpul zilei …

Vă rugăm să comentați dacă v-a plăcut sau aveți întrebări și vă mulțumim pentru lectură!

Recomandat: