Cuprins:

Wallace - Robot autonom DIY - Partea 5 - Adăugați IMU: 9 pași
Wallace - Robot autonom DIY - Partea 5 - Adăugați IMU: 9 pași

Video: Wallace - Robot autonom DIY - Partea 5 - Adăugați IMU: 9 pași

Video: Wallace - Robot autonom DIY - Partea 5 - Adăugați IMU: 9 pași
Video: Night 2024, Noiembrie
Anonim
Image
Image

Continuăm împreună cu Wallace. Numele Wallace a venit dintr-un amestec de „Wall-E” și dintr-un proiect anterior (recunoaștere vocală), iar în utilizarea utilitarului „speak”, a sunat puțin britanic. Și ca un valet sau majordom. Și acesta este scopul final: ca acest proiect să se transforme în ceva util. Astfel „Wallace”.

Wallace se poate mișca, poate evita obstacolele folosind senzori de distanță IR (recent, cumva s-au prăjit (?) (Trebuie să se uite la asta atunci când am o șansă), are și niște senzori de distanță acustici (trei dintre aceștia au mers prost în același timp timp, împreună cu un expansor MCP23017) și, în cele din urmă, pot detecta modificări ale curentului motorului pentru a ști când este lovit de ceva.

În plus față de senzori, Wallace „își amintește” cele 100 de mișcări și are o analiză rudimentară folosind istoricul mișcărilor.

Scopul de până acum pentru Wallace este să încerce doar să continue să meargă înainte și să știe când este blocat într-un tipar care se repetă (cum ar fi într-un colț) și nu se mișcă înainte.

Am trecut prin mai multe iterații pentru mișcare și navigare, iar durerea de cap constantă a fost în timpul rotației.

Întrucât Wallace este un robot urmărit și am vrut să păstrez lucrurile mai simple în software (pentru mai târziu), pentru a mă transforma, trebuie doar să-l pivoteze / să se rotească în loc. Astfel, aplicați motoare egale, dar opuse ciclu de putere / sarcină.

Problema întâmpinată se datorează designului platformei robot Agent 390. Centurile de cale au tendința de a se freca de părți. Și mai rău, o parte face mai mult decât cealaltă.

Pe pardoseală și mergând drept, nu a fost o problemă. Apare pe covoare. Am ales să-l țin pe Wallace departe de covor după ce urmele sale au devenit murdare (ridică murdăria extrem de ușor).

Adevărata problemă este atunci când pivotați pe pardoseală.

Dacă software-ul aplică un ciclu de funcționare la nivel înalt, atunci acesta se transformă mai mult sau mai puțin consecvent. Cu toate acestea, în timpul unui ciclu de funcționare redus, se poate transforma sau nu efectiv. Sau se poate transforma puțin și apoi încetini. Acțiunea pivotantă pare a fi incontrolabilă prin intermediul software-ului sau, în cel mai bun caz, foarte dificilă.

Problema apare în timpul navigării și deplasării în jurul sau departe de obstacole. Poate fie să se învârtă prea sălbatic, fie se poate bloca încercând să facă schimburi foarte minuscule, chiar fără să se miște.

Astfel, explicația de mai sus a motivat acest instructabil.

Inițial, am vrut să renunț sau să întârziez introducerea unei unități de detectare a mișcării (IMU), deoarece acestea sunt A) complicate, B) zgomotoase, C) pot fi introduse erori în timp, etc., etc. a fost că ne-am putea descurca foarte bine saltând înainte la senzorii cu laser IR din timpul zborului. Și am putea - folosind lasere am putea ști dacă robotul sa rotit sau nu, urmărind schimbările de distanță.

De fapt, am putea (chiar) să facem asta acum, cu senzorii acustici.

Totuși, toate acestea sunt o modalitate foarte indirectă și complicată de a răspunde la o întrebare simplă: „ne-am rotit sau nu?”

Mi s-a părut că săritul pentru a folosi senzorii laser ToF mă va duce la următorul nivel de software; și anume, SLAM (Localizare și cartografiere simultană). Nu eram încă pregătit să merg acolo.

Este un lucru bun să faci un proiect robot în straturi, primele straturi (inferioare) fiind mai simple, iar ultimele straturi (superioare) fiind mai abstracte și abordând probleme mai dificile.

Straturile pot fi gândite la așa ceva:

  1. cadru fizic robot / bază structurală mecanică
  2. sistem de acționare rudimentar (Raspberry, Roboclaw, motoare, cabluri etc., software de bază, comandat de tastatură)
  3. circuite esențiale pentru susținerea senzorilor (schimbător de tensiune bidirecțional, expansor de port, E-Stop, distribuție de energie etc.)
  4. senzori de evitare a obstacolelor (acustice, IR)
  5. poziționare de bază și mișcare - detecție esențială (accelerometru, giroscop, magnetometru, codificatoare de motor, codificatoare de roți)

Puteți veni cu propria listă. Punctele despre această listă sunt că probabil ar trebui să le faceți mai mult sau mai puțin în această ordine și, de asemenea, că, dacă petreceți ceva timp la fiecare strat pentru a ajunge la fiecare la o stare bună de lucru, ar trebui să vă ajute mai târziu, pe măsură ce lucrurile se complică.

Lista de mai sus ar putea fi mai mult sau mai puțin mapată la aceste straturi conceptuale din software.

  • SLAM (Localizare și mapare simultană)
  • Controlul și conștientizarea mișcării, rotației
  • Evitarea obstacolului de bază
  • Controlul și detectarea datelor senzorilor
  • Mișcare esențială înainte, înapoi, stânga și dreapta, accelerare, încetinire, oprire

După cum puteți vedea, pentru această listă, primele elemente ar fi straturile superioare, mai complicate, care abordează probleme și întrebări mai abstracte, cum ar fi „unde sunt eu” și „unde mă duc”, în timp ce ultimele elemente ar fi straturi software mai mici care gestionează „cum să vorbești / să asculți senzorul A” sau „cum să miști această roată”.

Acum, nu spun că atunci când începeți la un strat, îl veți finaliza și apoi se află pe următorul strat, pentru a nu reveni niciodată la cel anterior. Un proiect robot poate semăna mult cu metodele moderne, iterative de dezvoltare software (agile, SCRUM etc.).

Spun doar să-ți iei timp la fiecare. Va trebui să echilibrați cât de mult faceți la fiecare și să decideți ce încercați la un anumit strat care merită timpul și necazurile.

Există un anumit „conflict” sau „tensiune” între două idei sau direcții concurente.

Una este ceea ce aș numi „plug-n-play” pentru a rezolva problema A.

Cealaltă este DIY (fă-o singur). Și poate că nici măcar nu este cea mai bună etichetă pentru această altă idee.

Iată un exemplu pentru fiecare, sperăm că veți vedea tensiunea sau conflictul dintre cele două opțiuni.

Pentru acest exemplu, să lămurim SLAM, evitarea obstacolelor și mișcarea de bază esențială, toate ca o problemă de rezolvat în același timp.

  1. Dacă decidem să mergem pe traseul plug-n-play, sărim imediat (în funcție de buget) la lucruri precum acele lasere rotative montate deasupra sau camera cu adâncime de câmp sau lasere ToF și IMU (subiectul acestui Instructabil).
  2. Dacă, pe de altă parte, dorim să parcurgem cea de-a doua rută, putem încerca să extragem fiecare informație posibilă din niște senzori acustici sau senzori IR sau deloc senzori - folosim doar monitorizarea curentului motorului (bump)

Ce se poate spune despre # 1 vs # 2? Un lucru ar fi că vom învăța mult mai multe făcând # 2. Limitele de a avea doar senzori acustici cu care să lucrăm ne obligă să ne gândim la mai multe probleme.

Pe de altă parte, dacă suntem prea concentrați să facem lucruri prin intermediul # 2, este posibil să pierdem timpul, deoarece cerem mai mult decât ar trebui de la senzorii acustici.

Încă un concept sau idee la care să ne gândim: ce amestec de hardware și software răspunde cel mai bine la întrebările „cum să” și ce amestec de software (și hardware?) Răspunde la întrebarea „ce”, „când”, „unde”. Deoarece „cum să” este de obicei o întrebare de nivel inferior de care „ce”, „când” și „unde” depind pentru a obține un răspuns.

Oricum, toate cele de mai sus erau doar ceva de gândit.

În cazul meu, după o mulțime de eforturi și având o problemă enervantă consistentă de frecare pe șină și incapabilă să obțin un control și o mișcare consecvente, este timpul să facem altceva.

Astfel, acest instructabil - un IMU.

Scopul este ca, dacă IMU spune că robotul NU pivotează, creștem ciclul de funcționare. Dacă pivotăm prea repede, reducem ciclul de funcționare.

Pasul 1: senzorul IMU

Senzorul IMU
Senzorul IMU
Senzorul IMU
Senzorul IMU

Astfel, următorul nostru senzor de adăugat la Wallace este IMU. După câteva cercetări, mă stabileam pe un MPU6050. Dar, în acest moment, MPU9050 (și chiar mai recent, MPU9250) părea o idee și mai bună.

Sursa mea de acces a fost Amazon (în S. U. A.). Așa că am comandat două dintre ele.

Ceea ce am primit de fapt (se pare că nu există control asupra acestui lucru; asta nu-mi place la Amazon) au fost două MPU92 / 65. Mă întreb un pic despre desemnare. Uită-te la imagini; aceasta pare a fi o denumire „familială”. În orice caz, cu asta sunt blocat.

Adăugarea acestuia este foarte simplă - obțineți o placă proto cu piste de conectare, lipiți senzorul la placă, adăugați un bloc terminal cu șurub cu 10 pini (am primit-o pe a mea de la Pololu).

Pentru a minimiza orice interferență, am încercat să plasez acești senzori departe de orice altceva.

Asta a însemnat și utilizarea unor șuruburi / piulițe din nailon.

Voi folosi protocolul I2C. Sperăm că lungimea totală a firului nu va fi prea rea.

Există o mulțime de informații în altă parte despre conexiunile de bază și nivelurile de tensiune etc., așa că nu voi repeta asta aici.

Pasul 2: Lucrurile nu sunt întotdeauna curate, ușoare

La această scriere, nu pare să existe multe online pentru acest MPU-92/65. Ceea ce este disponibil, la fel ca la majoritatea senzorilor, pare a fi exemple folosind Arduino.

Încerc să fac aceste Instrucțiuni un pic diferite prin prezentarea unui proces nu atât de curat, deoarece lucrurile nu funcționează întotdeauna imediat.

Presupun că aceste instructabile sunt mai asemănătoare cu un blog decât drept A-B-C, 1-2-3 „așa o faci”.

Pasul 3: Test inițial

Test inițial
Test inițial
Test inițial
Test inițial

Din imaginile din pasul anterior, firele roșii și negre care merg la senzori sunt, desigur, VCC (5V) și GND. Firele verzi și galbene sunt conexiunile I2C.

Dacă ați făcut alte proiecte I2C sau ați urmărit împreună cu aceste serii, atunci știți deja despre „i2cdetect” și acesta este primul pas pentru a ști dacă Raspberry poate vedea noul senzor.

După cum puteți vedea din imaginile din acest pas, prima noastră încercare nu a reușit. IMU nu apare (ar trebui să fie ID-ul dispozitivului 0x68).

Cu toate acestea, vestea bună este că autobuzul I2C funcționează. Vedem un dispozitiv 0x20 și este expansorul de port MCP23017 (în prezent responsabil pentru senzorii acustici HCSR04).

Nu este ușor de văzut în imagine, dar am conectat aceleași fire de culoare verde și galben de la IMU la MCP23017 (vezi stânga jos în imagine)

Va trebui să facem unele soluții de depanare.

Pasul 4: Depanare

Image
Image
Depanare
Depanare
Depanare
Depanare

Folosind setarea de continuitate pe un voltmetru (cel cu tonul acut), am testat conexiunile VCC (5V), GND, SDA și SCL. Au fost bune.

Următoarea încercare a fost să deconectați MCP23017 de autobuzul I2C, lăsând doar MPU-92/65 pe autobuz. Acest lucru s-a dovedit infructuos - „i2cdetect” nu a arătat apoi niciun dispozitiv.

Așadar, am demontat senzorul de la totem și l-am recablurat direct pe magistrala bidirecțională de 5V-la-3V; adică direct la Zmeură. (fire mai scurte?).

Și voila. De data aceasta există succes. Vedem apariția 0x68 folosind „i2cdetect”.

Dar nu știm încă de ce a funcționat de data aceasta. Ar putea fi lungimea firelor? Locația anterioară?

Notă: Nu a făcut nicio diferență dacă ADO a fost sau nu împământat. S-ar putea să existe rezistențe de tragere și de tragere la bord. Același lucru ar putea fi valabil și pentru FSYNC.

Apoi, am reconectat MCP23017. Deci, acum avem două dispozitive pe magistrala I2C. (vezi imaginea). Succes, acum vedem atât 0x20 cât și 0x68 cu i2cdetect.

Videoclipurile analizează puțin mai mult din ceea ce s-a întâmplat în timpul depanării.

Pasul 5: Citirea datelor senzorului

Image
Image
Citirea datelor senzorului
Citirea datelor senzorului
Citirea datelor senzorului
Citirea datelor senzorului

Diverse abordări

Am decis să iau mai multe abordări pentru a obține informații utile de la senzor. Iată-le, nu în nici o ordine:

  1. încercați câteva programe de bază
  2. căutați câteva documente online pe registre
  3. aruncați o privire la exemplele și / sau codul altora

De ce aceste abordări? De ce să nu căutăm doar o bibliotecă sau un cod existent?

Experimentând și încercând câteva idei, putem absorbi mai bine unele cunoștințe despre acest senzor, dar putem câștiga și o anumită tehnică, abilitate și moduri de gândire despre abordarea a ceva nou și ceva care poate nu are o mulțime de documente; ceva ce poate avea o mulțime de necunoscute.

De asemenea, odată ce ne-am jucat și am încercat unele dintre ideile noastre și am câștigat o oarecare perspectivă, suntem într-o poziție mai bună pentru a evalua codul sau biblioteca altcuiva.

De exemplu, după ce m-am uitat la un cod C ++ pentru MPU9250 în github, mi-am dat seama că mă obliga să folosesc întreruperi, ceea ce nu doresc încă să fac.

De asemenea, vine cu lucruri suplimentare, cum ar fi calibrarea; din nou, ceva care nu mă interesează încă.

S-ar putea ca ceea ce trebuie să fac pentru a răspunde la întrebarea simplă „este robotul care se rotește da sau nu” s-ar putea răspunde foarte simplu doar citind unele registre.

Registrele

La această scriere, nu pare să fie prea multe disponibile pe acest senzor. De fapt, dacă aruncați o privire asupra imaginilor care vin cu acest instructabil și aruncați o privire atentă pe inscripțiile de pe jetoanele reale, mă face să mă întreb dacă nu este un knock-off. Nu raportez ceea ce văd cu nimic de la Invense. Indiferent, am ales să mă uit la informațiile de registru pentru modelele pe care le-am găsit: MPU-6050 și MPU-9250.

În ambele cazuri, următorul este același pentru ambele. Și pentru început, presupunem că va fi la fel și pentru acest MPU-92/65.

59-64 - măsurători accelerometru

65, 66 - măsurători de temperatură 67-72 - măsurători giroscopice 73-96 - date senzor extern

O notă: MPU-6050 pare să NU aibă magnetometru, în timp ce MPU-9250 (și presupunem că și acesta) are unul.

Câteva informații mai interesante, sperăm utile, culese din registrul documentului:

Informații despre magnetometru:

magnetometru id: 0x48 registre 00 până la 09: 00H WIA 0 1 0 0 1 0 0 0 01H INFO INFO7 INFO6 INFO5 INFO4 INFO3 INFO2 INFO1 INFO0 02H ST1 0 0 0 0 0 0 DOR DRDY 03H HXL HX7 HX6 HX5 HX4 HX3 HX2 HX1 HX0 HXH HX15 HX14 HX13 HX12 HX11 HX10 HX9 HX8 05H HYL HY7 HY6 HY5 HY4 HY3 HY2 HY1 HY0 06H HYH HY15 HY14 HY13 HYZ HZHZZ HZZ HZZ HZZ HZZ HZZ HZZ HZZ HZ HZ ST2 0 0 0 BITM HOFL 0 0 0 o defalcare a ceea ce înseamnă fiecare registru: HXL [7: 0]: date de măsurare axa X mai mici 8 biți HXH [15: 8]: date de măsurare axe X mai mari 8 biți HYL [7: 0]: Date de măsurare axa Y mai mici 8 biți HYH [15: 8]: date de măsurare axa Y mai mari 8 biți HZL [7: 0]: date de măsurare axa Z mai mici 8 biți HZH [15: 8]: date de măsurare axa Z mai mari 8 biți

Programare

O altă informație din documentele registrului este că păreau să existe doar aproximativ 100 de registre. Deci, o tactică ar putea fi aceea de a scrie un program simplu care accesează dispozitivul (0x68) și încearcă să citească o serie de registre secvențial, fără a ține cont de semnificația lor, doar pentru a vedea ce date pot fi văzute.

Și apoi, faceți treceri succesive, folosind același cod, și comparați datele dintr-o trecere față de următoarea.

Ideea este că probabil am putea elimina orice registre care par să nu aibă date (zerouri sau FF?) Sau care nu se schimbă absolut niciodată și ne-am putea concentra și asupra celor care se schimbă.

Apoi, una ne uităm doar la cele care se schimbă, adăugăm o funcție de mediere care face media celor mai recente N citiri ale acelui registru, pentru a vedea dacă există de fapt o anumită valoare constantă pentru acel registru. Acest lucru ar presupune că ținem senzorul foarte nemișcat și în aceeași locație.

În cele din urmă, am putea încerca cu ușurință lucrurile cu senzorul, cum ar fi împingerea acestuia (accelerometru, giroscop) sau suflare pe el (temperatura) sau rotirea acestuia (magnetometrul cu două plus anterioare) și a vedea ce efect are acest lucru asupra valorilor.

Îmi place să folosesc biblioteca wiringPi cât mai mult posibil. Are suport pentru I2C.

Prima alergare:

/********************************************************************************

* pentru a construi: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * pentru a rula: sudo./first.test.mpu9265 * * acest program tocmai scoate o gamă de (posibili) registre din MCP23017, * și apoi de la MPU9265 (sau orice alt MPU la acea adresă 0x68) * * L-am folosit pentru a valida dacă aș putea chiar să citesc de la senzor, deoarece deja * aveam încredere în MCP23017. * ************************************************** **************************** / #include #include #include #include #include int main (int argc, char ** argv) {pune („Să vedem ce are de spus MCP23017 @ 0x20:”); errno = 0; int deviceId1 = 0x20; int fd1 = wiringPiI2CSetup (deviceId1); if (-1 == fd1) {fprintf (stderr, "Nu se poate deschide dispozitivul WiringPi I2C:% s / n", strerror (errno)); retur 1; } pentru (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", wiringPiI2CReadReg8 (fd1, reg)); fflush (stderr); întârziere (10); } pune (""); put ("Să vedem ce are de spus MPU9265 @ 0x20:"); errno = 0; int deviceId2 = 0x68; int fd2 = wiringPiI2CSetup (deviceId2); if (-1 == fd2) {fprintf (stderr, "Nu se poate deschide dispozitivul WiringPi I2C:% s / n", strerror (errno)); retur 1; } pentru (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", wiringPiI2CReadReg8 (fd2, reg)); fflush (stderr); întârziere (10); } pune (""); retur 0; }

A doua rundă:

/********************************************************************************

* pentru a construi: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * pentru a rula: sudo./second.test.mpu9265 * * Acest program afișează numărul de registru alături de valoarea citită. * * Acest lucru face util să direcționați (redirecționați) ieșirea către un fișier, iar apoi * se pot face mai multe rulări, pentru a compara. S-ar putea oferi o oarecare înțelegere despre * ce registru este important și cum se pot comporta datele. * ************************************************** **************************** / #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x20", strlen ("0x20"))) {deviceId = 0x20; } else if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } else if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } pune ("Să vedem ce poate spune MPU9265 @ 0x20:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Nu se poate deschide dispozitivul WiringPi I2C:% s / n", strerror (errno)); retur 1; } pentru (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); întârziere (10); } returnează 0; }

A treia alergare:

/********************************************************************************

* a construi: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * pentru a rula: sudo./third.test.mpu9265 * * Acest program este rezultatul celui de-al doilea. Citește doar din registrele * care indicau o diferență între o rundă și următoarea.* ************************************************** **************************** / #include #include #include #include #include #include int main (int argc, char ** argv) {int deviceId = -1; if (0) {} else if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } else if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } pune ("Să vedem ce poate spune MPU9265 @ 0x20:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Nu se poate deschide dispozitivul WiringPi I2C:% s / n", strerror (errno)); retur 1; } pentru (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); întârziere (10); } pentru (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); întârziere (10); } pentru (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); întârziere (10); } for (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); întârziere (10); } returnează 0; }

Deci, ce am învățat până acum? Imaginea tabelului cu zone evidențiate colorate indică faptul că ieșirea pare să se potrivească cu primele seturi de registre.

Rezultatele de până acum pot genera noi întrebări.

Întrebare: de ce există un singur rezultat de registru pentru grupul „extern”?

Întrebare: ce sunt toate acele registre necunoscute "??????"

Întrebare: deoarece programul nu este întrerupt, a solicitat date prea lent? prea repede?

Întrebare: putem afecta rezultatele încercând lucrurile cu senzorul în sine în timp ce rulează?

Pasul 6: Să sapăm mai multe în citiri / date

Cred că următorul pas înainte de orice altceva este îmbunătățirea programului pentru:

  • fii flexibil în cât de mult întârziere buclă (ms)
  • fii flexibil în ceea ce privește numărul de citiri pentru a da o medie de rulare pe registru

(A trebuit să atașez programul ca fișier. Se pare că a fost o problemă la introducerea acestuia aici. "Al patrulea.test.mpu9265.c")

Iată o alergare care utilizează ultimele 10 citiri pentru o medie, la o buclă de 10 ms:

sudo./fourth.test.mpu9265 0x68 10 10

61:255 0 255 0 255 0 255 0 0 0: 102 62:204 112 140 164 148 156 188 248 88 228: 167 63:189 188 189 187 189 188 188 188 188 189: 188 64: 60 40 16 96 208 132 116 252 172 36: 112 65: 7 7 7 7 7 7 7 7 7 7: 7 66:224 224 224 240 160 208 224 208 144 96: 195 67: 0 0 0 0 0 0 0 0 0 0: 0 68:215 228 226 228 203 221 239 208 214 187: 216 69: 0 255 0 255 255 0 255 0 0 0: 102 70:242 43 253 239 239 45 206 28 247 207: 174 71: 0 255 255 0 255 255 255 255 255 255: 204 72: 51 199 19 214 11 223 21 236 193 8: 117 73: 0 0 0 0 0 0 0 0 0 0: 0 111: 46 149 91 199 215 46 142 2 233 199: 132 112: 0 0 0 0 0 0 0 0 0 0: 0 189:255 0 255 0 255 0 0 255 0 255: 127 190: 76 36 240 36 100 0 164 164 152 244: 121 191:188 188 188 188 187 188 187 189 187 189: 187 192: 8 48 48 196 96 220 144 0 76 40: 87 193: 7 7 7 7 7 8 7 7 7 7: 7 194:208 224 144 240 176 240 224 208 240 224: 212 195: 0 0 0 0 0 0 0 0 0 0: 0 196:243 184 233 200 225 192 189 242 188 203: 209 197:255 0 0 0 255 0 255 0 0 255: 102 198:223 39 247 43 245 22 255 221 0 6: 130 199: 0 255 255 255 0 255 255 255 255 0: 178 200:231 225 251 1 252 20 211 216 218 16: 164 201: 0 0 0 0 0 0 0 0 0 0: 0 239: 21 138 196 87 26 89 16 245 187 144: 114 240: 0 0 0 0 0 0 0 0 0 0: 0

Prima coloană din stânga este numărul registrului. Apoi vin ultimele 10 citiri pentru acel registru. În cele din urmă, ultima coloană este media pentru fiecare rând.

Se pare că registrele 61, 69, 71, 189, 197 și 199 sunt fie numai binare, fie gata / nu sunt gata, fie reprezintă octetul mare al unei valori pe 16 biți (negativ?).

Alte observații interesante:

  • registre 65, 193 - foarte stabil și aceeași valoare
  • registrul 63, 191 - foarte stabil și aceeași valoare
  • registre 73, 112, 195, 201, 240 - toate la zero

Să raportăm aceste observații la imaginea de masă multicoloră, evidențiată de mai devreme.

Înregistrați 65 - temperatura

Înregistrează 193 - ??????

Înregistrați 63 - accelerometru

Înregistrați-vă 191 - ??????

Registrul 73 - extern

Înregistrați 112 și pe - ??????

Ei bine, încă avem necunoscute, cu toate acestea, am învățat ceva util.

Registrul 65 (temperatura) și registrul 63 (accelerometrul) au fost ambele foarte stabile. La asta ne-am aștepta. Nu am atins senzorul; nu se mișcă, în afară de orice vibrații accidentale, deoarece robotul se sprijină pe aceeași masă cu computerul meu.

Există un test interesant pe care îl putem pentru fiecare dintre aceste registre de temperatură / accelerometru. Pentru acest test, avem nevoie încă de o altă versiune a programului.

Pasul 7: Suntem capabili să afectăm temperatura și accelerarea

În pașii anteriori am restrâns cel puțin un registru pentru temperatură și unul pentru accelerație.

Cu următoarea versiune a programului („5th.test.mpu9265.c”), putem vedea că are loc o schimbare pentru ambele registre. Vă rugăm să urmăriți videoclipurile.

Mai multe săpături

Dacă ne întoarcem și analizăm informațiile despre registru, vedem că există:

  • trei ieșiri de 16 biți pentru giroscop
  • trei ieșiri de 16 biți pentru accelerometru
  • trei ieșiri de 16 biți pentru magnetometru
  • o ieșire de 16 biți pentru temperatură

Cu toate acestea, rezultatele obținute de programele noastre de testare simple au fost toate ieșiri unice pe 8 biți. (registre unice).

Deci, să încercăm mai mult din aceeași abordare, dar de data aceasta citind 16 biți în loc de 8.

Probabil va trebui să facem ceva ca mai jos. Să folosim temperatura ca exemplu, deoarece este doar o ieșire de 16 biți.

// obțineți descriptorul de fișiere fd …

int tempRegHi = 65; int tempRegLo = 66; int hiByte = wiringPiI2CReadReg8 (fd, tempRegHi); int loByte = wiringPiI2CReadReg8 (fd, tempRegLo); int result = hiByte << 8; // puneți ordinea hi 8 biți în partea superioară a unui rezultat de valoare de 16 biți | = loByte; // acum adăugați în ordinea lo 8 biți, obținând un număr complet de 16 biți // tipăriți acel număr sau utilizați funcția de afișare a graficelor orizontale dinainte

Din pașii noștri anteriori am văzut că registrul 65 este destul de constant, în timp ce registrul 66 este foarte zgomotos. Deoarece 65 este octetul de ordine hi și 66 octetul de ordin scăzut, acest lucru are sens.

Pentru citire, putem lua datele din registrul 65 ca atare, dar am putea înregistra în medie valorile din registrul 66.

Sau putem doar să obținem media întregului rezultat.

Aruncați o privire la ultimul videoclip pentru această parte; demonstrează citirea întregii valori de temperatură pe 16 biți. Codul este „al șaselea.test.mpu9265.c”

Pasul 8: Accelerometru și giroscop

Image
Image

Videoclipurile pentru această secțiune arată ieșirea din accelerometru și giroscop, utilizând un program de testare „7th.test.mpu9265.c”. Acest cod poate citi 1, 2 sau 3 perechi consecutive de octeți (hi și lo octeți) și convertește valorile într-o singură valoare de 16 biți. Astfel, putem citi orice axă sau putem citi două dintre ele împreună (și rezumă modificările) sau le putem citi pe toate trei (și rezumă modificările).

Pentru a reitera, pentru această fază, pentru acest instructabil, caut doar să răspund la o întrebare simplă: „s-a rotit robotul / pivotează?”. Nu caut nicio valoare precisă, cum ar fi, s-a rotit cu 90 de grade. Acest lucru va veni mai târziu când vom începe să facem SLAM, dar nu este necesar pentru simpla evitare a obstacolelor și mișcare aleatorie.

Pasul 9: (lucrați în curs) magnetometrul

când utilizați instrumentul i2cdetect, MPU9265 apare în tabel ca 0x68:

0 1 2 3 4 5 6 7 8 9 a b c d e f

00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

Există pași suplimentari necesari pentru a citi din porțiunea magnetometrului IMU.

Din documentul PDF al registrelor Invesense:

ÎNREGISTRĂRI 37 LA 39 - I2C SLAVE 0 CONTROL

  • ÎNREGISTRARE 37 - I2C_SLV0_ADDR
  • ÎNREGISTRARE 38 - I2C_SLV0_REG
  • ÎNREGISTRARE 39 - I2C_SLV0_CTRL

Recomandat: