Sadržaj:
2025 Autor: John Day | [email protected]. Zadnja izmjena: 2025-01-13 06:57
MPU6050 IMU ima troosni akcelerometar i troosni žiroskop integrirani na jednom čipu.
Žiroskop mjeri brzinu rotacije ili brzinu promjene kutnog položaja tokom vremena, duž osi X, Y i Z.
Izlazi žiroskopa su u stupnjevima u sekundi, pa da bismo dobili kutni položaj samo moramo integrirati kutnu brzinu.
S druge strane, akcelerometar MPU6050 mjeri ubrzanje mjerenjem gravitacijskog ubrzanja duž 3 osi i pomoću neke matematike trigonometrije možemo izračunati kut pod kojim je senzor postavljen. Dakle, ako spojimo ili kombiniramo podatke akcelerometra i žiroskopa možemo dobiti vrlo točne podatke o orijentaciji senzora.
Žiroskop s tri osi MPU-6050 sastoji se od troosnog žiroskopa koji može detektirati brzinu rotacije duž osi x, y, z pomoću tehnologije mikro-mehaničkih sistema (MEMS). Kada se senzor rotira duž bilo koje osi, stvaraju se vibracije zbog Coriolisovog efekta koji detektira MEMS.16-bitni ADC koristi se za digitalizaciju napona za uzorkovanje svake osi. +/- 250, +/- 500, +/- 1000, +/- 2000 su puni raspon izlaznih vrijednosti. Kutna brzina se mjeri duž svake osi u stupnjevima po sekundi.
Korisna veza: …………….
Arduino ploča:. ……….
MPU6050 IMU ……………
Korak 1: Modul MPU-6050
Modul MPU-6050 ima 8 pinova,
INT: Prekini pin za digitalni izlaz.
AD0: I2C slave adresa LSB pin. Ovo je 0-ti bit u 7-bitnoj slave adresi uređaja. Ako je spojen na VCC, tada se čita kao logička i slave adresa.
XCL: pin pomoćnog serijskog sata. Ovaj pin se koristi za povezivanje drugih SCL pinova sa omogućenim I2C interfejsom na MPU-6050.
XDA: pin pomoćnih serijskih podataka. Ovaj pin se koristi za povezivanje drugih SDA pinova sa omogućenim I2C interfejsom na MPU-6050.
SCL: Pin za serijski sat. Priključite ovaj pin na SCL pin mikrokontrolera. SDA: Pin za serijske podatke. Priključite ovaj pin na SDA pin mikrokontrolera.
GND: Igla za uzemljenje. Spojite ovaj pin na uzemljenje.
VCC: Pin za napajanje. Priključite ovaj pin na +5V DC napajanje. Modul MPU-6050 ima Slave adresu (Kada je AD0 = 0, tj. Nije spojen na Vcc) kao, Adresa za pomoćno upisivanje (SLA+W): 0xD0
Adresa za pomoćno čitanje (SLA+R): 0xD1
Korak 2: Proračuni
Podaci senzora žiroskopa i akcelerometra MPU6050 modula sastoje se od 16-bitnih sirovih podataka u obliku komplementa 2.
Podaci senzora temperature MPU6050 modula sastoje se od 16-bitnih podataka (ne u obliku komplementa 2).
Pretpostavimo da smo odabrali,
- - Opseg skale akcelerometra od +/- 2g sa faktorom skale osjetljivosti 16, 384 LSB (broj)/g.
- - Puni raspon žiroskopa od +/- 250 °/s sa faktorom skale osjetljivosti 131 LSB (broj)/°/s. tada,
Da bismo dobili neobrađene podatke senzora, moramo prvo izvršiti komplement 2 na senzorskim podacima akcelerometra i žiroskopa. Nakon dobivanja neobrađenih podataka senzora možemo izračunati ubrzanje i kutnu brzinu dijeljenjem neobrađenih podataka senzora s njihovim faktorom ljestvice osjetljivosti na sljedeći način-
Vrijednosti akcelerometra u g (g sila)
- Ubrzanje duž osi X = (Sirovi podaci osi X akcelerometra sirovi podaci/16384) g.
- Ubrzanje po osi Y = (Sirovi podaci osi akcelerometra Y osi/16384) g.
- Ubrzanje duž osi Z = (Sirovi podaci osi akcelerometra Z osi/16384) g.
Vrijednosti žiroskopa u °/s (stepen u sekundi)
- Kutna brzina duž osi X = (Sirovi podaci osi X osi žiroskopa/131) °/s.
- Kutna brzina duž Y osi = (Sirovi podaci osi Y osi žiroskopa/131) °/s.
- Kutna brzina duž osi Z = (Sirovi podaci osi Z osi žiroskopa/131) °/s.
Temperaturna vrijednost u °/c (stepen po Celzijusu)
Temperatura u stupnjevima C = ((podaci senzora temperature)/340 + 36,53) °/c.
Na primjer, Pretpostavimo da nakon 2’komplementa dobijemo sirovu vrijednost osi akcelerometra X osi = +15454
Tada je Ax = +15454/16384 = 0.94 g.
Više,
Dakle, znamo da radimo na osjetljivosti od +/- 2G i +/- 250deg/s, ali kako naše vrijednosti odgovaraju tim ubrzanjima/uglovima.
Ovo su oboje ravni grafikoni i iz njih možemo zaključiti da ćemo za 1G čitati 16384, a za 1 stupanj/sek 131,07 (iako će se.07 zanemariti zbog binarnosti) ove vrijednosti su samo izrađene crtanjem ravni grafikon sa 2G na 32767 i -2G na -32768 i 250/-250 na istim vrijednostima.
Dakle, sada znamo naše vrijednosti osjetljivosti (16384 i 131,07), samo trebamo umanjiti odstupanja od naših vrijednosti, a zatim podijeliti prema osjetljivosti.
Oni će dobro funkcionirati za vrijednosti X i Y, ali kako je Z zabilježeno na 1G, a ne na 0, morat ćemo minus 1G (16384) prije nego što podijelimo s osjetljivošću.
Korak 3: MPU6050-Atmega328p veze
Samo povežite sve kako je prikazano na dijagramu…
Veze su date na sledeći način:-
MPU6050 Arduino Nano
VCC 5v izlazni pin
GND Uzemljenje
SDA A4 pin // serijski podaci
SCL A5 pin // serijski sat
Proračun nagiba i nagiba: Roll je rotacija oko osi x, a korak je rotacija duž osi y.
Rezultat je u radijanima. (konvertujte u stepene množenjem sa 180 i deljenjem sa pi)
Korak 4: Kodovi i objašnjenja
/*
Arduino i MPU6050 Akcelerometar i senzor žiroskopa senzor, Dejan, https://howtomechatronics.com */#include const int MPU = 0x68; // MPU6050 I2C adresa float AccX, AccY, AccZ; float 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; void setup () {Serial.begin (19200); Wire.begin (); // Pokretanje komunikacije Wire.beginTransmission (MPU); // započeti komunikaciju s MPU6050 // MPU = 0x68 Wire.write (0x6B); // Razgovarajte sa registrom 6B Wire.write (0x00); // Poništi - postavite 0 u 6B registar Wire.endTransmission (true); // prekid prijenosa/* // Konfiguriranje osjetljivosti akcelerometra - puni raspon opsega (zadano +/- 2g) Wire.beginTransmission (MPU); Wire.write (0x1C); // Razgovarajte sa ACCEL_CONFIG registrom (1C hex) Wire.write (0x10); // Postavite registrske bitove kao 00010000 (+/- 8g punog raspona) Wire.endTransmission (true); // Konfiguriranje osjetljivosti žiroskopa - cijeli raspon opsega (zadano +/- 250deg/s) Wire.beginTransmission (MPU); Wire.write (0x1B); // Razgovarajte s GYRO_CONFIG registrom (1B hex) Wire.write (0x10); // Postavite registrske bitove kao 00010000 (1000deg/s u punoj skali) Wire.endTransmission (true); kašnjenje (20); */ // Pozovite ovu funkciju ako trebate dobiti vrijednosti IMU greške za vaš modul calcule_IMU_error (); kašnjenje (20); } void loop () {// === Čitanje podataka akcelerometra === // Wire.beginTransmission (MPU); Wire.write (0x3B); // Počni s registrom 0x3B (ACCEL_XOUT_H) Wire.endTransmission (false); Wire.requestFrom (MPU, 6, tačno); // Pročitajte ukupno 6 registara, svaka vrijednost osi je pohranjena u 2 registra // Za raspon od +-2g, moramo podijeliti neobrađene vrijednosti na 16384, prema podatkovnom listu AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Vrijednost osi X AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Vrijednost osi Y AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Z -vrijednost osi // Izračunavanje pomaka i nagiba iz podataka akcelerometra accAngleX = (atan (AccY / sqrt (pow (AccX, 2) + pow (AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~ (0.58) Pogledajte prilagođenu funkciju calcule_IMU_error () za više detalja accAngleY = (atan (-1 * AccX / sqrt (pow (AccY, 2) + pow (AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~ (-1,58) // === Čitanje podataka žiroskopa === // previousTime = currentTime; // Prethodno vrijeme se pohranjuje prije stvarnog vremena čitanja currentTime = millis (); // Trenutno vrijeme pročitano vrijeme elapsedTime = (currentTime - previousTime) / 1000; // Podijelite s 1000 da biste dobili sekunde Wire.beginTransmission (MPU); Wire.write (0x43); // Adresa prvog registra žiroskopa 0x43 Wire.endTransmission (false); Wire.requestFrom (MPU, 6, tačno); // Čitanje ukupno 4 registra, svaka vrijednost osi pohranjena je u 2 registra GyroX = (Wire.read () << 8 | Wire.read ()) / 131.0; // Za raspon od 250deg/ s moramo prvo podijeliti sirovu vrijednost sa 131,0, prema tablici podataka GyroY = (Wire.read () << 8 | Wire.read ())/ 131.0; GyroZ = (Wire.read () << 8 | Wire.read ()) / 131.0; // Ispravimo izlaze s izračunatim vrijednostima greške GyroX = GyroX + 0,56; // GyroErrorX ~ (-0,56) GyroY = GyroY - 2; // GyroErrorY ~ (2) GyroZ = GyroZ + 0,79; // GyroErrorZ ~ (-0.8) // Trenutno su sirove vrijednosti u stupnjevima po sekundi, deg/s, pa moramo pomnožiti sa sendonds (s) da dobijemo kut u stupnjevima gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg gyroAngleY = gyroAngleY + GyroY * elapsedTime; yaw = yaw + GyroZ * elapsedTime; // Komplementarni filter - kombinirajte vrijednosti ubrzanja i žiro kuta roll = 0,96 * gyroAngleX + 0,04 * accAngleX; pitch = 0,96 * gyroAngleY + 0,04 * accAngleY; // Odštampajte vrijednosti na serijskom monitoru Serial.print (roll); Serial.print ("/"); Serial.print (pitch); Serial.print ("/"); Serial.println (zakretanje); } void Calculate_IMU_error () {// Ovu funkciju možemo nazvati u odjeljku za postavljanje radi izračunavanja akcelerometra i greške podataka žiroskopa. Odavde ćemo dobiti vrijednosti grešaka korištene u gornjim jednadžbama odštampanim na serijskom monitoru. // Imajte na umu da bismo trebali postaviti IMU ravno kako bismo dobili odgovarajuće vrijednosti, tako da tada možemo ispraviti vrijednosti // 200 puta očitati vrijednosti akcelerometra dok (c <200) {Wire.beginTransmission (MPU); Wire.write (0x3B); Wire.endTransmission (false); Wire.requestFrom (MPU, 6, tačno); AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Zbroji sva očitanja 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 ++; } // Podijelite zbir sa 200 da biste dobili vrijednost greške AccErrorX = AccErrorX /200; AccErrorY = AccErrorY / 200; c = 0; // 200 puta čitajte vrijednosti žiroskopa dok (c <200) {Wire.beginTransmission (MPU); Wire.write (0x43); Wire.endTransmission (false); Wire.requestFrom (MPU, 6, tačno); GyroX = Wire.read () << 8 | Wire.read (); GyroY = Wire.read () << 8 | Wire.read (); GyroZ = Wire.read () << 8 | Wire.read (); // Zbroji sva očitanja GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c ++; } // Podijelite zbir sa 200 da biste dobili vrijednost greške GyroErrorX = GyroErrorX /200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Ispisuje vrijednosti greške na 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); } ------------------------------------------------- ---------------------------------------------- Rezultati:-X = Y = Z = --------------------------------------------- ----------------------------------------------- Važna napomena: -----------------
U odjeljku petlje započinjemo čitanjem podataka akcelerometra. Podaci za svaku os pohranjeni su u 2 bajta ili registre, a adrese tih registara možemo vidjeti iz podatkovne tablice senzora.
Da bismo ih sve pročitali, počinjemo s prvim registrom, a pomoću funkcije requiestFrom () tražimo čitanje svih 6 registara za osi X, Y i Z. Zatim čitamo podatke iz svakog registra, a budući da se izlazi nadopunjuju, kombiniramo ih na odgovarajući način kako bismo dobili ispravne vrijednosti.
Korak 5: Razumijevanje kuta nagiba
Akcelerometar
Zemljina gravitacija je konstantno ubrzanje gdje je sila uvijek usmjerena prema središtu Zemlje.
Kad je akcelerometar paralelan s gravitacijom, izmjereno ubrzanje bit će 1G, kada je akcelerometar okomit na gravitaciju, mjerit će 0G.
Kut nagiba može se izračunati iz izmjerenog ubrzanja pomoću ove jednadžbe:
θ = sin-1 (izmjereno ubrzanje / ubrzanje gravitacije)
GyroGyro (zvani senzor brzine) koristi se za mjerenje kutne brzine (ω).
Da bismo dobili kut nagiba robota, moramo integrirati podatke iz žiroskopa kako je prikazano u donjoj jednadžbi:
ω = dθ / dt, θ = ∫ ω dt
Fuzija senzora žiroskopa i akcelerometraNakon proučavanja karakteristika žiroskopa i akcelerometra, znamo da oni imaju svoje snage i slabosti. Izračunati kut nagiba iz podataka akcelerometra ima sporo vrijeme odziva, dok je integrirani kut nagiba iz giroskopskih podataka podvrgnut pomaku u određenom vremenskom periodu. Drugim riječima, možemo reći da su podaci akcelerometra dugoročno korisni, dok su žiroskopi kratkoročni.
Link za bolje razumijevanje: kliknite ovdje