Innholdsfortegnelse:

Wallace - DIY Autonomous Robot - Del 5 - Legg til IMU: 9 trinn
Wallace - DIY Autonomous Robot - Del 5 - Legg til IMU: 9 trinn

Video: Wallace - DIY Autonomous Robot - Del 5 - Legg til IMU: 9 trinn

Video: Wallace - DIY Autonomous Robot - Del 5 - Legg til IMU: 9 trinn
Video: СМОТРЕТЬ: НАСА анонсирует посадку марсохода Perseverance на Марс — прямая трансляция 2024, November
Anonim
Image
Image

Vi fortsetter sammen med Wallace. Navnet Wallace kom fra en blanding av "Wall-E", og fra et tidligere prosjekt (stemmegjenkjenning), og ved bruk av "espeak" -verktøyet hørtes det litt britisk ut. Og som en betjent eller butler. Og det er sluttmålet: at dette prosjektet skal bli til noe nyttig. Dermed "Wallace".

Wallace kan bevege seg rundt, han kan unngå hindringer ved hjelp av IR -avstandssensorer (nylig, på en eller annen måte stekte de (?) (Må se nærmere på det når jeg får sjansen), har også noen akustiske avstandssensorer (tre av dem gikk dårlig samtidig tid, sammen med en MCP23017-ekspander), og til slutt kan det oppdage endringer i motorstrøm for å vite når det støter på noe.

I tillegg til sensorene "husker" Wallace de 100 trekkene, og har noen rudimentære analyser ved hjelp av bevegelseshistorien.

Målet så langt for Wallace er å bare prøve å fortsette fremover, og å vite når det sitter fast i et gjentatt mønster (for eksempel i et hjørne) og egentlig ikke gå videre.

Jeg har gått gjennom flere iterasjoner for bevegelse og navigasjon, og den konsekvente hodepine har vært under rotasjon.

Siden Wallace er en sporet robot, og jeg ønsket å holde ting enklere i programvaren (for senere), for å snu, må jeg bare få ham til å svinge/rotere på plass. Påfør derfor motorene lik, men motsatt effekt / driftssyklus.

Problemet skyldes designet av robotplattformen Agent 390. Sporbeltene har en tendens til å gni mot sidene. Og verre, den ene siden gjør det mer enn den andre.

På gulv og gå rett, har det ikke vært et problem. Det dukker opp på tepper. Jeg valgte å holde Wallace utenfor teppet etter at sporene ble skitne (de tar opp skitt ekstremt lett).

Det virkelige problemet er når du svinger på gulv.

Hvis jeg har programvaren til å bruke en høy syklus, vil den mer eller mindre konsekvent snu. I løpet av en lavdriftssyklus kan den imidlertid faktisk snu. Eller det kan snu litt og deretter senke farten. Den svingende handlingen ser ut til å være ukontrollabel via programvaren, eller i beste fall veldig vanskelig.

Problemet dukker opp under navigering og beveger seg rundt eller bort fra hindringer. Den kan enten svinge for vilt bort, eller den kan sette seg fast ved å prøve å gjøre svært små skift, uten egentlig å bevege seg.

Og derfor motiverte forklaringen ovenfor denne instruksen.

I utgangspunktet hadde jeg ønsket å avstå fra eller forsinke introduksjonen av en bevegelsesføler (IMU), fordi de er A) kompliserte, B) bråkete, C) feil kan bli introdusert over tid, osv. Osv. Min tanke hadde vært at vi kunne gjøre det veldig bra ved å hoppe fremover til IR-lasersensorer på flyet. Og vi kunne - ved hjelp av lasere kunne vi vite om roboten roterte eller ikke, ved å spore endringene i avstand.

Faktisk kunne vi også (slags) gjøre det nå, med de akustiske sensorene.

Alt dette er imidlertid en veldig indirekte, komplisert måte å svare på et enkelt spørsmål: "har vi rotert eller ikke?"

Det virket for meg som å hoppe for å bruke ToF lasersensorer ville ta meg til neste nivå av programvare; nemlig SLAM (Simultan lokalisering og kartlegging). Jeg var ikke klar til å dra dit ennå.

Det er en god ting å gjøre et robotprosjekt i lag, med de første (nedre) lagene som er enklere, og de siste (øvre) lagene er mer abstrakte og takler vanskeligere problemer.

Lag kan tenkes på noe slikt:

  1. robot fysisk ramme / mekanisk strukturelt grunnlag
  2. rudimentært drivsystem (bringebær, Roboclaw, motorer, kabling osv., grunnleggende programvare, tastaturdrevet)
  3. viktige kretser for å støtte sensorer (toveis spenningsskifter, portutvidelse, E-Stop, strømfordeling osv.)
  4. hindringssensorer (akustisk, IR)
  5. vesentlig, grunnleggende posisjonering og bevegelse - deteksjon (akselerometer, gyro, magnetometer, motorkodere, hjulkodere)

Du kan komme med din egen liste. Poengene med denne listen er at du sannsynligvis bør gjøre disse mer eller mindre i den rekkefølgen, og også at hvis du bruker litt tid på hvert lag for å få hver til en god arbeidstilstand, bør det hjelpe deg senere ettersom ting blir mer kompliserte.

Listen ovenfor kan mer eller mindre kartlegges til disse konseptuelle lagene i programvare.

  • SLAM (samtidig lokalisering og kartlegging)
  • Kontroll og bevissthet om bevegelse, rotasjon
  • Grunnleggende hindring av hindringer
  • Kontroll og deteksjon av sensordata
  • Viktig bevegelse fremover, bakover, venstre og høyre, øke hastigheten, senke farten, stoppe

Som du kan se, for denne listen, vil de første elementene være de øvre, mer kompliserte lagene som takler mer abstrakte spørsmål og spørsmål, for eksempel "hvor er jeg" og "hvor skal jeg", mens de siste elementene ville være lavere programvarelag som håndterer "hvordan snakke/lytte til sensor A" eller "hvordan du beveger dette hjulet".

Nå sier jeg ikke at når du starter på et lag, vil du ha fullført det, og så er det på det neste laget, for aldri å gå tilbake til det forrige. Et robotprosjekt kan minne mye om moderne, iterative programvareutviklingsmetoder (smidig, SCRUM, osv.).

Jeg sier bare å ta tid på hver. Du må balansere hvor mye du skal gjøre for hver, og bestemme hva du prøver på et bestemt lag verdt tiden og bryet.

Det er en viss "konflikt" eller "spenning" mellom to konkurrerende ideer eller retninger.

Det ene er det jeg vil kalle "plug-n-play" for å løse problem A.

Den andre er DIY (gjør det selv). Og det er kanskje ikke engang den beste etiketten for denne andre ideen.

Her er et eksempel på hver, forhåpentligvis vil du se spenningen eller konflikten mellom de to valgene.

For dette eksemplet, la oss klumpe SLAM, unngåelse av hindringer og grunnleggende grunnleggende bevegelser som et problem å løse samtidig.

  1. Hvis vi bestemmer oss for å gå plug-n-play-ruten, hopper vi umiddelbart (avhengig av budsjett) til ting som de toppmonterte roterende laserne, eller dybdeskarphetskameraet, eller ToF-lasere, og IMU (emne for dette Instruerbar).
  2. Hvis vi derimot ønsker å gå den andre ruten, kan vi prøve å trekke ut all mulig informasjon fra noen akustiske sensorer eller IR -sensorer, eller ingen sensorer i det hele tatt - vi bruker bare motorstrømovervåking (støt)

Hva kan man si om #1 vs #2? En ting ville være at vi vil ha lært mye mer ved å gjøre #2. Begrensningene ved å bare ha akustiske sensorer å jobbe med, tvinger oss til å tenke på mange flere problemer.

På den annen side, hvis vi er for fokuserte på å gjøre ting via #2, kan vi kaste bort tid fordi vi ber om mer enn vi burde fra akustiske sensorer.

Nok et konsept eller en idé å tenke på: Hvilken blanding av maskinvare og programvare svarer best på spørsmålene "hvordan", og hvilken blanding av programvare (og maskinvare?) Svarer på spørsmålet "hva", "når", "hvor". Fordi "hvordan" vanligvis er et spørsmål på lavere nivå som "hva", "når" og "hvor" er avhengig av for å få svar.

Uansett var alt det ovennevnte bare noe å tenke på.

I mitt tilfelle, etter mye innsats og med det konsekvente irriterende problemet med sporfriksjon og ikke klarer å få konsekvent kontroll og bevegelse, er det på tide å gjøre noe annet.

Dermed er dette instruerbart - en IMU.

Målet er at hvis IMU sier at roboten IKKE svinger, øker vi driftssyklusen. Hvis vi svinger for fort, reduserer vi driftssyklusen.

Trinn 1: IMU -sensoren

IMU -sensoren
IMU -sensoren
IMU -sensoren
IMU -sensoren

Og så er vår neste sensor å legge til i Wallace IMU. Etter litt undersøkelse slo jeg meg til ro med en MPU6050. Men da på dette tidspunktet virket MPU9050 (og enda mer nylig, MPU9250) som en enda bedre idé.

Min kilde har vært Amazon (i USA). Så jeg bestilte to av dem.

Det jeg faktisk fikk (det ser ut til å ikke være kontroll over dette; det er det jeg ikke liker med Amazon) var to MPU92/65. Jeg lurer litt på betegnelsen. Ta en titt på bildene; det ser ut til å være en "familie" betegnelse. Det er i alle fall det jeg sitter fast med.

Det er veldig enkelt å legge til det -få et proto -brett med tilkoblingsspor, lodd sensoren til brettet, legg til en 10 -pinners skrueklemme (jeg har min fra Pololu).

For å minimere forstyrrelser, prøvde jeg å plassere disse sensorene vekk fra alt annet.

Det betydde også å bruke noen nylonbolter/muttere.

Jeg skal bruke I2C -protokollen. Forhåpentligvis vil ikke total ledningslengde være så ille.

Det er mye informasjon andre steder om de grunnleggende tilkoblingene og spenningsnivåene osv., Så jeg vil ikke gjenta det her.

Trinn 2: Ting er ikke alltid rene, enkle

Ved denne skrivingen ser det ikke ut til å være mye online for denne spesielle MPU-92/65. Det som er tilgjengelig, akkurat som med de fleste sensorer, ser ut til å være eksempler på bruk av Arduino.

Jeg prøver å gjøre disse instruksjonene litt annerledes ved å presentere en ikke så ren prosess, fordi ting ikke alltid fungerer med en gang.

Jeg antar at disse instruksjonene ligner mer på en blogg enn rett A-B-C, 1-2-3 "slik gjør du det".

Trinn 3: Første test

Første test
Første test
Første test
Første test

Fra bildene i forrige trinn er de røde og svarte ledningene som går til sensorene selvfølgelig VCC (5V) og GND. De grønne og gule ledningene er I2C -tilkoblingene.

Hvis du har gjort andre I2C -prosjekter, eller har fulgt med disse seriene, vet du allerede om "i2cdetect", og det er det første trinnet for å vite om bringebæren kan se den nye sensoren.

Som du kan se fra bildene i dette trinnet, var vårt første forsøk mislykket. IMU -en vises ikke (bør være enhets -ID 0x68).

Den gode nyheten er imidlertid at I2C -bussen kjører. Vi ser en enhet 0x20, og det er MCP23017 portutvidelsen (for tiden ansvarlig for HCSR04 akustiske sensorer).

Det er ikke lett å se på bildet, men jeg koblet de samme fargede grønne og gule ledningene fra IMU til MCP23017 (se nederst til venstre i bildet)

Vi må gjøre noen feilsøking.

Trinn 4: Feilsøking

Image
Image
Feilsøking
Feilsøking
Feilsøking
Feilsøking

Ved å bruke kontinuitetsinnstillingen på et voltmeter (den med høy tone) testet jeg VCC (5V), GND, SDA og SCL tilkoblinger. De var gode.

Neste forsøk var å koble MCP23017 fra I2C-bussen, og bare la MPU-92/65 stå på bussen. Det viste seg å være fruktbart - "i2cdetect" viste da ingen enheter.

Så avmonterte jeg sensoren fra totempolen og koblet den direkte til 5V-til-3V toveis bussen; dvs. rett til bringebæret. (kortere ledninger?).

Og voila. Denne gangen er det suksess. Vi ser 0x68 dukke opp ved hjelp av "i2cdetect".

Men vi vet ennå ikke hvorfor det fungerte denne gangen. Kan det være lengden på ledningene? Den forrige plasseringen?

Merk: Det gjorde ingen forskjell om ADO var jordet eller ikke. Det kan være ombord pullup og nedtrekksmotstander. Det samme kan gjelde for FSYNC.

Deretter koblet jeg MCP23017 til igjen. Så nå har vi to enheter på I2C -bussen. (se bildet). Suksess, vi ser nå både 0x20 og 0x68 med i2cdetect.

Videoene går inn på litt mer av det som skjedde under feilsøkingen.

Trinn 5: Lesing av sensordata

Image
Image
Lese sensordata
Lese sensordata
Lese sensordata
Lese sensordata

Ulike tilnærminger

Jeg bestemte meg for å ta flere tilnærminger for å få nyttig informasjon fra sensoren. Her er de, ikke i noen rekkefølge:

  1. prøv litt grunnleggende programmering
  2. se gjennom noen online dokumentasjon om registre
  3. ta en titt på andres eksempler og / eller kode

Hvorfor disse tilnærmingene? Hvorfor ikke bare se etter et eksisterende bibliotek eller kode?

Ved å eksperimentere og prøve noen ideer, kan vi bedre absorbere litt kunnskap om ikke bare denne sensoren, men også få litt teknikk, ferdigheter og måter å tenke på å takle noe nytt, og noe som kanskje ikke har mye dokumentasjon; noe som kan ha mange ukjente.

Når vi har lekt med og prøvd ut noen av våre egne ideer og fått litt innsikt, er vi også bedre i stand til å evaluere andres kode eller bibliotek.

For eksempel, etter å ha sett på noen C ++ - koder for MPU9250 i github, skjønte jeg at det tvang meg til å bruke avbrudd, som jeg ennå ikke ønsker å gjøre.

Den kommer også med ekstra ting som kalibrering; igjen, noe jeg ikke er interessert i ennå.

Det kan være at det jeg trenger å gjøre for å svare på det enkle spørsmålet "er roboten som roterer ja eller nei" kan besvares veldig enkelt ved å lese noen registre.

Registre

I skrivende stund ser det ikke ut til å være mye tilgjengelig på denne sensoren. Faktisk, hvis du tar en titt på bildene som følger med denne instruksjonsboken, og ser nøye på påskriftene på de faktiske sjetongene, får jeg meg til å lure på om dette ikke er en knock-off. Jeg knytter ikke det jeg ser til noe fra Invense. Uansett valgte jeg å se på registerinformasjonen for modellene jeg fant: MPU-6050 og MPU-9250.

I begge tilfeller er følgende det samme for begge. Og for det første antar vi at det også vil være det samme for denne MPU-92/65.

59 til 64 - målinger av akselerometer

65, 66 - temperaturmålinger 67 til 72 - gyroskopmålinger 73 til 96 - eksterne sensordata

En merknad: MPU-6050 ser ut til IKKE å ha et magnetometer, mens MPU-9250 (og vi antar også at dette) har et.

Mer interessant, forhåpentligvis nyttig informasjon hentet fra registerdokumentet:

Magnetometer Info:

magnetometer id: 0x48 registrerer 00 til 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 HX0 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 HY12 HY11 HY10 HY9 HYZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ ST2 0 0 0 BITM HOFL 0 0 0 en oversikt over hva hvert register betyr: HXL [7: 0]: X-akse måledata lavere 8bit HXH [15: 8]: X-akse måledata høyere 8bit HYL [7: 0]: Y-akse måledata lavere 8bit HYH [15: 8]: Y-akse måledata høyere 8bit HZL [7: 0]: Z-akse måledata lavere 8bit HZH [15: 8]: Z-akse måledata høyere 8bit

Programmering

En annen bit informasjon fra registerdokumentene er at det så ut til å være omtrent 100 registre. Så en taktikk kan være å skrive et enkelt program som får tilgang til enheten (0x68) og prøver å lese en serie registre sekvensielt, uten å ta hensyn til deres betydning, bare for å se hvilke data som kan sees.

Og så gjør du påfølgende passeringer ved å bruke den samme koden, og sammenlign dataene fra det ene passet mot det neste.

Tanken er at vi sannsynligvis kan eliminere alle registre som ser ut til å ha ingen data (nuller eller FF?) Eller som absolutt aldri endres, og vi kan også fokusere på de som endres.

Deretter ser vi bare på de som endres, og legger til en gjennomsnittsfunksjon som gjennomsnitter de siste N -avlesningene i det registeret, for å se om det faktisk er en viss jevn verdi for det registret. Dette vil anta at vi holder sensoren veldig stille og på samme sted.

Til slutt kan vi forsiktig prøve ting med sensoren, for eksempel å skyve den (akselerometer, gyro), eller blåse på den (temperatur), eller rotere den (de to foregående pluss magnetometer) og se hvilken effekt dette har på verdiene.

Jeg liker å bruke wiringPi -biblioteket så mye som mulig. Den har støtte for I2C.

Første forsøk:

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

* å bygge: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * for å kjøre: sudo./first.test.mpu9265 * * dette programmet sender bare ut en rekke (mulige) registre fra MCP23017, * og deretter fra MPU9265 (eller en annen MPU på den 0x68 adressen) * * Jeg brukte den til å validere om jeg kunne lese fra sensoren, siden jeg allerede * hadde tillit til MCP23017. ************************************************ ****************************/ #include #include #include #include #include int main (int argc, char ** argv) {puts ("La oss se hva MCP23017 @ 0x20 har å si:"); errno = 0; int deviceId1 = 0x20; int fd1 = wiringPiI2CSetup (deviceId1); if (-1 == fd1) {fprintf (stderr, "Kan ikke åpne wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd1, reg)); fflush (stderr); forsinkelse (10); } setter (""); setter ("La oss se hva MPU9265 @ 0x20 har å si:"); errno = 0; int deviceId2 = 0x68; int fd2 = wiringPiI2CSetup (deviceId2); if (-1 == fd2) {fprintf (stderr, "Kan ikke åpne wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd2, reg)); fflush (stderr); forsinkelse (10); } setter (""); retur 0; }

Det andre løpet:

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

* å bygge: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * for å kjøre: sudo./second.test.mpu9265 * * Dette programmet sender ut registernummeret ved siden av verdien som er lest. * * Dette gjør det nyttig å pipe (omdirigere) utgangen til en fil, og deretter * kan flere kjøringer utføres for å sammenligne. Det kan gi litt innsikt i * hvilket register som er viktig, og hvordan dataene kan oppføre seg. ************************************************ ****************************/ #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; } annet hvis (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } annet hvis (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } setter ("La oss se hva MPU9265 @ 0x20 har å si:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Kan ikke åpne wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } for (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); forsinkelse (10); } returnere 0; }

Det tredje løpet:

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

* å bygge: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * for å kjøre: sudo./third.test.mpu9265 * * Dette programmet er et resultat av den andre. Den leser bare fra * registerene som indikerte en forskjell mellom en kjøring og den neste.************************************************ ****************************/ #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; } annet hvis (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } setter ("La oss se hva MPU9265 @ 0x20 har å si:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Kan ikke åpne wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } for (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); forsinkelse (10); } for (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); forsinkelse (10); } for (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); forsinkelse (10); } for (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); forsinkelse (10); } returnere 0; }

Så hva lærte vi så langt? Bildet av tabellen med fargede markerte områder indikerer at utgangen ser ut til å matche de første settene med registre.

Resultatene så langt kan generere nye spørsmål.

Spørsmål: Hvorfor er det bare ett registerresultat for den "eksterne" gruppen?

Spørsmål: hva er alle de ukjente registerene "??????"

Spørsmål: Siden programmet ikke er avbruddsdrevet, ba det om data for sakte? for fort?

Spørsmål: Kan vi påvirke resultatene ved å prøve ting med selve sensoren mens den kjører?

Trinn 6: La oss grave mer inn i avlesningene / dataene

Jeg tror det neste trinnet før alt annet er å forbedre programmet til:

  • være fleksibel i hvor mye sløyfeforsinkelse (ms)
  • være fleksibel i over hvor mange avlesninger som skal gi et løpende gjennomsnitt per register

(Jeg måtte legge ved programmet som en fil. Det syntes å være et problem å sette det inn her. "Fjerde.test.mpu9265.c")

Her er en løpetur med de siste 10 avlesningene for et gjennomsnitt, på en 10 ms sløyfe:

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

Den første, venstre kolonnen er registernummeret. Så kommer de siste 10 avlesningene for det registeret. Til slutt er den siste kolonnen gjennomsnittet for hver rad.

Det ser ut til at registrene 61, 69, 71, 189, 197 og 199 enten bare er binære eller klare / ikke klare, eller de er den høye byten til en 16-bits verdi (negativ?).

Andre interessante observasjoner:

  • registrerer 65, 193 - veldig jevn og samme verdi
  • register 63, 191 - veldig jevn og samme verdi
  • registrerer 73, 112, 195, 201, 240 - alt på null

La oss relatere disse observasjonene tilbake til det flerfargede, fremhevede tabellbildet fra tidligere.

Registrer 65 - temperatur

Registrer 193 - ??????

Registrer 63 - akselerometer

Registrer 191 - ??????

Register 73 - eksternt

Registrer 112 og videre - ??????

Vel, vi har fremdeles ukjente, men vi har lært noe nyttig.

Register 65 (temperatur) og register 63 (akselerometer) var begge veldig stabile. Dette er noe vi forventer. Jeg har ikke rørt sensoren; den beveger seg ikke, annet enn tilfeldige vibrasjoner, da roboten hviler på det samme bordet som datamaskinen min.

Det er en interessant test vi kan for hvert av disse temperatur-/akselerometerregistrene. For den testen trenger vi enda en versjon av programmet.

Trinn 7: Vi kan påvirke temperatur og akselerasjon

I de foregående trinnene reduserte vi minst ett register for temperatur, og ett for akselerasjon.

Med denne neste versjonen av programmet ("5th.test.mpu9265.c") kan vi faktisk se at en endring finner sted for begge registrene. Se videoene.

Mer graving

Hvis vi går tilbake og ser på registerinformasjonen, ser vi at det er:

  • tre 16 -biters utganger for gyroskop
  • tre 16 -biters utganger for akselerometer
  • tre 16 -bits utganger for magnetometer
  • en 16 bit utgang for temperatur

Resultatene oppnådd med våre enkle testprogrammer var imidlertid alle enkelt 8 -bits utganger. (enkeltregistre).

Så la oss prøve mer av den samme tilnærmingen, men denne gangen leser vi 16 bits i stedet for 8.

Vi må sannsynligvis gjøre noe som nedenfor. La oss bruke temperaturen som et eksempel, siden det bare er en 16 -bits utgang.

// få filbeskrivelse fd …

int tempRegHi = 65; int tempRegLo = 66; int hiByte = wiringPiI2CReadReg8 (fd, tempRegHi); int loByte = wiringPiI2CReadReg8 (fd, tempRegLo); int resultat = hiByte << 8; // legg hi -ordren 8 biter inn i den øvre delen av et 16 -bits verdi -resultat | = loByte; // legg nå til i rekkefølgen 8 bits, noe som gir et komplett 16 biters tall // skriv ut det nummeret eller bruk den horisontale graffunksjonen fra før

Fra våre tidligere trinn har vi sett at register 65 er ganske jevnt, mens register 66 er veldig bråkete. Siden 65 er høy rekkefølge byte, og 66 lav rekkefølge byte, er det fornuftig.

For lesing kan vi ta register 65-dataene som de er, men vi kan gjennomsnittlig registrere 66s verdier.

Eller vi kan bare gjennomsnittliggjøre hele resultatet.

Ta en titt på den siste videoen for denne delen; den demonstrerer å lese hele 16 bit temperaturverdien. Koden er "sixth.test.mpu9265.c"

Trinn 8: Akselerometer og gyroskop

Image
Image

Videoene for denne delen viser utgang fra akselerometeret og gyroskopet, ved hjelp av et testprogram "seventh.test.mpu9265.c". Denne koden kan lese 1, 2 eller 3 påfølgende byte-par (hi og lo byte) og konverterer verdiene til en enkelt 16-bits verdi. Dermed kan vi lese en enkelt akse, eller vi kan lese to av dem sammen (og det summerer endringene), eller vi kan lese alle tre (og det summerer endringene).

For å gjenta, for denne fasen, for denne Instructable, jeg er bare ute etter å svare på et enkelt spørsmål: "roterte/svingte roboten?". Jeg leter ikke etter noen presis verdi, for eksempel roterte den 90 grader. Det vil komme senere når vi kommer til å gjøre SLAM, men det er ikke nødvendig for enkel hindring av hindringer og tilfeldig bevegelse.

Trinn 9: (pågår) Magnetometeret

når du bruker i2cdetect -verktøyet, viser MPU9265 seg som 0x68 i tabellen:

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: -- -- -- -- -- -- -- --

Det kreves ekstra trinn for å lese fra magnetometerdelen av IMU.

Fra Invesense -registerene PDF -dokument:

REGISTRERINGER 37 TIL 39 - I2C SLAVE 0 KONTROLL

  • REGISTRER 37 - I2C_SLV0_ADDR
  • REGISTRERE 38 - I2C_SLV0_REG
  • REGISTRERE 39 - I2C_SLV0_CTRL

Anbefalt: