Innehållsförteckning:
- Steg 1: IMU -sensorn
- Steg 2: Det är inte alltid rent, enkelt
- Steg 3: Första testet
- Steg 4: Felsökning
- Steg 5: Läsa sensordata
- Steg 6: Låt oss gräva mer i avläsningarna / data
- Steg 7: Vi kan påverka temperatur och acceleration
- Steg 8: Accelerometer och gyroskop
- Steg 9: (pågår) Magnetometern
Video: Wallace - DIY Autonomous Robot - Del 5 - Lägg till IMU: 9 steg
2024 Författare: John Day | [email protected]. Senast ändrad: 2024-01-30 12:45
Vi fortsätter tillsammans med Wallace. Namnet Wallace kom från en blandning av "Wall-E", och från ett tidigare projekt (röstigenkänning), och när det använde "espeak" -verktyget lät det lite brittiskt. Och som en betjänad eller butler. Och det är slutmålet: att det här projektet ska bli något användbart. Alltså "Wallace".
Wallace kan röra sig, han kan undvika hinder med hjälp av IR -avståndssensorer (nyligen, på något sätt stekte de (?) (Måste titta på det när jag får en chans), har också några akustiska avståndssensorer (tre av dem gick dåligt samtidigt) tid, tillsammans med en MCP23017 expander), och slutligen kan detektera förändringar i motorström för att veta när det stöter på något.
Förutom sensorerna "minns" Wallace de 100 rörelserna och har en rudimentär analys med hjälp av rörelseshistoriken.
Målet hittills för Wallace är att bara försöka fortsätta framåt och att veta när det har fastnat i något upprepande mönster (som i ett hörn) och inte riktigt gå framåt.
Jag har gått igenom flera iterationer för rörelse och navigering, och den konsekventa huvudvärken har varit under rotation.
Eftersom Wallace är en spårad robot, och jag ville hålla saker enklare i programvaran (för senare), för att vända, har jag bara honom att svänga/rotera på plats. Applicera alltså motorerna lika men motsatt effekt / driftcykel.
Problemet beror på utformningen av robotplattformen Agent 390. Spårbälten tenderar att gnugga mot sidorna. Och värre, den ena sidan gör det mer än den andra.
På golv och gå rakt har det inte varit några problem. Det dyker upp på mattor. Jag valde att hålla Wallace borta från mattorna efter att spåren blev smutsiga (de tar upp smuts extremt lätt).
Det verkliga problemet är när man svänger på golv.
Om jag har programvaran tillämpa en hög arbetscykel, blir den mer eller mindre konsekvent. Men under en lågdriftscykel kan den faktiskt vända eller inte. Eller det kan vända lite och sedan sakta ner. Den svängbara åtgärden verkar vara okontrollerbar via programvaran, eller i bästa fall mycket svår.
Problemet dyker upp under navigering och rörelse runt eller bort från hinder. Det kan antingen svänga för vilt bort, eller så kan det fastna i ett försök att göra väldigt små skift utan att ens röra sig.
Och så motiverade ovanstående förklaring denna instruerbara.
Inledningsvis hade jag velat avstå från eller fördröja införandet av en rörelsedetekterande enhet (IMU), eftersom de är A) komplicerade, B) bullriga, C) fel kan introduceras över tid, etc., etc. Min tanke hade varit att vi skulle kunna göra mycket bra genom att hoppa fram till IR-sensorer vid tidpunkten för flygningen. Och vi kunde - med hjälp av lasrar kunde vi veta om roboten roterade eller inte, genom att spåra förändringar i avstånd.
Faktum är att vi också (typ) kunde göra det nu med de akustiska sensorerna.
Men allt detta är ett mycket indirekt, komplicerat sätt att svara på en enkel fråga: "har vi roterat eller inte?"
Det verkade för mig att hoppa för att använda ToF lasersensorer skulle ta mig till nästa nivå av programvara; nämligen SLAM (Simultan lokalisering och kartläggning). Jag var inte redo att åka dit ännu.
Det är bra att göra ett robotprojekt i lager, där de första (nedre) lagren är enklare och de senare (övre) skikten är mer abstrakta och hanterar svårare frågor.
Lager kan tänkas på något så här:
- robot fysisk ram / mekanisk strukturell grund
- rudimentärt drivsystem (hallon, Roboclaw, motorer, kablage, etc, grundläggande programvara, tangentborddriven)
- väsentliga kretsar för att stödja sensorer (dubbelriktad spänningsväxel, portexpander, E-Stop, effektfördelning, etc.)
- hinder-undvikande sensorer (akustiska, IR)
- väsentlig, grundläggande positionering och rörelse - detektering (accelerometer, gyro, magnetometer, motorkodare, hjulkodare)
Du kan komma med en egen lista. Poängen med den här listan är att du förmodligen borde göra dessa mer eller mindre i den ordningen, och också att om du spenderar lite tid på varje lager för att få varje till ett gott fungerande tillstånd, bör det hjälpa dig senare eftersom sakerna blir mer komplicerade.
Ovanstående lista kan mer eller mindre mappas till dessa konceptuella lager i programvara.
- SLAM (samtidig lokalisering och kartläggning)
- Kontroll och medvetenhet om rörelse, rotation
- Grundläggande undvikande av hinder
- Kontroll och detektion av sensordata
- Viktig rörelse framåt, bakåt, vänster och höger, snabba upp, sakta ner, stoppa
Som du kan se, för den här listan, skulle de första objekten vara de övre, mer komplicerade skikten som hanterar mer abstrakta frågor och frågor, till exempel "var är jag" och "vart ska jag", medan de senare objekten skulle vara lägre mjukvarulager som hanterar "hur man pratar/lyssnar på sensor A" eller "hur man flyttar detta hjul".
Nu säger jag inte att när du börjar på ett lager har du slutfört det och sedan är det på nästa lager, för att aldrig återgå till det föregående. Ett robotprojekt kan likna moderna, iterativa utvecklingsmetoder för mjukvara (agile, SCRUM, etc).
Jag säger bara att ta tid vid varje. Du måste balansera hur mycket du ska göra vid varje och bestämma vad du försöker på ett visst lager som är värt tiden och besväret.
Det finns en viss "konflikt" eller "spänning" mellan två konkurrerande idéer eller riktningar.
En är vad jag skulle kalla "plug-n-play" för att lösa problem A.
Den andra är DIY (gör det själv). Och det kanske inte ens är den bästa etiketten för denna andra idé.
Här är ett exempel på varje, förhoppningsvis ser du spänningen eller konflikten mellan de två alternativen.
I det här exemplet, låt oss klumpa SLAM, undvikande av hinder och grundläggande grundrörelser som ett problem att lösa samtidigt.
- Om vi bestämmer oss för att gå plug-n-play-rutten hoppar vi omedelbart (beroende på budget) till saker som de toppmonterade roterande lasrarna eller skärpedjupskameran eller ToF-lasrar och IMU (ämnet för detta Instruerbar).
- Om vi å andra sidan vill gå den andra vägen kan vi försöka extrahera all möjlig information från några akustiska sensorer eller IR -sensorer, eller inga sensorer alls - vi använder bara motorströmövervakning (bump)
Vad kan man säga om #1 vs #2? En sak skulle vara att vi kommer att ha lärt oss mycket mer genom att göra #2. Begränsningarna i att bara ha akustiska sensorer att arbeta med tvingar oss att tänka på mycket fler frågor.
Å andra sidan, om vi är för fokuserade på att göra saker via #2, kan vi slösa tid, eftersom vi ber om mer än vi borde från akustiska sensorer.
Ytterligare ett koncept eller en idé att tänka på: Vilken blandning av hårdvara och mjukvara svarar bäst på frågorna "hur man", och vilken blandning av programvara (och hårdvara?) Svarar på frågan "vad", "när", "var". För "hur" är vanligtvis en lägre nivå som "vad", "när" och "var" beror på för att få svar.
Hur som helst, allt ovan var bara något att tänka på.
I mitt fall, efter mycket ansträngning och med den konsekvent irriterande frågan om spårfriktion och inte kan få konsekvent kontroll och rörelse, är det dags att göra något annat.
Således denna instruerbara - en IMU.
Målet är att om IMU säger att roboten INTE svänger, ökar vi arbetscykeln. Om vi svänger för snabbt minskar vi arbetscykeln.
Steg 1: IMU -sensorn
Och så är vår nästa sensor att lägga till i Wallace IMU. Efter lite undersökning bestämde jag mig för en MPU6050. Men då vid den här tiden verkade MPU9050 (och ännu mer nyligen, MPU9250) som en ännu bättre idé.
Min källa har varit Amazon (i USA). Så jag beställde två av dem.
Det jag faktiskt fick (det verkar inte finnas någon kontroll över detta; det är det jag inte gillar med Amazon) var två MPU92/65. Jag undrar lite över beteckningen. Ta en titt på bilderna; det verkar vara en "familj" beteckning. Det är i alla fall vad jag har fastnat för.
Att lägga till det är väldigt enkelt -få ett proto -kort med anslutande spår, löd sensorn på kortet, lägg till en 10 -polig skruvplint (jag fick min från Pololu).
För att minimera störningar försökte jag placera dessa sensorer bort från allt annat.
Det innebar också att använda några nylonbultar/muttrar.
Jag kommer att använda I2C -protokollet. Förhoppningsvis blir den totala trådlängden inte så dålig.
Det finns gott om information någon annanstans om de grundläggande anslutningarna och spänningsnivåerna osv, så jag kommer inte att upprepa det här.
Steg 2: Det är inte alltid rent, enkelt
Vid detta skrivande verkar det inte finnas mycket online för just den här MPU-92/65. Det som är tillgängligt, precis som med de flesta sensorer, verkar vara exempel med Arduino.
Jag försöker göra dessa instruktioner lite annorlunda genom att presentera en inte så ren process, eftersom saker inte alltid fungerar direkt.
Jag antar att dessa instruktioner liknar mer en blogg än rak A-B-C, 1-2-3 "så här gör du".
Steg 3: Första testet
Från bilderna i föregående steg är naturligtvis de röda och svarta ledningarna som går till sensorerna VCC (5V) och GND. De gröna och gula ledningarna är I2C -anslutningarna.
Om du har gjort andra I2C -projekt, eller har följt med dessa serier, vet du redan om "i2cdetect", och det är det första steget för att veta om Hallon kan se den nya sensorn.
Som du kan se från bilderna i detta steg var vårt första försök misslyckat. IMU visas inte (ska vara enhets -id 0x68).
Den goda nyheten är dock att I2C -bussen fungerar. Vi ser en enhet 0x20 och det är MCP23017 port expander (för närvarande ansvarig för HCSR04 akustiska sensorer).
Det är inte lätt att se på bilden, men jag anslöt samma färgade gröna och gula trådar från IMU till MCP23017 (se nedre vänster på bilden)
Vi måste göra lite felsökning.
Steg 4: Felsökning
Med kontinuitetsinställningen på en voltmeter (den med hög ton) testade jag VCC (5V), GND, SDA och SCL-anslutningar. De var bra.
Nästa försök var att koppla bort MCP23017 från I2C-bussen och lämna bara MPU-92/65 kvar på bussen. Det visade sig vara fruktlöst - "i2cdetect" visade då inga enheter.
Så därefter avmonterade jag sensorn från totempolen och kopplade om den direkt till 5V-till-3V dubbelriktad buss; dvs direkt till hallon. (kortare ledningar?).
Och voila. Den här gången är det framgång. Vi ser att 0x68 dyker upp med "i2cdetect".
Men vi vet ännu inte varför det fungerade den här gången. Kan det vara längden på trådarna? Den tidigare platsen?
Obs: Det gjorde ingen skillnad om ADO var jordat eller inte. Det kan vara att det finns inbyggda pullup- och neddragningsmotstånd. Detsamma kan gälla för FSYNC.
Därefter kopplade jag om MCP23017. Så nu har vi två enheter på I2C -bussen. (se bild). Lyckas, vi ser nu både 0x20 och 0x68 med i2cdetect.
Videorna går in lite mer på vad som hände under felsökningen.
Steg 5: Läsa sensordata
Olika tillvägagångssätt
Jag bestämde mig för att ta flera metoder för att få användbar information från sensorn. Här är de, inte i någon ordning:
- prova lite grundläggande programmering
- titta igenom lite onlinedokumentation om register
- ta en titt på andras exempel och / eller kod
Varför dessa tillvägagångssätt? Varför inte bara leta efter ett befintligt bibliotek eller en kod?
Genom att experimentera och prova några idéer kan vi bättre absorbera viss kunskap om inte bara den här sensorn, utan också få lite teknik, skicklighet och sätt att tänka på att ta itu med något nytt och något som kanske inte har mycket dokumentation; något som kan ha många okända.
När vi väl har lekt med och testat några av våra egna idéer och fått lite insikt är vi bättre i stånd att utvärdera någon annans kod eller bibliotek.
Till exempel, efter att ha tittat på någon C ++ - kod för MPU9250 i github, insåg jag att det tvingade mig att använda avbrott, vilket jag ännu inte vill göra.
Det kommer också med extra saker som kalibrering; igen, något jag ännu inte är intresserad av.
Det kan vara så att det jag behöver göra för att svara på den enkla frågan "är roboten som roterar ja eller nej" skulle kunna besvaras mycket enkelt genom att bara läsa några register.
Register
Vid detta skrivande verkar det inte finnas så mycket tillgängligt på den här sensorn. Faktum är att om du tittar på bilderna som följer med denna Instructable och tittar noga på inskriptionerna på de faktiska chipsen, får det mig att undra om det här inte är en knock-off. Jag relaterar inte vad jag ser till något från Invense. Oavsett valde jag att titta på registerinformationen för de modeller jag hittade: MPU-6050 och MPU-9250.
I båda fallen är följande detsamma för båda. Och till att börja med antar vi att det också kommer att vara samma för denna MPU-92/65.
59 till 64 - accelerometermätningar
65, 66 - temperaturmätningar 67 till 72 - gyroskopmätningar 73 till 96 - externa sensordata
En anmärkning: MPU-6050 verkar INTE ha en magnetometer, medan MPU-9250 (och vi antar att den här också) har en.
Lite mer intressant, förhoppningsvis användbar information som hämtats från registerdokumentet:
Magnetometerinformation:
magnetometer id: 0x48 register 00 till 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 HY HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ HZ ST2 0 0 0 BITM HOFL 0 0 0 en uppdelning av vad varje register betyder: HXL [7: 0]: X-axelmätdata lägre 8bit HXH [15: 8]: X-axelmätdata högre 8bit HYL [7: 0]: Y-axels mätdata lägre 8bit HYH [15: 8]: Y-axels mätdata högre 8bit HZL [7: 0]: Z-axels mätdata lägre 8bit HZH [15: 8]: Z-axels mätdata högre 8bit
Programmering
En annan bit information från registerdokumenten är att det bara tycktes finnas cirka 100 register. Så en taktik kan vara att skriva ett enkelt program som har åtkomst till enheten (0x68) och försöker läsa en serie register i följd, utan att ta hänsyn till deras betydelse, bara för att se vilken data som kan ses.
Och sedan, gör på varandra följande pass, med samma kod, och jämför data från en pass vs nästa.
Tanken är att vi förmodligen kan eliminera alla register som verkar ha inga data (nollor eller FF?) Eller som absolut aldrig ändras, och vi kan också fokusera på de som ändras.
Sedan, vi tittar bara på de som ändras, lägger till en medelvärdesfunktion som medelvärderar de senaste N -läsningarna i det registret, för att se om det faktiskt finns ett visst stabilt värde för det registret. Detta skulle anta att vi håller sensorn väldigt stilla och på samma plats.
Slutligen kan vi försiktigt prova saker med sensorn, som att knuffa den (accelerometer, gyro) eller blåsa på den (temperatur) eller rotera den (de två föregående plusmagnetometern) och se vilken effekt detta har på värdena.
Jag gillar att använda wiringPi -biblioteket så mycket som möjligt. Den har stöd för I2C.
Första omgången:
/********************************************************************************
* att bygga: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * för att köra: sudo./first.test.mpu9265 * * detta program har bara matat ut en rad (möjliga) register från MCP23017, * och sedan från MPU9265 (eller någon annan MPU på den 0x68 -adressen) * * Jag använde den för att validera om jag ens kunde läsa från sensorn, eftersom jag redan * hade förtroende för MCP23017. ************************************************** ****************************/ #include #include #include #include #include int main (int argc, char ** argv) {puts ("Låt oss se vad MCP23017 @ 0x20 har att säga:"); errno = 0; int deviceId1 = 0x20; int fd1 = wiringPiI2CSetup (deviceId1); if (-1 == fd1) {fprintf (stderr, "Kan inte öppna wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } för (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd1, reg)); fflush (stderr); fördröjning (10); } sätter (""); sätter ("Låt oss se vad MPU9265 @ 0x20 har att säga:"); errno = 0; int deviceId2 = 0x68; int fd2 = wiringPiI2CSetup (deviceId2); if (-1 == fd2) {fprintf (stderr, "Kan inte öppna wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } för (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d", wiringPiI2CReadReg8 (fd2, reg)); fflush (stderr); fördröjning (10); } sätter (""); returnera 0; }
Den andra omgången:
/********************************************************************************
* att bygga: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * to run: sudo./second.test.mpu9265 * * Detta program matar ut registernumret vid sidan av värdet läst. * * Detta gör det användbart att pipa (omdirigera) utmatningen till en fil, och sedan * kan flera körningar göras för att jämföra. Det kan ge en inblick i * vilket register som är viktigt och hur uppgifterna kan bete sig. ************************************************** ****************************/ #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; } annars if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } annars if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } sätter ("Låt oss se vad MPU9265 @ 0x20 har att säga:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Kan inte öppna wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } för (int reg = 0; reg <300; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); fördröjning (10); } returnera 0; }
Den tredje körningen:
/********************************************************************************
* att bygga: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * to run: sudo./third.test.mpu9265 * * Detta program är ett resultat av den andra. Den läser bara från * registren som indikerar skillnad mellan en körning och nästa.************************************************** ****************************/ #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; } annars if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } sätter ("Låt oss se vad MPU9265 @ 0x20 har att säga:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Kan inte öppna wiringPi I2C-enhet: %s / n", strerror (errno)); retur 1; } för (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); fördröjning (10); } för (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); fördröjning (10); } för (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); fördröjning (10); } för (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "%d:%d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); fördröjning (10); } returnera 0; }
Så vad har vi lärt oss hittills? Bilden av tabellen med färgade markerade områden indikerar att utmatningen verkar matcha de första uppsättningarna register.
Resultaten hittills kan generera nya frågor.
Fråga: varför finns det bara ett registerresultat för den "externa" gruppen?
Fråga: vad är alla de okända registren "??????"
Fråga: eftersom programmet inte är avbrottsdrivet, begärde det data för långsamt? för snabbt?
Fråga: kan vi påverka resultaten genom att prova saker med själva sensorn när den körs?
Steg 6: Låt oss gräva mer i avläsningarna / data
Jag tror att nästa steg före allt annat är att förbättra programmet till:
- Var flexibel i hur mycket loopfördröjning (ms)
- vara flexibel över hur många avläsningar som ska ge ett löpande genomsnitt per register
(Jag var tvungen att bifoga programmet som en fil. Verkade vara ett problem att infoga det här. "Fjärde.test.mpu9265.c")
Här är en körning med de senaste 10 avläsningarna för ett genomsnitt, vid en 10 ms slinga:
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örsta, vänsterkolumnen är registernumret. Sedan kommer de tio sista avläsningarna för det registret. Slutligen är den sista kolumnen genomsnittet för varje rad.
Det ser ut som om registren 61, 69, 71, 189, 197 och 199 antingen bara är binära eller klara / inte klara, eller så är de höga byten för ett 16-bitars värde (negativt?).
Andra intressanta observationer:
- register 65, 193 - mycket stabilt och samma värde
- register 63, 191 - mycket stabilt och samma värde
- register 73, 112, 195, 201, 240 - allt på noll
Låt oss relatera dessa observationer till den flerfärgade, markerade tabellbilden från tidigare.
Registrera 65 - temperatur
Registrera 193 - ??????
Registrera 63 - accelerometer
Registrera 191 - ??????
Register 73 - externt
Registrera 112 och vidare - ??????
Tja, vi har fortfarande okända, men vi har lärt oss något användbart.
Register 65 (temperatur) och register 63 (accelerometer) var båda mycket stabila. Detta är något vi kan förvänta oss. Jag har inte rört sensorn; den rör sig inte, förutom några tillfälliga vibrationer, eftersom roboten vilar på samma bord som min dator.
Det finns ett intressant test vi kan för vart och ett av dessa temperatur/accelerometer -register. För det testet behöver vi ännu en version av programmet.
Steg 7: Vi kan påverka temperatur och acceleration
I de föregående stegen minskade vi åtminstone ett register för temperatur och ett för acceleration.
Med den här nästa versionen av programmet ("5th.test.mpu9265.c") kan vi faktiskt se att en förändring sker för båda registren. Se videorna.
Mer grävning
Om vi går tillbaka och tittar på registerinformationen ser vi att det finns:
- tre 16 -bitars utgångar för gyroskop
- tre 16 -bitars utgångar för accelerometer
- tre 16 -bitars utgångar för magnetometer
- en 16 -bitars utmatning för temperatur
Resultaten från våra enkla testprogram var emellertid alla enkla 8 -bitars utgångar. (enstaka register).
Så låt oss prova mer av samma tillvägagångssätt, men den här gången läser vi 16 bitar istället för 8.
Vi kommer förmodligen att behöva göra något som nedan. Låt oss använda temperaturen som ett exempel, eftersom det bara är en 16 -bitars utmatning.
// få filbeskrivning fd …
int tempRegHi = 65; int tempRegLo = 66; int hiByte = wiringPiI2CReadReg8 (fd, tempRegHi); int loByte = wiringPiI2CReadReg8 (fd, tempRegLo); int resultat = hiByte << 8; // lägg hi -ordern 8 bitar i den övre delen av ett 16 -bitars värde -resultat | = loByte; // lägg nu till i ordningen 8 bitar, vilket ger ett komplett 16 bitars nummer // skriv ut det numret eller använd den horisontella grafiska funktionen från tidigare
Från våra tidigare steg har vi sett att register 65 är ganska stabilt, medan register 66 är mycket bullrigt. Eftersom 65 är hi -order -byte och 66 low -order -byte, är det vettigt.
För läsning kan vi ta register 65: s data som de är, men vi kan genomsnittliga register 66: s värden.
Eller så kan vi bara genomsnittliga hela resultatet.
Ta en titt på den sista videon för denna del; det visar att man läser hela 16 bitars temperaturvärde. Koden är "sixth.test.mpu9265.c"
Steg 8: Accelerometer och gyroskop
Videorna för detta avsnitt visar utmatning från accelerometern och gyroskopet med ett testprogram "seventh.test.mpu9265.c". Den koden kan läsa 1, 2 eller 3 på varandra följande byte-par (hi och lo byte) och konverterar värdena till ett enda 16 bitars värde. Således kan vi läsa vilken enskild axel som helst, eller så kan vi läsa två av dem tillsammans (och det summerar förändringarna), eller så kan vi läsa alla tre (och det summerar förändringarna).
För att upprepa, för denna fas, för denna instruerbara, jag bara vill svara på en enkel fråga: "roterade/svängde roboten?". Jag letar inte efter något exakt värde, till exempel, roterade det 90 grader. Det kommer senare när vi kommer att göra SLAM, men det krävs inte för enkel hindring och slumpmässig rörelse.
Steg 9: (pågår) Magnetometern
när du använder i2cdetect -verktyget visas MPU9265 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 krävs extra steg för att läsa från magnetometerdelen av IMU.
Från Invesense -registren PDF -dokument:
REGISTRERINGAR 37 TILL 39 - I2C SLAVE 0 CONTROL
- REGISTRERA 37 - I2C_SLV0_ADDR
- REGISTRERA 38 - I2C_SLV0_REG
- REGISTRERA 39 - I2C_SLV0_CTRL
Rekommenderad:
Raspberry PI 3 - Aktivera seriell kommunikation till TtyAMA0 till BCM GPIO 14 och GPIO 15: 9 steg
Raspberry PI 3 - Aktivera seriell kommunikation till TtyAMA0 till BCM GPIO 14 och GPIO 15: Jag hade nyligen intresse av att aktivera UART0 på min Raspberry Pi (3b) så att jag kunde ansluta den direkt till en RS -232 signalnivåenhet med en standard 9 -nål d-sub-kontakt utan att behöva gå via en USB till RS-232-adapter. En del av mitt intresse
Lägga till nya bibliotek till KICAD: 6 steg
Lägga till nya bibliotek till KICAD: KiCad är en gratis mjukvarupaket för elektronisk designautomation (EDA). Det underlättar utformningen av scheman för elektroniska kretsar och deras konvertering till PCB -konstruktioner. Den har en integrerad miljö för schematisk fångst och PCB -layout
Lägga till en Snabbladdningsfunktion till en Powerbank: 5 steg (med bilder)
Lägga till en Snabbladdningsfunktion till en Powerbank: I det här projektet kommer jag att visa dig hur jag modifierade en vanlig powerbank för att minska den löjligt långa laddningstiden. Längs vägen kommer jag att prata om powerbank -kretsen och varför batteriet i min powerbank är lite speciellt. Låt oss få st
Hur man lägger till en IR -fjärrkontroll till ett högtalarsystem: 5 steg (med bilder)
Hur man lägger till en IR -fjärrkontroll till ett högtalarsystem: I det här projektet kommer jag att visa dig hur jag skapade en extra krets för mitt högtalarsystem för att styra det trådlöst med en hemgjord IR -fjärrkontroll. Låt oss börja
Hur man lägger till videor till din iPhone från Ubuntu: 4 steg
Så här lägger du till videor till din iPhone från Ubuntu: Om du använder Ubuntu och iPhone kanske du vill lägga till några videor till din enhet med din dator. Oroa dig inte, det är ganska enkelt och kräver inte att du jailbreak din iPhone