VIDI X preuzima kontrolu nad drugim robotom. Kako Borg kaže: Resistance is futile!
Kompletan kod pronađite na linku: https://github.com/VidiLAB-com/Vidi-X/tree/master/VIDI%20X%20upravlja%20robotom
Stemi Hexapod je šesteronožni robot, kao i VIDI X mikroračunalo, proizveden u Hrvatskoj. Ako ste nabavili Stemi Hexapod robota te ga sastavili i pokrenuli, zasigurno ste otkrili da ga možete programirati za određene pokrete ili njime možete upravljati pomoću mobilne aplikacije.
No kako bismo proširili mogućnosti robota, povezat ćemo ga s VIDI X mikroračunalom. Kada su povezani, moguće je VIDI X mikroračunalo iskoristiti za upravljanje Hexapodom te mu naređivati što raditi tj. kuda se kretati.
Na ovaj način ne moramo razmišljati o programiranju svakog servo motora zasebno kako bi se robot pokrenuo nego vrlo kratkom i jednostavnom porukom zadajemo robotu što mora napraviti.
Mnogo je načina na koje se može postići simbioza o kojoj pišemo. Najjednostavniji je način putem serijske komunikacije.
Na serijsku smo se komunikaciju odlučili nakon što smo otkrili da Wi-Fi veza Hexsapoda ne radi kada učitamo biblioteku zaduženu za njegovo upravljanje. Problem s Wi-Fi mrežom vjerojatno nastaje zbog korištenja određenih GPIO pinova koji dijele funkcionalnost s pinovima zaduženima za Wi-Fi. Kasnije u tekstu bit će napisano više o tome.
Za ovu radionicu trebat će vam:
VIDI X mikroračunalo – dva komada. Jedno kao Master uređaj za upravljanje, a drugo kao Slave koji će upravljati Hexapod robotom
Stemi Heksapod – šesteronožni robot kojeg nakon što ga sastavite možete programirati
Wi-Fi antena – kako biste mogli koristiti ESP Now vezu na barem jedan VIDI X morate obavezno ugraditi Wi-Fi antenu. Ugradite li je na oba VIDI X-a, povećat ćete domet ESP Now komunikacije. Antenu možete kupiti putem linka: https://e-radionica.com/hr/wifi-2-4g-5g-antena-s-ipx-konektorom.html ili iskoristiti neku ugrađenu u stari laptop ili router.
Serijska komunikacija
Kada govorimo o programiranju mikrokontrolera prisutnih u VIDI X mikroračunalu ili Hexapod robotu, serijskom se komunikacijom najčešće šalju tekstualne poruke prema PC računalu s kojeg programirate. To su one poruke koje primate putem Serial Monitora (pokreće se kraticom CTRL+SHIFT+M u Arduino IDE razvojnom okruženju).
Više o tome kako radi serijska komunikacija možete pročitati u radionici na linku https://hr.vidi-x.org/radionice/vidi-project-x-92-serijska-komunikacija/
Shema spajanja Stemi Hexapoda i VIDI X mikroračunala
Na ovoj shemi možete primijetiti kako VIDI X napajamo baterijom Hexapoda što je vrlo zgodno rješenje kako ne bismo morali koristiti dva izvora napajanja. Iako u nekim situacijama korištenje dva izvora napajanja može biti od koristi. No ovako s jednom baterijom imamo i manje tereta za nositi na robotu. Ukupna je masa bitna kada govorimo o potrošnji električne energije, pa bi u nekim slučajevima moglo biti da nam dva izvora napajanja ne bi znatno pomogla zbog potrošnje električne energije na nošenje ukupne mase oba napajanja.
Iako UART serijsku komunikaciju definiramo s dva pina, mi ćemo spojiti samo jedan pin jer nam treba jednosmjerna komunikacija. Tako ćemo s VIDI X mikroračunala samo slati podatke, dok će ih Hexapod samo primati.
Znači Tx PIN VIDI X-a spajamo s Rx pinom Hexapoda. Osim toga treba nam GND–GND konekcija te žica napajanja koju spajamo s Vbat Hexapoda na VIN VIDI X mikroračunala.
Kada je sve ovako spojeno potrebno je pripaziti na činjenicu da se Hexapod i VIDI X mogu napajati putem USB kabela, pa nije pametno imati spojeno istovremeno i USB prema računalu i Vbat Hexapoda na VIN PIN. Isto tako, dok je spojena žica na GPIO4 VIDI X-a, na njega nećete moći uploadati kod.
Iz tog razloga najbolje je prvo uploadati kod pa onda spojiti sve žice. Koristite li USB konekciju prema PC-u, prekinite vezu Vbat Hexapoda na VIN VIDI X mikroračunala jer oba uređaja već imaju napajanje putem USB konekcije s PC-jem.
Kod za Hexapod
Biblioteka koja vam je potrebna za korištenje Hexapoda nalazi se na linku: https://github.com/stemi-education/stemi-hexapod
Instalirali smo Hexapod.h biblioteku verzije 2.0.10 te smo uz korištenje uputa koje pišu na GitHub linku pokušali uploadati Default demo kod koji dolazi uz biblioteku.
Nakon paljenja robota, počeo se trzati, srećom, samo jednom nogom, inače bi se tako mogao potrgati. Serijska konzola pokazivala je konstantan reboot sustava. Serijska konzola Arduino IDE razvojnog okruženja radi i kada je Hexapod ugašen, ali spojen USB kabelom, pa je i to zgodan način kako provjeriti reboota li se heksapod prije samog paljenja, a sa svrhom očuvanja njegovih nogu koje se nekontroliranim mahanjem mogu slomiti. Nakon puno pokušaja i promašaja pronašli smo rješenje. Greška je bila u verziji ESP32 podrške koju smo koristili.
Bilo je potrebno putem Boards Managera reinstalirati verziju podrške za ESP32 mikrokontroler te smo otkrili kako je najveća funkcionalna verzija 1.0.4, pa smo nju instalirali.
Kada nam je proradila Default skica, pokušali smo napravit vlastitu. Sve je bilo okej dok nismo pokušali uključiti Wi-Fi na Hexapodu. Korištenje Wi-Fi-ja ponovno je uzrokovalo beskonačni restart.
Dio problema javlja se radi mogućeg konflikta u pinovima koji se koriste kada je Wi-Fi upaljen, a dio može biti vezan uz Arduino IDE i podršku za ESP32.
Kako je gotovo nemoguće otkriti kombinaciju biblioteka za Hexapod, Wi-Fi te podrške za ESP32 koja bi radila stabilno – odlučili smo se za UART komunikaciju.
Kako bi Hexapod primao naredbe, trebamo isprogramirati skicu koja na osnovu primljene naredbe reagira. To smo učinili ovako:
//Definiramo pinove za serijsku komunikaciju #define RXD2 4 #define TXD2 2 void setup() { // postavljamo brzinu i vrstu seriske komunikacije na ranije definirane pinove Serial.begin(115200); Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); … } void loop() { if (Serial2.available()) //check incoming on default serial (USB) from PC { int a = Serial2.read(); Serial.println(a); //Ispisujemo primljenu vrijednost kako bi vidjeli vrijednost koja treba stajati kod if uvjeta if ( a == 54) { robot.setHeight(50); n = 0; } else if (a == 53) …
Putem if uvjeta na primljenu poruku pokrećemo određenu radnju. U gorenjem primjeru, primljena poruka 54 odgovara naredbi char(54) što je zapravo ASCII kôd znamenke „6“. Pokrenemo naredbu robot.setHeight(50); koja će robota postaviti na pola njegove visine.
Nastavljamo s else if uvjetom koji provjerava je li primljena poruka znamenka „5“ tj. char(53) kako bi Hexapod odradio neku drugu radnju.
Kompletnu skicu za Hexapod pronađite na GitHub linku: https://github.com/VidiLAB-com/Vidi-X/tree/master/VIDI%20X%20upravlja%20robotom/Stemi_Hexapod_Serial
Kod za VIDI X
VIDI X kod na sličan način šalje poruku na serijsku vezu.
Za VIDI X vam prilažemo dvije programske skice. Jedna će biti bez spomenutih Wi-Fi funkcija, dok će druga imati dio koda zadužen za Wi-Fi ESP Now komunikaciju. Tako ćete moći usporediti obje skice kako biste lakše pohvatali konce.
Skicu za VIDI X bez Wi-FI ESP Now implementacije pronađite na GitHub linku: https://github.com/VidiLAB-com/Vidi-X/tree/master/VIDI%20X%20upravlja%20robotom/VIDI_X_Serial2
Uz spomenutu skicu možete upravljati Hexapodom pritiskom na ugrađene gumbe VIDI X-a. Uz tu se programsku skicu možete uvjeriti da UART serijska komunikacija radi dobro te da Hexapod sluša zadane naredbe.
Prvo je potrebno inicijalizirati serijsku vezu:
#define RXD2 13 #define TXD2 4 void setup() { // Init Serial Monitor Serial.begin(115200); Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2); …
Nakon definiranja pinova i inicijalizacije serijske komunikacije putem if uvjeta, provjeravamo ja li stisnut gumb i ako je šaljemo odgovarajuću poruku:
if ( analogRead(gumb_B) == 0 ) { // || OR - digitalWrite(statusLED, HIGH); Serial2.println(“6”); /// Serial.read daje 54, Serial.println(“6”); }
Sada je potrebno VIDI X skicu isprogramirati kao Gateway za prosljeđivanje poruka. Time ćemo dobiti kontrolu nad robotom s udaljene lokacije.
Sada već zasigurno možete i sami uz pomoć ranije objavljenih tutorijala iskombinirati kod kao biste Hexapodom upravljali na razne načine.
Recimo uz tutorijal „Robot nadograđen Vidi Project X mikroračunalom“ na linku: https://hr.vidi-x.org/radionice/vidi-project-x-65laserski-senzor-udaljenosti-u-ulozi-pametnog-robota/ možete lako postići upravljanje Hexapodom putem Internet preglednika.
VIDI Project X #65:Laserski senzor udaljenosti u ulozi pametnog robota
Ili uz tutorijal „Multiplayer game TIC-TAC-TOE iliti Križić-Kružić“ na linku: https://hr.vidi-x.org/radionice/vidi-project-x-59-multiplayer-game-tic-tac-toe/
Mi ćemo vam sada pokazati kako možete upravljati Hexapodom uz pomoć ESP-Now protokola.
ESP-Now je protokol koji je razvio Espressif, a koji omogućuje da više uređaja međusobno komunicira bez korištenja Wi-Fi-ja. Protokol je sličan bežičnom povezivanju niske snage od 2,4 GHz koja se često koristi u bežičnim miševima. Uparivanje između uređaja potrebno je prije njihove komunikacije, a uparivanje se odvija putem razmjene MAC adresa uređaja. Nakon što je uparivanje obavljeno, veza je sigurna i ravnopravna, te nije potreban Handshake (rukovanje) kao što je to slučaj s Wi-Fi konekcijama.
Dakle u ovom ćemo slučaju trebati još jedan VIDI X koji će slati naredbe putem ESP-Now protokola na VIDI X koji je spojen s Hexapodom.
ESP-NOW vrlo je svestran i možete imati jednosmjernu ili dvosmjernu komunikaciju u različitim postavkama.
ESP-NOW podržava šifriranu ili nekriptiranu unicast komunikaciju, može se slati poruka veličine do 250 bajtova te možemo tražiti obavijest o uspjehu ili neuspjehu prijenosa.
ESP-NOW ima i neka ograničenja.
Podržano je najviše do 10 šifriranih ravnopravnih uređaja u načinu rada Station, a najviše 6 u načinu rada SoftAP.
Podržano je nekoliko nekriptiranih ravnopravnih uređaja, no njihov ukupan broj ne bi smio prelaziti 20.
Kako biste se pobliže upoznali s ESP NOW kodom, pogledajte skice Master i Slave iz Arduino IDE izbornika Datoteka → Primjeri → ESP32 → ESPNow → Basic.
Dakle za drugi VIDI X koji ćete koristiti kao daljinski upravljač tretirati ćemo kao Master uređaj te ćemo na osnovnu programsku skicu za upravljanje robotom putem UART-a jednostavno dodati kod za odašiljanje poruka ESP Now protokolom.
Skicu za Master VIDI X s ESP Now implementacijom pronađite na GitHub linku: https://github.com/VidiLAB-com/Vidi-X/tree/master/VIDI%20X%20upravlja%20robotom/VIDI_X_Master
U ovome kodu primijetite funkcije:
InitESPNow() – brine se da je ESPNow protokol pokrenut, ako nije slijedi restart pa ponovni pokušaj
ScanForSlave() – pronalazi primatelje imena Slave Wi-Fi mreže i bilježi njihove Mac adrese u memoriju
manageSlave() – spaja se na primatelje
deletePeer() – odspaja se s primatelja
sendData() – šalje poruku
Uz ovakvu programsku skicu, ESP Now Master će pregledati mrežu te uspostaviti komunikaciju s jednim pronađenim Slave uređajem. Zanimljiva nam je i ova posljednja funkcija zadužena za slanje poruke:
void sendData() { data = poruka; //data++; const uint8_t *peer_addr = slave.peer_addr; Serial.print(“Sending: “); Serial.println(data); esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data)); …
Kako biste lakše razumjeli kod zadržali smo integer varijablu data iz originalnog Master primjera za ESP Now komunikaciju, te u nju spremamo našu poruku.
U nastavku koda glavne petlje loop, potrebno je dodati spremanje naše poruke u varijablu. To i činimo u if funkcijama putem koda za provjeru je li stisnut neki gumb.
if ( analogRead(UP_DOWN) > 1700 && analogRead(UP_DOWN) < 2300 ) { // || OR - digitalWrite(statusLED, HIGH); Serial2.println(“2”); /// Serial.read daje 50 Serial.println(“2”); poruka = 50; }
Na kraju if uvjeta varijabli poruka dodjeljujemo vrijednost ASCII koda broja dva što je u ovom slučaju 50.
Finalna skica koda za spajanje VIDI X-a s Hexapodom
Finalnu skicu za VIDI X kao Slave ESP Now uređaj pronađite na linku:
https://github.com/VidiLAB-com/Vidi-X/tree/master/VIDI%20X%20upravlja%20robotom/VIDI_X_Slave
Pogledamo li osnovnu Slave skicu koda, primijetit ćete funkcije:
InitESPNow()
configDeviceAP()
OnDataRecv()
InitESPNow() – potpuno je ista kao i koda master primjera
configDeviceAP() – postavlja Wi-Fi imena “Slave_1” kako bi ga ranije spomenuti Master mogao raspoznati prema tom imenu te se spojiti na njega
OnDataRecv() – se brine o primljenim podatcima te ih sprema u pokazatelju (pointeru) *data
Pointer označavamo sa zvjezdicom (*) ispred imena, a označava memorijsku adresu na kojoj je spremljen podatak varijable. S toga uz pointer obično imamo i integer varibalu u kojoj je spremljena veličina poruke. To je data_len u našem slučaju.
// callback when data is recv from Master void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) { digitalWrite(statusLED, HIGH); char macStr[18]; snprintf(macStr, sizeof(macStr), “%02x:%02x:%02x:%02x:%02x:%02x”, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); Serial.print(“Last Packet Recv from: “); Serial.println(macStr); poruka = *data; Serial.print(“Last Packet Recv Data: “); Serial.println(poruka); Serial.println(“”); digitalWrite(statusLED, LOW); }
Radi lakšeg baratanja podatcima mi primljenu poruku spremamo u varijablu poruka.
poruka = *data;
Ostaje nam još jedino u glavnu petlju ubaciti kod koji će reagirati na primljenu poruku.
Ukoliko je poruka 50 što odgovara ASCII kodu znaka 2, pošali to na drugu serijsku konzolu koja se nalazi na samom Hexapod robotu.
if ( poruka == 50 ) { // || OR - digitalWrite(statusLED, HIGH); Serial2.println(“2”); /// Serial.read daje 50 Serial.println(“2”); poruka = 0; }
Nadalje će taj robot reagirati na taj kod 50, odnosno broj 2 kako je zadano u njegovoj programskoj skici. U ovome smo trenutku kompletnu glavnu petlju mogli svesti na samo jednu liniju koda koja će primljenu poruku proslijediti robotu koji će onda odlučiti što s njome.
Tada bi glavna petlja izgledala ovako:
void loop() { Serial2.println(char(poruka)); }
Dakle integer varijablu poruke pretvorili bismo u znak naredbom char() i taj podatak proslijedili serijskom komunikacijom.
Iako bismo oslobodili nešto memorije za neke druge programske radnje, ograničili bismo debugiranje koda.
Uz zadržavanje if dijelova koda barem imamo veću kontrolu nad drugim dijelovima hardvera kao što je plava ledica koju palimo i gasimo ovisno o dijelu koda u kojem se nalazimo.
Najveća prednost ovakve simbioze (ili da ipak to nazovemo simROBOza) između dva mikrokontrolera je ta što smo im povećali mogućnosti za eventualnu nadogradnju dodatnim senzorima i to sa slobodnim pinovima oba mikrokontrolera.
Drugim riječima, zatrebaju li vam dodatni pinovi, a pri ruci imate još jedan VIDI X, povežite ih serijskom komunikacijom i tako proširite funkcionalnost vašeg robota. To je puno bolja opcija od korištenja Shift Registra ili I2C MCP23017 za proširivanje dostupnih pinova iz jednostavnog razloga što time povećavate i RAM pa onda u jedan RAM natrpate koda za jedan set senzora, a u drugi za drugi set senzora i logiku koja upravlja skupnim podatcima svih senzora.
Na ovaj bi način lakše bilo napraviti i međusobnu dijagnostiku otkaže li jedan od procesora, pa bi drugi bio u stanju dojaviti da nešto nije u redu s prvim.
Doživite li VIDI X kao mozak robota, a Hexapod kao tijelo, zanimljivo bi bilo napajati svaki od njih zasebnim napajanjem. Oba uz vrlo malo truda imaju mogućnost provjere stanja vlastitog napajanja.
Pustite mašti na volju pa razmislite o mnogim senzorima koje želite dodati, a u međuvremenu na VIDI X mikroračunalu već imate ugrađeni infracrveni prijemnik i predajnik, mikrofon i zvučnik te još poneki senzor. Dio koda za senzor temperature već smo ostavili u priloženim skicama kako biste mogli započeti s eksperimentiranjem.