Съдържание:

DuvelBot - робот за сервиране на бира ESP32 -CAM: 4 стъпки (със снимки)
DuvelBot - робот за сервиране на бира ESP32 -CAM: 4 стъпки (със снимки)

Видео: DuvelBot - робот за сервиране на бира ESP32 -CAM: 4 стъпки (със снимки)

Видео: DuvelBot - робот за сервиране на бира ESP32 -CAM: 4 стъпки (със снимки)
Видео: Заряжай! с 0 до Мастера Спорта. Методика БКМ. #tabletennis #настольныйтеннис #multiball 2024, Ноември
Anonim
DuvelBot - робот за сервиране на бира ESP32 -CAM
DuvelBot - робот за сервиране на бира ESP32 -CAM

След тежък работен ден нищо не се доближава до отпиването на любимата ви бира на дивана. В моя случай това е белгийската руса бира "Duvel". Въпреки това, след като се срутим, ние се сблъскваме с най -сериозен проблем: хладилникът, съдържащ моя Duvel, е непреодолим 20 фута, изваден от дивана.

Докато лека принуда от моя страна би могла да накара някой тийнейджър за почистване на хладилник да излее моята седмична добавка за Duvel, задачата да я доставя на почти изтощената си предшественица очевидно е една крачка твърде далеч.

Време е да извадите поялника и клавиатурата …

DuvelBot е безпроблемна уеб камера за базиране на AI-Thinker ESP32-CAM, която можете да контролирате от вашия смартфон, браузър или таблет.

Лесно е да се адаптира или разшири тази платформа за по -малко алкохолни употреби (помислете за SpouseSpy, NeighbourWatch, KittyCam …).

Създадох този робот главно, за да науча малко за цялото уеб програмиране и IoT неща, за които не знаех нищо. Така че в края на тази инструкция е подробно обяснение как работи това.

Много части от тази инструкция се основават на отличните обяснения, намерени в уроците за случайни глупаци, така че, моля, отидете да ги посетите!

Консумативи

От какво имаш нужда:

Списъкът с части не е издълбан в камък и много части могат да бъдат получени в много различни версии и от много различни места. Най-много закупих от Ali-Express. Както каза Мачете: импровизирайте.

Хардуер:

  • AI Thinker ESP32-CAM модул. Вероятно може да работи с други модули ESP32-CAM, но това използвах
  • L298N платка за водача на двигателя,
  • Евтина 4-колесна платформа за роботика,
  • Корпус с голяма равна повърхност като Hammond Electronics 1599KGY,
  • USB към 3.3V-TTL конвертор за програмиране.
  • За осветлението: 3 бели светодиода, BC327 или друг транзистор с общо предназначение NPN (Ic = 500mA), резистор 4k7k, 3 резистора 82Ohm, перфорирана плоскост, кабели (вижте схеми и снимки).
  • Превключвател за включване/изключване и нормално отворен бутон за програмиране.

По избор:

  • Камера с рибешко око с по-дълго огъване от стандартната камера OV2460, предоставена с модула ESP32-CAM,
  • WiFi антена с подходящо дълъг кабел и ултра миниатюрен коаксиален конектор, като този. ESP32-CAM има вградена антена, а корпусът е пластмасов, така че антена всъщност не е необходима, но си мислех, че изглежда страхотно, така че …
  • Мастилено -струйна хартия за стикери за дизайн на горния капак.

Обичайните хардуерни инструменти: поялник, бормашини, отвертки, клещи …

Стъпка 1: Изграждане на платформата за роботи

Изграждане на платформа за роботи
Изграждане на платформа за роботи
Изграждане на платформа за роботи
Изграждане на платформа за роботи
Изграждане на платформа за роботи
Изграждане на платформа за роботи

Схемата:

Схемата не е нищо особено. Камерата ESP32 управлява двигателите чрез платката на драйвера на двигателя L298N, която има два канала. Двигателите от лявата и дясната страна са разположени успоредно и всяка страна заема един канал. Четири малки 10..100nF керамични кондензатора в близост до щифтовете на двигателя са както винаги препоръчителни за противодействие на RF смущения. Също така, голяма електролитна капачка (2200… 4700uF) на захранването на платката на двигателя, както е показано на схемата, макар и да не е строго необходима, може да ограничи малко пулсациите на захранващото напрежение (ако искате да видите филм на ужасите, след това сондирайте Vbat с осцилоскоп, докато двигателите са активни).

Обърнете внимание, че и двата пина ENABLE на каналите на двигателя се задвижват от един и същ щифт с широчина на импулса (PWM) на ESP32 (IO12). Това е така, защото модулът ESP32-CAM няма много GPIO (схемата на модула е включена за справка). Светодиодите на робота се задвижват от IO4, който също задвижва вградения светодиод на светкавицата, така че премахнете Q1, за да предотвратите светването на светодиода в затворен корпус.

Бутонът за програмиране, превключвателят за включване/изключване, конекторът за зареждане и конекторът за програмиране са достъпни под робота. Можех да свърша много по -добра работа за конектора за програмиране (3,5 мм жак?), Но бирата вече не можеше да чака. Също така актуализациите по въздуха (OTA) би било хубаво да се настроят.

За да поставите робота в режим на програмиране, натиснете бутона за програмиране (това дърпа IO0 ниско) и след това го включете.

Важно: за да заредите NiMH батериите на робота, използвайте лабораторен комплект (разтоварен) до около 14V и ток, ограничен до 250mA. Напрежението ще се адаптира към напрежението на батериите. Изключете, ако роботът е горещ или напрежението на батерията достигне около 12,5V. Очевидно подобрение тук би било интегрирането на подходящо зарядно устройство за батерии, но това е извън обхвата на тази инструкция.

Хардуерът:

Моля, вижте и бележките в снимките. Корпусът е монтиран на основата на робота с помощта на 4 болта M4 и самозаключващи се гайки. Обърнете внимание на гумените тръби, използвани като дистанционни елементи. Надяваме се, че това също дава известно окачване на Duvel, ако пътуването се окаже неравномерно. Модулът ESP32-CAM и моторната платка L298N са монтирани в корпуса с помощта на пластмасови лепкави крачета (не съм сигурен за правилното име на английски), за да се предотврати необходимостта от пробиване на допълнителни дупки. Също така ESP32 е монтиран на собствена перфорирана дъска и щепселни щифтове. Това улеснява смяната на ESP32.

Не забравяйте: ако ще използвате външна WiFi антена вместо вградената, тогава запойте и джъмпера за избор на антена от долната страна на платката ESP32-CAM.

Разпечатайте горното лого във файла DuvelBot.svg върху мастилено -струйна хартия за стикери (или проектирайте своя собствена) и сте готови!

Стъпка 2: Програмирайте робота

Програмирайте робота
Програмирайте робота

Препоръчително е да програмирате робота, преди да го затворите, за да сте сигурни, че всичко работи и няма да се появи вълшебен дим.

Нуждаете се от следните софтуерни инструменти:

  • IDE на Arduino,
  • Библиотеките ESP32, SPIFFS (серийна периферна флаш файлова система), ESPAsync библиотека за уеб сървър.

Последното може да бъде инсталирано, като следвате този randomnerdtutorial до и включително секцията „организиране на вашите файлове“. Наистина не бих могъл да го обясня по -добре.

Кодът:

Моят код може да бъде намерен на:

  • Скица на Arduino DuvelBot.ino,
  • Подпапка с данни, която съдържа файловете, които ще бъдат качени на ESP флаш с помощта на SPIFFS. Тази папка съдържа уеб страницата, която ESP ще обслужва (index.html), изображение на лого, което е част от уеб страницата (duvel.png) и каскаден стилов лист или CSS файл (style.css).

За да програмирате робота:

  • Свържете USB-TTL конвертора, както е показано на схемата,
  • Файл -> Отваряне -> отидете в папката, където се намира DuvelBot.ino.
  • Променете вашите мрежови идентификационни данни в скицата:

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

  • Инструменти -> Board -> "AI -Thinker ESP -32 CAM" и изберете подходящия сериен порт за вашия компютър (Tools -> Port -> нещо като /dev /ttyUSB0 или COM4),
  • Отворете серийния монитор в Arduino IDE, Докато натискате бутона PROG (който дърпа IO0 ниско), включете робота,
  • Проверете на серийния монитор дали ESP32 е готов за изтегляне,
  • Затворете серийния монитор (в противен случай качването на SPIFFS е неуспешно),
  • Инструменти -> „ESP32 Sketch Data Upload“и изчакайте да приключи,
  • Изключете и включете отново, като задържите бутона PROG, за да се върнете в режим на програмиране,
  • Натиснете стрелката „Качване“, за да програмирате скицата и изчакайте да завърши,
  • Отворете серийния монитор и нулирайте ESP32, като изключите/включите,
  • След като се стартира, запишете ip адреса (нещо като 192.168.0.121) и изключете робота от USB-TTL конвертора,
  • Отворете браузър на този ip адрес. Трябва да видите интерфейса, както е на снимката.
  • По избор: задайте mac-адреса на ESP32 на фиксиран ip адрес във вашия рутер (зависи от маршрутизатора как да го направите).

Това е! Прочетете, ако искате да знаете как работи …

Стъпка 3: Как работи

Сега стигаме до интересната част: как всичко това работи заедно?

Ще се опитам да го обясня стъпка… по… стъпка, но имайте предвид, че Kajnjaps не е специалист по уеб програмиране. Всъщност изучаването на малко уеб програмиране беше цялата предпоставка за изграждането на DuvelBot. Ако направя очевидни грешки, моля, оставете коментар!

Добре, след като ESP32 е включен, както обикновено в настройката, той инициализира GPIO, свързва ги с PWM таймери за управление на двигателя и LED. Вижте тук за повече информация относно управлението на двигателя, това е доста стандартно.

След това камерата се конфигурира. Умишлено поддържах резолюцията доста ниска (VGA или 640x480), за да избегна бавен отговор. Обърнете внимание, че платката AI-Thinker ESP32-CAM има сериен RAM чип (PSRAM), който използва за съхраняване на рамки на камерите с по-голяма разделителна способност:

if (psramFound ()) {Serial.println ("PSRAM е намерен."); config.frame_size = FRAMESIZE_VGA; config.jpg_quality = 12; config.fb_count = 2; // брой рамкови буфери вижте: https://github.com/espressif/esp32-camera} else {Serial.println ("не е намерен PSRAM."); config.frame_size = FRAMESIZE_QVGA; config.jpg_quality = 12; config.fb_count = 1; }

След това серийната периферна флаш файлова система (SPIFFS) се инициализира:

// инициализира SPIFFS if (! SPIFFS.begin (true)) {Serial.println ("Възникна грешка при монтирането на SPIFFS!"); връщане; }

SPIFFS действа като малка файлова система на ESP32. Тук той се използва за съхраняване на три файла: самата уеб страница index.html, каскадна таблица със стилове на файла style.css и лого с изображение-p.webp

След това ESP32 се свързва с вашия рутер (не забравяйте да зададете идентификационните си данни преди качването):

// промяна на идентификационните данни на вашия рутер hereconst char* ssid = "yourNetworkSSIDHere"; const char* password = "yourPasswordHere"; … // свързване към WiFi Serial.print („Свързване към WiFi“); WiFi.begin (ssid, парола); while (WiFi.status ()! = WL_CONNECTED) {Serial.print ('.'); забавяне (500); } // сега свързан с рутера: ESP32 вече има ip адрес

За да направим нещо полезно, стартираме асинхронен уеб сървър:

// създаваме обект AsyncWebServer на порт 80AsyncWebServer сървър (80); … Server.begin (); // започнете да слушате за връзки

Сега, ако въведете ip адреса, който е присвоен на ESP32 от рутера в адресната лента на браузъра, ESP32 получава заявка. Това означава, че той трябва да отговори на клиента (вие или вашият браузър), като му сервира нещо, например уеб страница.

ESP32 знае как да отговори, тъй като при настройката отговорите на всички възможни разрешени заявки са регистрирани с помощта на server.on (). Например основната уеб страница или индекс (/) се обработват по следния начин:

server.on ("/", HTTP_GET, (AsyncWebServerRequest *заявка) {Serial.println ("/заявката е получена!"); request-> send (SPIFFS, "/index.html", String (), false, процесор);});

Така че, ако клиентът се свърже, ESP32 отговаря, като изпраща файла index.html от файловата система SPIFFS. Процесорът на параметри е името на функция, която предварително обработва html и замества всички специални тагове:

// Заменя заместителите в html като %DATA %// с променливите, които искате да покажете //

Данни: %DATA %

Низов процесор (const String & var) {if (var == "DATA") {//Serial.println("in процесор! "); връщащ низ (dutyCycleNow); } връщане на низ ();}

Сега нека разглобим самата уеб страница index.html. Като цяло винаги има три части:

  1. html код: кои елементи трябва да се показват (бутони/текст/плъзгачи/изображения и т.н.),
  2. стил код, или в отделен.css файл, или в … раздел: как трябва да изглеждат елементите,
  3. javascript a… раздел: как трябва да действа уеб страницата.

След като index.html се зареди в браузъра (който знае, че е html поради реда DOCTYPE), той се сблъсква с този ред:

Това е заявка за лист със стил css. Местоположението на този лист е дадено в href = "…". И така, какво прави вашият браузър? Добре, той стартира друга заявка към сървъра, този път за style.css. Сървърът улавя тази заявка, защото е регистрирана:

server.on ("/style.css", HTTP_GET, (AsyncWebServerRequest *заявка) {Serial.println ("получена css заявка"); request-> send (SPIFFS, "/style.css", "text/css ");});

Чисто а? Между другото, можеше да е href = "/some/file/on/the/other/side/of/the/moon", за всичките ви браузъри. Щеше да извлече този файл също толкова щастливо. Няма да обяснявам за стиловата таблица, тъй като тя само контролира външния вид, така че не е наистина интересно тук, но ако искате да научите повече, разгледайте този урок.

Как се появява логото на DuvelBot? В index.html имаме:

на което ESP32 отговаря с:

server.on ("/duvel", HTTP_GET, (AsyncWebServerRequest *заявка) {Serial.println ("получена заявка за лого на duvel!"); request-> send (SPIFFS, "/duvel.png", "image-p.webp

..още един SPIFFS файл, този път цялостно изображение, както е посочено от "image/png" в отговора.

Сега стигаме до наистина интересната част: кодът за бутоните. Нека се съсредоточим върху бутона НАПРЕД.

НАПРЕД

Името class = "…" е само име, което го свързва със стиловата таблица, за да персонализира размера, цвета и т.н. Важните части са onmousedown = "toggleCheckbox ('напред')" и onmouseup = "toggleCheckbox ('стоп') ". Те представляват действията на бутона (същото за ontouchstart/ontouchend, но за това са сензорни екрани/телефони). Тук действието на бутона извиква функция toggleCheckbox (x) в секцията javascript:

функция toggleCheckbox (x) {var xhr = нов XMLHttpRequest (); xhr.open ("GET", "/" + x, true); xhr.send (); // би могъл да направи нещо с отговора, когато е готов, но не го правим}

Така че натискането на бутона напред, веднага води до извикване на toggleCheckbox ('напред'). След това тази функция стартира XMLHttpRequest "GET", на местоположението "/forward", което действа точно като ако сте въвели 192.168.0.121/forward в адресната лента на браузъра си. След като тази заявка пристигне в ESP32, тя се обработва от:

server.on ("/forward", HTTP_GET, (AsyncWebServerRequest *заявка) {Serial.println ("получено/препращане"); actionNow = НАПРЕД; request-> send (200, "text/plain", "OK напред. ");});

Сега ESP32 просто отговаря с текст "OK напред". Забележка: toggleCheckBox () не прави нищо с (или изчакайте) този отговор, но може, както е показано по -късно в кода на камерата.

Сама по себе си по време на този отговор програмата задава само променлива actionNow = НАПРЕД, като отговор на натискане на бутона. Сега в основната верига на програмата тази променлива се следи с цел увеличаване/намаляване на ШИМ на двигателите. Логиката е: стига да имаме действие, което не е СТОП, усилвайте двигателите в тази посока, докато се достигне определен брой (dutyCycleMax). След това поддържайте тази скорост, стига да не се е променило actionNow:

void loop () {currentMillis = millis (); if (currentMillis - previousMillis> = dutyCycleStepDelay) {// запишете последния път, когато сте изпълнявали цикъла previousMillis = currentMillis; // mainloop е отговорен за ускоряване нагоре/надолу на двигателите, ако (actionNow! = previousAction) {// наклоните надолу, след това спрете, след това променете действието и увеличете dutyCycleNow = dutyCycleNow-dutyCycleStep; if (dutyCycleNow <= 0) {// ако след спускане dc е 0, зададено на новата посока, започнете от мин. работен цикъл setDir (actionNow); previousAction = actionNow; dutyCycleNow = dutyCycleMin; }} else // actionNow == previousAction се увеличава, освен когато посоката е STOP {if (actionNow! = STOP) {dutyCycleNow = dutyCycleNow+dutyCycleStep; if (dutyCycleNow> dutyCycleMax) dutyCycleNow = dutyCycleMax; } else dutyCycleNow = 0; } ledcWrite (pwmChannel, dutyCycleNow); // коригирайте работния цикъл на мотора}}

Това бавно увеличава скоростта на двигателите, вместо просто да стартира с пълна скорост и да разлее скъпоценния скъпоценен Duvel. Очевидно подобрение би било преместването на този код в програма за прекъсване на таймера, но тя работи както е.

Сега, ако пуснем бутона за пренасочване, браузърът ви извиква toggleCheckbox („стоп“), което води до заявка за GET /stop. ESP32 задава actionNow на STOP (и отговаря с "OK stop."), Което въвежда главната верига да върти надолу двигателите.

Ами светодиодите? Същият механизъм, но сега имаме плъзгач:

В javascript се следи настройката на плъзгача, така че при всяка промяна се случва повикване за получаване на „/LED/xxx“, където xxx е стойността на яркостта, на която светодиодите трябва да бъдат настроени:

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

Обърнете внимание, че използвахме document.getElementByID ('slide'), за да получим самия обект на плъзгача, който е деклариран с и че стойността се извежда към текстов елемент при всяка промяна.

Манипулаторът в скицата улавя всички заявки за яркост, като използва "/LED/*" в регистрацията на манипулатора. След това последната част (число) се разделя и предава на int:

server.on ("/LED/ *", HTTP_GET, (AsyncWebServerRequest *заявка) {Serial.println ("получена led заявка!"); setLedBrightness ((request-> url ()). substring (5).toInt ()); request-> send (200, "text/plain", "OK Leds.");});

Подобно на описаното по -горе, бутоните за управление контролират променливите, които задават настройките по подразбиране на ШИМ, така че DuvelBot може да кара бавно към вас с бирата, като внимава да не разлее това течно злато, и бързо обратно в кухнята, за да донесе още.

… И така, как се актуализира изображението на камерата, без да се налага да опреснявате страницата? За това използваме техника, наречена AJAX (асинхронен JavaScript и XML). Проблемът е, че обикновено връзката клиент-сървър следва фиксирана процедура: клиентът (браузърът) прави заявка, сървърът (ESP32) отговаря, случаят е затворен. Свършен. Вече нищо не се случва. Ако само по някакъв начин бихме могли да накараме браузъра редовно да иска актуализации от ESP32 … и точно това ще направим с това парче 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) {// вижте: 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); // създайте обект от blob document.querySelector ("#camimage"). src = imageUrl; urlCreator.revokeObjectURL (imageurl)}}; xhttp.send ();}, 250);

setInterval приема като параметър функция и я изпълнява от време на време (тук веднъж на 250ms, което води до 4 кадъра/секунда). Функцията, която се изпълнява, прави заявка за двоично "blob" на адреса /CAMERA. Това се обработва от ESP32-CAM в скицата като (от Randomnerdtutorials):

server.on ("/CAMERA", HTTP_GET, (AsyncWebServerRequest * заявка) {Serial.println ("получена заявка за камера!"); camera_fb_t * fb = NULL; // esp_err_t res = ESP_OK; size_t _jpg_buf_len = 0; * _jpg_buf = NULL; // улавяне на кадър fb = esp_camera_fb_get (); if (! fb) {Serial.println ("Буферът на рамката не може да бъде придобит"); return;} if (fb-> format! = PIXFORMAT_JPEG)/ /вече в този формат от config {bool jpeg_converted = frame-j.webp

Важните части са получаването на рамката fb = esp_camera_fb_get () преобразуването й в-j.webp

След това функцията javascript чака това изображение да пристигне. След това е нужно само малко работа, за да преобразувате полученото „blob“в url, който може да се използва като източник за актуализиране на изображението с в html страницата.

ох, свършихме!

Стъпка 4: Идеи и остатъци

Идеи и остатъци
Идеи и остатъци

Целта на този проект за мен беше да науча достатъчно уеб програмиране, за да свържа хардуера към мрежата. Възможни са няколко разширения на този проект. Ето няколко идеи:

  • Приложете „истинско“поточно предаване на камера, както е обяснено тук и тук, и го преместете на 2 -ри сървър, както е обяснено тук на същия ESP32, но на другото ядро на процесора, след което импортирайте потока от камера в html, обслужван от първия сървър, използвайки…. Това би трябвало да доведе до по -бързи актуализации на камерата.
  • Използвайте режим на точка за достъп (AP), така че роботът да е по -самостоятелен, както е обяснено тук.
  • Разширете с измерване на напрежението на батерията, възможности за дълбок сън и т.н. Това е малко трудно в момента, защото AI-Thinker ESP32-CAM няма много GPIO; се нуждае от разширение чрез uart и например роб arduino.
  • Преобразувайте се в робот, търсещ котки, който от време на време изхвърля котешки лакомства с натискане на лапа на голям бутон, предавайте тонове хубави снимки на котки през деня …

Моля, коментирайте, ако ви е харесало или имате въпроси и благодаря за четенето!

Препоръчано: