Turinys:

MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“): 5 žingsniai
MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“): 5 žingsniai

Video: MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“): 5 žingsniai

Video: MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“): 5 žingsniai
Video: How to use MPU-6050 Accelerometer and Gyroscope with Arduino code 2024, Liepa
Anonim
MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“)
MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“)
MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“)
MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“)
MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“)
MPU 6050 giroskopas, akselerometro ryšys su „Arduino“(„Atmega328p“)

MPU6050 IMU turi 3 ašių akselerometrą ir 3 ašių giroskopą, integruotą viename luste.

Giroskopas matuoja sukimosi greitį arba kampinės padėties kitimo greitį laikui bėgant išilgai X, Y ir Z ašių.

Giroskopo išėjimai yra laipsniais per sekundę, todėl norint gauti kampinę padėtį, mums tereikia integruoti kampinį greitį.

Kita vertus, MPU6050 akselerometras matuoja pagreitį matuojant gravitacinį pagreitį išilgai 3 ašių ir naudojant tam tikrą trigonometrijos matematiką galime apskaičiuoti kampą, kuriuo jutiklis yra. Taigi, jei sujungsime arba sujungsime akselerometro ir giroskopo duomenis, galime gauti labai tikslią informaciją apie jutiklio orientaciją.

3 ašių giroskopas MPU-6050 susideda iš 3 ašių giroskopo, kuris gali aptikti sukimosi greitį išilgai x, y, z ašies, naudojant mikroelektroninės mechaninės sistemos technologiją (MEMS). Kai jutiklis pasukamas išilgai bet kurios ašies, dėl Coriolis efekto, kurį aptinka MEMS, atsiranda vibracija. 16 bitų ADC naudojamas įtampai skaitmeninti, kad būtų galima imti kiekvieną ašį. +/- 250, +/- 500, +/- 1000, +/- 2000 yra visas išvesties diapazonas. Kampinis greitis matuojamas išilgai kiekvienos ašies laipsniu per sekundę.

Naudinga nuoroda: …………….

„Arduino“lenta: …………….

MPU6050 IMU ……………

1 žingsnis: MPU-6050 modulis

MPU-6050 modulis
MPU-6050 modulis

MPU-6050 modulis turi 8 kaiščius,

INT: nutraukite skaitmeninio išvesties kaištį.

AD0: I2C pavaldinio adreso LSB kaištis. Tai yra 0-asis bitas įrenginio 7 bitų pavaldžiame adrese. Jei prijungtas prie VCC, jis skaitomas kaip loginis ir keičiasi vergo adresas.

XCL: pagalbinio nuoseklaus laikrodžio kaištis. Šis kaištis naudojamas prijungti kitus I2C sąsają įgalinančius jutiklius SCL kaiščius prie MPU-6050.

XDA: pagalbiniai nuoseklieji duomenų kaiščiai. Šis kaištis naudojamas prijungti kitus I2C sąsają įgalinančius jutiklius SDA kaiščius prie MPU-6050.

SCL: nuoseklaus laikrodžio kaištis. Prijunkite šį kaištį prie mikrovaldiklių SCL kaiščio. SDA: nuoseklių duomenų kaištis. Prijunkite šį kaištį prie mikrovaldiklių SDA kaiščio.

GND: įžeminimo kaištis. Prijunkite šį kaištį prie įžeminimo jungties.

VCC: maitinimo kaištis. Prijunkite šį kaištį prie +5 V nuolatinės srovės maitinimo šaltinio. MPU-6050 modulis turi pavaldinį adresą (kai AD0 = 0, t. Y. Jis nėra prijungtas prie Vcc) kaip, Slave Rašymo adresas (SLA+W): 0xD0

Slave Skaitymo adresas (SLA+R): 0xD1

2 žingsnis: Skaičiavimai

Skaičiavimai
Skaičiavimai

„MPU6050“modulio giroskopo ir akselerometro jutiklių duomenis sudaro 16 bitų neapdoroti 2 papildymo formos duomenys.

MPU6050 modulio temperatūros jutiklių duomenis sudaro 16 bitų duomenys (ne 2 papildymo forma).

Dabar tarkime, kad pasirinkome,

  • - Visas akselerometro skalės diapazonas +/- 2 g, o jautrumo skalės koeficientas 16, 384 LSB (skaičius)/g.
  • - Visas giroskopo diapazonas +/- 250 °/s, o jautrumo skalės koeficientas 131 LSB (skaičius)/°/s. tada,

Norėdami gauti neapdorotus jutiklio duomenis, pirmiausia turime atlikti 2 papildymą akselerometro ir giroskopo jutiklių duomenims. Gavę neapdorotus jutiklio duomenis, galime apskaičiuoti pagreitį ir kampinį greitį, padaliję neapdorotus jutiklio duomenis su jų jautrumo skalės koeficientu taip:

Akselerometro vertės g (g jėga)

  • Pagreitis išilgai X ašies = (Akselerometro X ašies neapdoroti duomenys/16384) g.
  • Pagreitis išilgai Y ašies = (Akselerometro Y ašies neapdoroti duomenys/16384) g.
  • Pagreitis išilgai Z ašies = (Akselerometro Z ašies neapdoroti duomenys/16384) g.

Giroskopo vertės °/s (laipsnis per sekundę)

  • Kampinis greitis išilgai X ašies = (giroskopo X ašies neapdoroti duomenys/131) °/s.
  • Kampinis greitis išilgai Y ašies = (Giroskopo Y ašies neapdoroti duomenys/131) °/s.
  • Kampinis greitis išilgai Z ašies = (Giroskopo Z ašies neapdoroti duomenys/131) °/s.

Temperatūros vertė °/c (laipsnis pagal Celsijų)

Temperatūra laipsniais C = ((temperatūros jutiklio duomenys)/340 + 36,53) °/c.

Pavyzdžiui, Tarkime, po 2’komplemento gauname akselerometro X ašių neapdorotą vertę = +15454

Tada ašis = +15454/16384 = 0,94 g.

Daugiau,

Taigi mes žinome, kad veikiame +/- 2G ir +/- 250deg/s jautrumu, bet kaip mūsų vertės atitinka tuos pagreičius/kampus.

Tai abu tiesiosios diagramos, ir iš jų galime išsiaiškinti, kad 1G atveju mes skaitome 16384, o 1 laipsnį per sekundę - 131.07 (nors.07 bus ignoruojamas dėl dvejetainės), šios vertės buvo tiesiog sukurtos nubrėžus tiesi grafika su 2G esant 32767 ir -2G esant -32768 ir 250/-250 tomis pačiomis vertėmis.

Taigi dabar mes žinome savo jautrumo vertes (16384 ir 131.07), mums tereikia atimti savo vertybių poslinkius ir tada atsižvelgti į jautrumą.

Tai puikiai tinka X ir Y reikšmėms, tačiau kadangi Z buvo užregistruotas esant 1G, o ne 0, prieš padalindami pagal savo jautrumą, turėsime atimti 1G (16384).

3 žingsnis: MPU6050-Atmega328p jungtys

MPU6050-Atmega328p jungtys
MPU6050-Atmega328p jungtys
MPU6050-Atmega328p jungtys
MPU6050-Atmega328p jungtys
MPU6050-Atmega328p jungtys
MPU6050-Atmega328p jungtys

Tiesiog prijunkite viską, kaip parodyta diagramoje…

Sujungimai pateikiami taip:-

MPU6050 „Arduino Nano“

VCC 5v išvesties kaištis

GND įžeminimo kaištis

SDA A4 kaištis // serijiniai duomenys

SCL A5 kaištis // serijinis laikrodis

Žingsnio ir ritinio skaičiavimas: ritinys yra sukimasis aplink x ašį, o žingsnis-sukimasis išilgai y ašies.

Rezultatas yra radianais. (konvertuoti į laipsnius padauginus iš 180 ir padalijus iš pi)

4 žingsnis: kodai ir paaiškinimai

Kodai ir paaiškinimai
Kodai ir paaiškinimai

/*

„Arduino“ir „MPU6050“akselerometro ir giroskopo jutiklio pamoka, sukurta Dejan, https://howtomechatronics.com */#include const int MPU = 0x68; // MPU6050 I2C adreso plūdė AccX, AccY, AccZ; float GyroX, GyroY, GyroZ; float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; plūdės ritinys, žingsnis, posūkis; float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ; float elapsedTime, currentTime, previousTime; int c = 0; void setup () {Serial.begin (19200); Wire.begin (); // Inicijuoti ryšį Wire.beginTransmission (MPU); // Pradėti ryšį su MPU6050 // MPU = 0x68 Wire.write (0x6B); // Pasikalbėkite su registru 6B Wire.write (0x00); // Atkurti - įdėti 0 į 6B registrą Wire.endTransmission (true); // baigti perdavimą/* // Konfigūruoti akselerometro jautrumą - visas skalės diapazonas (numatytasis +/- 2g) Wire.beginTransmission (MPU); Wire.write (0x1C); // Kalbėkitės su ACCEL_CONFIG registru (1C šešiakampis) Wire.write (0x10); // Nustatykite registro bitus kaip 00010000 (+/- 8g viso diapazono diapazonas) Wire.endTransmission (true); // Giroskopo jautrumo konfigūravimas - visas skalės diapazonas (numatytasis +/- 250deg/s) Wire.beginTransmission (MPU); Wire.write (0x1B); // Kalbėkitės su GYRO_CONFIG registru (1B šešiakampis) Wire.write (0x10); // Nustatykite registro bitus kaip 00010000 (1000 deg/s visos skalės) Wire.endTransmission (true); vėlavimas (20); */ // Paskambinkite šiai funkcijai, jei jums reikia gauti IMU klaidos reikšmes jūsų moduliui calc_IMU_error (); vėlavimas (20); } void loop () {// === Skaityti pagreičio duomenų duomenis === // Wire.beginTransmission (MPU); Wire.write (0x3B); // Pradėkite nuo registro 0x3B (ACCEL_XOUT_H) Wire.endTransmission (false); Wire.requestFrom (MPU, 6, tiesa); // Iš viso perskaitykite 6 registrus, kiekvienos ašies reikšmė saugoma 2 registruose // Jei diapazonas yra +-2 g, mes turime padalinti neapdorotas vertes iš 16384 pagal duomenų lapą AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; // X ašies reikšmė AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Y ašies reikšmė AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Z ašies reikšmė // Ritinio ir žingsnio apskaičiavimas iš akselerometro duomenų accAngleX = (atan (AccY / kv. (Pow (AccX, 2) + pow (AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~ (0.58) Norėdami gauti daugiau informacijos, žr. Pasirinktinę funkciją calc_IMU_error () accAngleY = (atan (-1 * AccX / sqrt (pow (AccY, 2) + pow (AccZ, 2))) * 180 / PI) + 1,58; // AccErrorY ~ (-1,58) // === Skaityti giroskopo duomenis === // previousTime = currentTime; // Ankstesnis laikas saugomas prieš faktinį perskaitytą laiką currentTime = millis (); // Dabartinis laikas faktinis perskaitytas laikas praleistasTime = (currentTime - previousTime) / 1000; // Padalinkite iš 1000, kad gautumėte sekundes Wire.beginTransmission (MPU); Wire.write (0x43); // Giroskopo duomenų pirmojo registro adresas 0x43 Wire.endTransmission (false); Wire.requestFrom (MPU, 6, tiesa); // Iš viso perskaitykite 4 registrus, kiekvienos ašies reikšmė saugoma 2 registruose GyroX = (Wire.read () << 8 | Wire.read ()) / 131.0; // 250 laipsnių/ s diapazonui pirmiausia turime padalinti neapdorotą vertę iš 131.0, pagal duomenų lapą GyroY = (Wire.read () << 8 | Wire.read ())/ 131.0; GyroZ = (Wire.read () << 8 | Wire.read ()) / 131.0; // Ištaisykite išvadas apskaičiuotomis klaidų reikšmėmis GyroX = GyroX + 0,56; // GyroErrorX ~ (-0,56) GyroY = GyroY - 2; // GyroErrorY ~ (2) GyroZ = GyroZ + 0,79; // GyroErrorZ ~ (-0,8) // Šiuo metu neapdorotos vertės yra laipsniais per sekundę, deg/s, todėl turime padauginti iš sentimentų, kad gautume kampą laipsniais gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg gyroAngleY = gyroAngleY + GyroY * elapsedTime; pasukimas = pasukimas + GyroZ * eltęsęs laikas; // Papildomas filtras - sujunkite pagreičio ir giroskopo kampo reikšmes roll = 0,96 * gyroAngleX + 0,04 * accAngleX; žingsnis = 0,96 * giroskopasY + 0,04 * prisitaikymas; // Spausdinkite reikšmes serijiniame monitoriuje Serial.print (roll); Serial.print ("/"); Serijinis atspaudas (žingsnis); Serial.print ("/"); Serial.println (yaw); } void calc_IMU_error () {// Šią funkciją galime vadinti sąrankos skiltyje, kad apskaičiuotume akselerometro ir giroskopo duomenų klaidą. Iš čia gausime klaidų reikšmes, naudojamas pirmiau pateiktose lygtyse, išspausdintose serijos monitoriuje. // Atminkite, kad norėdami gauti tinkamas vertes, IMU turėtume pastatyti plokščią, kad galėtume tada gauti teisingas vertes // 200 kartų skaitykite akselerometro reikšmes, o (c <200) {Wire.beginTransmission (MPU); Wire.write (0x3B); Wire.endTransmission (false); Wire.requestFrom (MPU, 6, tiesa); AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Susumuoti visus rodmenis 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 ++; } // Padalinkite sumą iš 200, kad gautumėte klaidos vertę AccErrorX = AccErrorX /200; AccErrorY = AccErrorY / 200; c = 0; // 200 kartų skaitykite giroskopo reikšmes, kai (c <200) {Wire.beginTransmission (MPU); Wire.write (0x43); Wire.endTransmission (klaidinga); Wire.requestFrom (MPU, 6, tiesa); GyroX = Wire.read () << 8 | Wire.read (); GyroY = Wire.read () << 8 | Wire.read (); GyroZ = Wire.read () << 8 | Wire.read (); // Susumuoti visus rodmenis GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c ++; } // Padalinkite sumą iš 200, kad gautumėte klaidos vertę GyroErrorX = GyroErrorX /200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Spausdinkite klaidų reikšmes 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); } ------------------------------------------------- ---------------------------------------------- Rezultatai:-X = Y = Z = --------------------------------------------- ----------------------------------------------- Svarbi pastaba: -----------------

Ciklo skyriuje mes pradedame skaityti akselerometro duomenis. Kiekvienos ašies duomenys saugomi 2 baitais arba registrais, o šių registrų adresus matome iš jutiklio duomenų lapo.

Norėdami juos perskaityti, mes pradedame nuo pirmojo registro, o naudodami funkciją RequestFrom () prašome perskaityti visus 6 X, Y ir Z ašių registrus. Tada mes skaitome kiekvieno registro duomenis ir kadangi išėjimai papildo du, mes juos atitinkamai sujungiame, kad gautume teisingas vertes.

5 žingsnis: supraskite pakreipimo kampą

Akselerometras

Žemės trauka yra nuolatinis pagreitis, kai jėga visada nukreipta žemyn į Žemės centrą.

Kai akselerometras yra lygiagretus gravitacijai, išmatuotas pagreitis bus 1G, o akselerometras statmenas gravitacijai - 0G.

Pasvirimo kampą galima apskaičiuoti pagal išmatuotą pagreitį naudojant šią lygtį:

θ = sin-1 (išmatuotas pagreitis / gravitacijos pagreitis)

„GyroGyro“(dar žinomas kaip greičio jutiklis) naudojamas kampiniam greičiui (ω) matuoti.

Norėdami gauti roboto pasvirimo kampą, turime integruoti giroskopo duomenis, kaip parodyta žemiau esančioje lygtyje:

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

Ištyrus giroskopo ir akselerometro charakteristikas, žinome, kad jie turi savo stipriąsias ir silpnąsias puses. Akselerometro duomenų apskaičiuotas pasvirimo kampas turi lėtą atsako laiką, o integruotas giroskopo duomenų pasvirimo kampas per tam tikrą laiką gali nukrypti. Kitaip tariant, galime pasakyti, kad akselerometro duomenys yra naudingi ilgam laikui, o giroskopo duomenys yra naudingi trumpam laikui.

Nuoroda, skirta geriau suprasti: spustelėkite čia

Rekomenduojamas: