Innholdsfortegnelse:

MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p): 5 trinn
MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p): 5 trinn

Video: MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p): 5 trinn

Video: MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p): 5 trinn
Video: Arduino Nano and GY-521 MPU6050 3-осевой гироскоп, 3-осевой акселерометр и DMP 2024, Juli
Anonim
MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p)
MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p)
MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p)
MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p)
MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p)
MPU 6050 Gyro, akselerometerkommunikasjon med Arduino (Atmega328p)

MPU6050 IMU har både 3-akset akselerometer og 3-akset gyroskop integrert på en enkelt brikke.

Gyroskopet måler rotasjonshastigheten eller endringshastigheten til vinkelposisjonen over tid, langs X-, Y- og Z -aksen.

Utgangene til gyroskopet er i grader per sekund, så for å få vinkelposisjonen trenger vi bare å integrere vinkelhastigheten.

På den annen side måler MPU6050 -akselerometeret akselerasjon ved å måle gravitasjonsakselerasjon langs de 3 aksene og ved hjelp av noen trigonometri -matematikk kan vi beregne vinkelen som sensoren er plassert i. Så hvis vi smelter sammen eller kombinerer akselerometer- og gyroskopdata, kan vi få veldig nøyaktig informasjon om sensorretningen.

3-akset gyroskop MPU-6050 består av et 3-akset gyroskop som kan detektere rotasjonshastighet langs x, y, z-aksen med mikroelektromekanisk systemteknologi (MEMS). Når sensoren roteres langs en hvilken som helst akse, produseres en vibrasjon på grunn av Coriolis-effekten som oppdages av MEMS. 16-biters ADC brukes til å digitalisere spenning for å prøve hver akse. +/- 250, +/- 500, +/- 1000, +/- 2000 er hele skalaen for utgang. Vinkelhastighet måles langs hver akse i grad per sekund enhet.

Nyttig lenke: …………….

Arduino Board:. ……….

MPU6050 IMU ……………

Trinn 1: MPU-6050-modul

MPU-6050-modul
MPU-6050-modul

MPU-6050-modulen har 8 pinner,

INT: Avbryt digital utgangspinne.

AD0: I2C Slave Address LSB pin. Dette er 0. bit i 7-biters slave-adresse til enheten. Hvis den er koblet til VCC, leses den som logisk en og endringer i slaveadressen.

XCL: Auxiliary Serial Clock pin. Denne pinnen brukes til å koble andre I2C-grensesnittaktiverte sensorer SCL-pinne til MPU-6050.

XDA: Auxiliary Serial Data pin. Denne pinnen brukes til å koble andre I2C-grensesnittaktiverte sensorer SDA-pinne til MPU-6050.

SCL: Seriell klokkepinne. Koble denne pinnen til mikrokontrollerne SCL -pinne. SDA: Serial Data pin. Koble denne pinnen til mikrokontrollerne SDA -pinnen.

GND: Jordnål. Koble denne pinnen til jordforbindelsen.

VCC: Strømforsyningspinne. Koble denne pinnen til +5V DC forsyning. MPU-6050-modulen har Slave-adresse (Når AD0 = 0, det vil si at den ikke er koblet til Vcc) som, Slave Skriv adresse (SLA+W): 0xD0

Slave Read -adresse (SLA+R): 0xD1

Trinn 2: Beregninger

Beregninger
Beregninger

Gyroskop- og akselerometer-sensordata for MPU6050-modulen består av 16-biters rådata i 2s komplementform.

Temperatursensordata for MPU6050-modulen består av 16-biters data (ikke i 2-komplementform).

Anta nå at vi har valgt,

  • - Akselerometer full skala på +/- 2g med følsomhetsskala faktor på 16, 384 LSB (telling)/g.
  • - Gyroskop fullt skalaområde på +/- 250 °/s med følsomhetsskala-faktor på 131 LSB (telling)/°/s. deretter,

For å få sensordata, må vi først utføre 2 -komplement på sensordata fra Accelerometer og gyroskop. Etter å ha fått sensordata kan vi beregne akselerasjon og vinkelhastighet ved å dele sensorens rådata med følsomhetsskalafaktoren som følger-

Akselerometerverdier i g (g kraft)

  • Akselerasjon langs X -aksen = (Accelerometer X -akse rådata/16384) g.
  • Akselerasjon langs Y -aksen = (Accelerometer Y -akse rådata/16384) g.
  • Akselerasjon langs Z -aksen = (Accelerometer Z -aksens rådata/16384) g.

Gyroskopverdier i °/s (grad per sekund)

  • Vinkelhastighet langs X -aksen = (Gyroskop X -aksens rådata/131) °/s.
  • Vinkelhastighet langs Y -aksen = (Gyroskop Y -akse rådata/131) °/s.
  • Vinkelhastighet langs Z -aksen = (Gyroskop Z -aksens rådata/131) °/s.

Temperaturverdi i °/c (grad per Celsius)

Temperatur i grader C = ((temperatursensordata)/340 + 36,53) °/c.

For eksempel, Anta at etter 2’komplement får vi akselerometer X -akser råverdi = +15454

Deretter er Ax = +15454/16384 = 0,94 g.

Mer,

Så vi vet at vi kjører med en følsomhet på +/- 2G og +/- 250deg/s, men hvordan samsvarer våre verdier med disse akselerasjonene/vinklene.

Dette er begge rettlinjede grafer, og vi kan regne ut fra dem at for 1G vil vi lese 16384 og for 1 grader/sek vil vi lese 131.07 (Selv om.07 blir ignorert på grunn av binær) ble disse verdiene bare beregnet ved å tegne rettlinjediagram med 2G ved 32767 og -2G ved -32768 og 250/-250 ved samme verdier.

Så nå kjenner vi følsomhetsverdiene våre (16384 og 131.07), vi trenger bare å minus forskyvningene fra våre verdier og deretter dele på sensitiviteten.

Disse vil fungere fint for X- og Y -verdiene, men ettersom Z ble registrert ved 1G og ikke 0, må vi minus 1G (16384) før vi deler med vår følsomhet.

Trinn 3: MPU6050-Atmega328p-tilkoblinger

MPU6050-Atmega328p-tilkoblinger
MPU6050-Atmega328p-tilkoblinger
MPU6050-Atmega328p-tilkoblinger
MPU6050-Atmega328p-tilkoblinger
MPU6050-Atmega328p-tilkoblinger
MPU6050-Atmega328p-tilkoblinger

Bare koble til alt som vist i diagrammet …

Tilkoblingene er gitt som følger:-

MPU6050 Arduino Nano

VCC 5v utpinne

GND Jordnål

SDA A4 pin // seriell data

SCL A5 pin // seriell klokke

Beregning av pitch og roll: Roll er rotasjonen rundt x-aksen og pitch er rotasjonen langs y-aksen.

Resultatet er i radianer. (konverter til grader ved å multiplisere med 180 og dividere med pi)

Trinn 4: Koder og forklaringer

Koder og forklaringer
Koder og forklaringer

/*

Arduino og MPU6050 Accelerometer and Gyroscope Sensor Tutorial av Dejan, https://howtomechatronics.com */#include const int MPU = 0x68; // MPU6050 I2C adresse float AccX, AccY, AccZ; flyte GyroX, GyroY, GyroZ; float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; float roll, pitch, yaw; float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ; float elapsedTime, currentTime, previousTime; int c = 0; ugyldig oppsett () {Serial.begin (19200); Wire.begin (); // Initialiser kommunikasjon Wire.beginTransmission (MPU); // Start kommunikasjon med MPU6050 // MPU = 0x68 Wire.write (0x6B); // Snakk med registeret 6B Wire.write (0x00); // Gjør tilbakestilling - plasser en 0 i 6B -registeret Wire.endTransmission (true); // avslutte overføringen/* // Configure Accelerometer Sensitivity - Full Scale Range (standard +/- 2g) Wire.beginTransmission (MPU); Wire.write (0x1C); // Snakk med ACCEL_CONFIG -registeret (1C hex) Wire.write (0x10); // Sett registerbitene som 00010000 (+/- 8g full skala) Wire.endTransmission (true); // Configure Gyro Sensitivity - Full Scale Range (standard +/- 250deg/s) Wire.beginTransmission (MPU); Wire.write (0x1B); // Snakk med GYRO_CONFIG -registeret (1B hex) Wire.write (0x10); // Sett registerbitene som 00010000 (1000deg/s full skala) Wire.endTransmission (true); forsinkelse (20); */ // Ring denne funksjonen hvis du trenger å få IMU feilverdier for modulen calcul_IMU_error (); forsinkelse (20); } void loop () {// === Les akseleromter data === // Wire.beginTransmission (MPU); Wire.write (0x3B); // Start med register 0x3B (ACCEL_XOUT_H) Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); // Les totalt 6 registre, hver akseverdi lagres i 2 registre // For et område på +-2g må vi dele råverdiene med 16384, i henhold til databladet AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; // X-akse verdi AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Y-aksens verdi AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Z -akseverdi // Beregning av rull og pitch fra akselerometerdata accAngleX = (atan (AccY / sqrt (pow (AccX, 2) + pow (AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~ (0.58) Se beregnings_IMU_feil () egendefinert funksjon for flere detaljer accAngleY = (atan (-1 * AccX / sqrt (pow (AccY, 2) + pow (AccZ, 2))) * 180 / PI) + 1,58; // AccErrorY ~ (-1.58) // === Les gyroskopdata === // previousTime = currentTime; // Tidligere tid lagres før den faktiske tiden leser currentTime = millis (); // Aktuell tid faktisk tid lest elapsedTime = (currentTime - previousTime) / 1000; // Del med 1000 for å få sekunder Wire.beginTransmission (MPU); Wire.write (0x43); // Gyrodata registrerer først adresse 0x43 Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); // Les totalt 4 registre, hver akseverdi lagres i 2 registre GyroX = (Wire.read () << 8 | Wire.read ()) / 131.0; // For et område på 250 grader/ s må vi først dele råverdien med 131,0, i henhold til databladet GyroY = (Wire.read () << 8 | Wire.read ())/ 131.0; GyroZ = (Wire.read () << 8 | Wire.read ()) / 131.0; // Korriger utdataene med de beregnede feilverdiene GyroX = GyroX + 0,56; // GyroErrorX ~ (-0.56) GyroY = GyroY - 2; // GyroErrorY ~ (2) GyroZ = GyroZ + 0,79; // GyroErrorZ ~ (-0.8) // For øyeblikket er råverdiene i grader per sekunder, deg/s, så vi må multiplisere med sendonds (s) for å få vinkelen i grader gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg gyroAngleY = gyroAngleY + GyroY * elapsedTime; yaw = yaw + GyroZ * elapsedTime; // Komplementær filter - kombinere akseleromter og gyrovinkelverdierull = 0,96 * gyroAngleX + 0,04 * accAngleX; tonehøyde = 0,96 * gyroAngleY + 0,04 * accAngleY; // Skriv ut verdiene på den serielle skjermen Serial.print (roll); Serial.print ("/"); Serial.print (tonehøyde); Serial.print ("/"); Serial.println (yaw); } void calculate_IMU_error () {// Vi kan kalle denne funksjonen i oppsettseksjonen for å beregne akselerometer og gyrodatafeil. Herfra vil vi få feilverdiene som brukes i ligningene ovenfor skrevet ut på Serial Monitor. // Vær oppmerksom på at vi bør plassere IMU flat for å få de riktige verdiene, slik at vi deretter kan de riktige verdiene // Les akselerometerverdier 200 ganger mens (c <200) {Wire.beginTransmission (MPU); Wire.write (0x3B); Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Sum alle avlesninger AccErrorX = AccErrorX + ((atan ((AccY) / sqrt (pow ((AccX), 2) + pow ((AccZ), 2))) * 180 / PI)); AccErrorY = AccErrorY + ((atan (-1 * (AccX) / sqrt (pow ((AccY), 2) + pow ((AccZ), 2))) * 180 / PI)); c ++; } // Del summen med 200 for å få feilverdien AccErrorX = AccErrorX /200; AccErrorY = AccErrorY / 200; c = 0; // Les gyroverdier 200 ganger mens (c <200) {Wire.beginTransmission (MPU); Wire.write (0x43); Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); GyroX = Wire.read () << 8 | Wire.read (); GyroY = Wire.read () << 8 | Wire.read (); GyroZ = Wire.read () << 8 | Wire.read (); // Sum alle avlesninger GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c ++; } // Del summen med 200 for å få feilverdien GyroErrorX = GyroErrorX /200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Skriv ut feilverdiene på Serial Monitor Serial.print ("AccErrorX:"); Serial.println (AccErrorX); Serial.print ("AccErrorY:"); Serial.println (AccErrorY); Serial.print ("GyroErrorX:"); Serial.println (GyroErrorX); Serial.print ("GyroErrorY:"); Serial.println (GyroErrorY); Serial.print ("GyroErrorZ:"); Serial.println (GyroErrorZ); } ------------------------------------------------- ---------------------------------------------- Resultater:-X = Y = Z = ---------------------------------------------------- ----------------------------------------------- Viktig notat: -----------------

I sløyfedelen starter vi med å lese akselerometerdataene. Dataene for hver akse er lagret i 2 byte eller registre, og vi kan se adressene til disse registrene fra databladet til sensoren.

For å lese dem alle starter vi med det første registeret, og ved å bruke requiestFrom () -funksjonen ber vi om å lese alle 6 registrene for X-, Y- og Z -aksene. Deretter leser vi dataene fra hvert register, og fordi utgangene kompletterer to, kombinerer vi dem på riktig måte for å få de riktige verdiene.

Trinn 5: Forstå tiltningsvinkelen

Akselerometer

Jordens tyngdekraft er en konstant akselerasjon der kraften alltid peker ned til sentrum av jorden.

Når akselerometeret er parallelt med tyngdekraften, vil den målte akselerasjonen være 1G, når akselerometeret er vinkelrett på tyngdekraften, vil det måle 0G.

Tiltvinkel kan beregnes ut fra den målte akselerasjonen ved å bruke denne ligningen:

θ = sin-1 (målt akselerasjon / tyngdekraftsakselerasjon)

GyroGyro (aka rate sensor) brukes til å måle vinkelhastigheten (ω).

For å få tiltvinkelen til en robot, må vi integrere dataene fra gyroen som vist i ligningen nedenfor:

ω = dθ / dt, θ = ∫ ω dt

Gyro og akselerometer sensorfusjon Etter å ha studert egenskapene til både gyro og akselerometer, vet vi at de har sine egne styrker og svakheter. Den beregnede tiltvinkelen fra akselerometerdataene har langsom responstid, mens den integrerte vippevinkelen fra gyrodataene blir utsatt for drift over en periode. Med andre ord kan vi si at akselerometerdataene er nyttige på lang sikt mens gyrodataene er nyttige på kort sikt.

Lenke for bedre forståelse: Klikk her

Anbefalt: