Satura rādītājs:

MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p): 5 soļi
MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p): 5 soļi

Video: MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p): 5 soļi

Video: MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p): 5 soļi
Video: Гироскоп с акселерометром на Arduino 2024, Jūlijs
Anonim
MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p)
MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p)
MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p)
MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p)
MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p)
MPU 6050 žiroskops, akselerometra sakari ar Arduino (Atmega328p)

MPU6050 IMU ir gan 3 asu akselerometrs, gan 3 asu žiroskops, kas integrēts vienā mikroshēmā.

Žiroskops mēra rotācijas ātrumu vai leņķiskā stāvokļa maiņas ātrumu laika gaitā gar X, Y un Z asi.

Žiroskopa izejas ir grādos sekundē, tāpēc, lai iegūtu leņķisko stāvokli, mums vienkārši jāintegrē leņķiskais ātrums.

No otras puses, akselerometrs MPU6050 mēra paātrinājumu, mērot gravitācijas paātrinājumu pa 3 asīm, un, izmantojot kādu trigonometrijas matemātiku, mēs varam aprēķināt leņķi, kādā sensors ir novietots. Tātad, ja mēs sakausējam vai apvienojam akselerometra un žiroskopa datus, mēs varam iegūt ļoti precīzu informāciju par sensora orientāciju.

3 asu žiroskops MPU-6050 sastāv no 3 asu žiroskopa, kas ar mikroelektromehāniskās sistēmas tehnoloģiju (MEMS) var noteikt rotācijas ātrumu pa x, y, z asi. Pagriežot sensoru pa jebkuru asi, Koriolisa efekta dēļ tiek radīta vibrācija, ko nosaka MEMS. 16 bitu ADC tiek izmantots, lai digitalizētu spriegumu katras ass paraugam. +/- 250, +/- 500, +/- 1000, +/- 2000 ir pilns skalas diapazons. Leņķa ātrumu mēra pa katru asi grādos sekundē.

Noderīga saite: …………….

Arduino padome: …………….

MPU6050 IMU ……………

1. darbība: MPU-6050 modulis

MPU-6050 modulis
MPU-6050 modulis

MPU-6050 modulim ir 8 tapas,

INT: pārtrauciet digitālās izvades tapu.

AD0: I2C vergu adreses LSB tapa. Šis ir 0. bits ierīces 7 bitu vergu adresē. Ja tas ir savienots ar VCC, tas tiek nolasīts kā loģisks un vergu adrese mainās.

XCL: seriālā pulksteņa papildu tapa. Šo tapu izmanto, lai savienotu citus I2C saskarnes sensorus SCL tapu ar MPU-6050.

XDA: papildu seriālo datu tapa. Šo tapu izmanto, lai pievienotu citus I2C saskarnes sensorus SDA tapu MPU-6050.

SCL: sērijas pulksteņa tapa. Pievienojiet šo tapu mikrokontrolleru SCL tapai. SDA: Sērijas datu tapa. Pievienojiet šo tapu mikrokontrolleru SDA tapai.

GND: Zemes tapa. Pievienojiet šo tapu zemējuma savienojumam.

VCC: strāvas padeves tapa. Pievienojiet šo tapu +5V līdzstrāvas padevei. MPU-6050 modulim ir vergu adrese (ja AD0 = 0, t.i., tas nav savienots ar Vcc) kā, Vergu rakstīšanas adrese (SLA+W): 0xD0

Vergu lasīšanas adrese (SLA+R): 0xD1

2. solis: Aprēķini

Aprēķini
Aprēķini

MPU6050 moduļa žiroskopa un akselerometra sensoru dati sastāv no 16 bitu neapstrādātiem datiem 2 papildinājuma formā.

MPU6050 moduļa temperatūras sensora dati sastāv no 16 bitu datiem (nevis 2 papildinājuma formā).

Tagad pieņemsim, ka esam izvēlējušies,

  • - Akselerometra pilna skalas diapazons +/- 2 g ar jutības skalas koeficientu 16, 384 LSB (skaits)/g.
  • - Žiroskopa pilna mēroga diapazons +/- 250 °/s ar jutīguma skalas koeficientu 131 LSB (skaits)/°/s. tad,

Lai iegūtu sensora neapstrādātus datus, mums vispirms jāveic 2 papildinājums akselerometra un žiroskopa sensoru datiem. Pēc sensora neapstrādātu datu iegūšanas mēs varam aprēķināt paātrinājumu un leņķisko ātrumu, dalot sensora neapstrādātos datus ar to jutības skalas koeficientu šādi-

Akselerometra vērtības g (g spēks)

  • Paātrinājums gar X asi = (akselerometra X ass izejas dati/16384) g.
  • Paātrinājums gar Y asi = (akselerometra Y ass izejas dati/16384) g.
  • Paātrinājums gar Z asi = (akselerometra Z ass izejas dati/16384) g.

Žiroskopa vērtības °/s (grāds sekundē)

  • Leņķiskais ātrums gar X asi = (žiroskopa X ass izejas dati/131) °/s.
  • Leņķiskais ātrums gar Y asi = (žiroskopa Y ass izejas dati/131) °/s.
  • Leņķiskais ātrums gar Z asi = (žiroskopa Z ass izejas dati/131) °/s.

Temperatūras vērtība °/c (grāds pēc Celsija)

Temperatūra grādos C = ((temperatūras sensora dati)/340 + 36,53) °/c.

Piemēram, Pieņemsim, ka pēc 2’papildinājuma mēs iegūstam akselerometra X asu neapstrādāto vērtību = +15454

Tad Ax = +15454/16384 = 0,94 g.

Vairāk,

Tātad mēs zinām, ka mēs strādājam ar +/- 2G un +/- 250deg/s jutību, bet kā mūsu vērtības atbilst šiem paātrinājumiem/leņķiem.

Šie abi ir taisnas līnijas grafiki, un no tiem mēs varam secināt, ka 1G gadījumā mēs lasīsim 16384 un 1 grādu/sek. - 131.07 (lai gan.07 ignorēs bināro datu dēļ), šīs vērtības tika izstrādātas, uzzīmējot taisnas līnijas grafiks ar 2G pie 32767 un -2G pie -32768 un 250/-250 ar tādām pašām vērtībām.

Tātad, tagad mēs zinām savas jutīguma vērtības (16384 un 131.07), mums vienkārši jāatņem mīnus no mūsu vērtībām un pēc tam jāvadās pēc jutīguma.

Tie darbosies labi attiecībā uz X un Y vērtībām, bet, tā kā Z tika reģistrēts 1G, nevis 0, mums būs jāsamazina 1G (16384), pirms mēs dalāmies ar jutību.

3. darbība: MPU6050-Atmega328p savienojumi

MPU6050-Atmega328p savienojumi
MPU6050-Atmega328p savienojumi
MPU6050-Atmega328p savienojumi
MPU6050-Atmega328p savienojumi
MPU6050-Atmega328p savienojumi
MPU6050-Atmega328p savienojumi

Vienkārši pievienojiet visu, kā norādīts diagrammā…

Savienojumi ir norādīti šādi:-

MPU6050 Arduino Nano

VCC 5v izejas tapa

GND Zemes tapa

SDA A4 tapa // sērijas dati

SCL A5 tapa // sērijas pulkstenis

Slīpuma un ruļļa aprēķins: rullis ir rotācija ap x asi un piķis ir rotācija pa y asi.

Rezultāts ir izteikts radiānos. (pārvērst grādos, reizinot ar 180 un dalot ar pi)

4. solis: kodi un skaidrojumi

Kodi un skaidrojumi
Kodi un skaidrojumi

/*

Arduino un MPU6050 akselerometra un žiroskopa sensora apmācība, ko izstrādājis Dejans, https://howtomechatronics.com */#include const int MPU = 0x68; // MPU6050 I2C adrešu pludiņš AccX, AccY, AccZ; pludiņš GyroX, GyroY, GyroZ; float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; pludiņa rullis, piķis, pagriešanās; float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ; pludiņš pagājušais laiks, pašreizējais laiks, iepriekšējais laiks; int c = 0; void setup () {Serial.begin (19200); Wire.begin (); // Inicializēt saziņu Wire.beginTransmission (MPU); // Sāciet saziņu ar MPU6050 // MPU = 0x68 Wire.write (0x6B); // Runājiet ar reģistru 6B Wire.write (0x00); // Veikt atiestatīšanu - ievietojiet 0 6B reģistrā Wire.endTransmission (true); // pārtraukt pārraidi/* // Konfigurēt akselerometra jutību - pilna mēroga diapazons (noklusējums +/- 2g) Wire.beginTransmission (MPU); Wire.write (0x1C); // Runājiet ar reģistru ACCEL_CONFIG (1C hex) Wire.write (0x10); // Iestatiet reģistra bitus kā 00010000 (+/- 8g pilna skalas diapazons) Wire.endTransmission (true); // Žiroskopu jutības konfigurēšana - pilna mēroga diapazons (noklusējums +/- 250deg/s) Wire.beginTransmission (MPU); Wire.write (0x1B); // Runājiet ar GYRO_CONFIG reģistru (1B hex) Wire.write (0x10); // Iestatiet reģistra bitus kā 00010000 (1000deg/s pilnā mērogā) Wire.endTransmission (true); kavēšanās (20); */ // Izsauciet šo funkciju, ja jums jāiegūst IMU kļūdas vērtības jūsu modulim calc_IMU_error (); kavēšanās (20); } void loop () {// === Lasīt akselerometra datus === // Wire.beginTransmission (MPU); Wire.write (0x3B); // Sāciet ar reģistru 0x3B (ACCEL_XOUT_H) Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); // Kopā nolasīti 6 reģistri, katra ass vērtība tiek saglabāta 2 reģistros // Diapazonam +-2 g neapstrādātās vērtības jāsadala ar 16384, saskaņā ar datu lapu AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; // X ass vērtība AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Y ass vērtība AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Z ass vērtība // Roll un Pitch aprēķināšana no akselerometra datiem accAngleX = (atan (AccY / kv. (Pow (AccX, 2) + pow (AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~ (0.58) Lai iegūtu sīkāku informāciju, skatiet pielāgoto funkciju calc_IMU_error () accAngleY = (atan (-1 * AccX / sqrt (pow (AccY, 2) + pow (AccZ, 2))) * 180 / PI) + 1,58; // AccErrorY ~ (-1,58) // === Lasīt žiroskopa datus === // previousTime = currentTime; // Iepriekšējais laiks tiek saglabāts pirms faktiskā nolasīšanas laika currentTime = millis (); // Pašreizējais laiks faktiskais nolasītais laiks pagājušais laiks = (pašreizējais laiks - iepriekšējais laiks) / 1000; // Sadaliet ar 1000, lai iegūtu sekundes Wire.beginTransmission (MPU); Wire.write (0x43); // Žiroskopu datu pirmā reģistra adrese 0x43 Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); // Kopā nolasīti 4 reģistri, katra ass vērtība tiek saglabāta 2 reģistros GyroX = (Wire.read () << 8 | Wire.read ()) / 131.0; // Attiecībā uz 250deg/ s diapazonu mums vispirms jādala neapstrādātā vērtība ar 131.0, saskaņā ar datu lapu GyroY = (Wire.read () << 8 | Wire.read ())/ 131.0; GyroZ = (Wire.read () << 8 | Wire.read ()) / 131.0; // Labojiet izejas ar aprēķinātajām kļūdu vērtībām GyroX = GyroX + 0,56; // GyroErrorX ~ (-0,56) GyroY = GyroY - 2; // GyroErrorY ~ (2) GyroZ = GyroZ + 0,79; // GyroErrorZ ~ (-0,8) // Pašlaik neapstrādātas vērtības ir grādos sekundēs, deg/s, tāpēc mums jāreizina ar sendondiem, lai iegūtu leņķi grādos gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg gyroAngleY = gyroAngleY + GyroY * pagājušais laiks; pagriešanās = pagriešanās + GyroZ * pagājušais laiks; // Papildu filtrs - apvienojiet akselerometra un žiroskopu leņķa vērtības roll = 0,96 * gyroAngleX + 0,04 * accAngleX; piķis = 0,96 * žiroskopsY + 0,04 * saskariY; // Drukājiet vērtības uz seriālā monitora Serial.print (roll); Serial.print ("/"); Sērijas nospiedums (piķis); Serial.print ("/"); Serial.println (pagrieziens); } void calc_IMU_error () {// Šo funkciju varam izsaukt iestatīšanas sadaļā, lai aprēķinātu akselerometra un žiroskopa datu kļūdu. No šejienes mēs iegūsim kļūdas vērtības, kas izmantotas iepriekš minētajos vienādojumos, kas izdrukāti uz sērijas monitora. // Ņemiet vērā, ka, lai iegūtu pareizās vērtības, IMU jānovieto līdzenumā, lai pēc tam varētu noteikt pareizās vērtības // 200 reizes izlasiet akselerometra vērtības, kamēr (c <200) {Wire.beginTransmission (MPU); Wire.write (0x3B); Wire.endTransmission (nepatiesa); 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; // Summēt visus rādījumus AccErrorX = AccErrorX + ((atan ((AccY) / sqrt (pow ((AccX), 2) + pow ((AccZ), 2))) * 180 / PI)); AccErrorY = AccErrorY + ((atan (-1 * (AccX) / kv. (Pow ((AccY), 2) + pow ((AccZ), 2))) * 180 / PI)); c ++; } // Sadaliet summu ar 200, lai iegūtu kļūdas vērtību AccErrorX = AccErrorX /200; AccErrorY = AccErrorY / 200; c = 0; // 200 reizes nolasiet žiroskopu vērtības, kamēr (c <200) {Wire.beginTransmission (MPU); Wire.write (0x43); Wire.endTransmission (nepatiesa); Wire.requestFrom (MPU, 6, true); GyroX = Wire.read () << 8 | Wire.read (); GyroY = Wire.read () << 8 | Wire.read (); GyroZ = Wire.read () << 8 | Wire.read (); // Summē visus rādījumus GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c ++; } // Sadaliet summu ar 200, lai iegūtu kļūdas vērtību GyroErrorX = GyroErrorX /200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Izdrukājiet kļūdu vērtības 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); } ------------------------------------------------- ---------------------------------------------- Rezultāti:-X = Y = Z = --------------------------------------------- ----------------------------------------------- Svarīga piezīme: -----------------

Cilpas sadaļā mēs sākam ar akselerometra datu nolasīšanu. Katras ass dati tiek glabāti 2 baitos vai reģistros, un mēs varam redzēt šo reģistru adreses no sensora datu lapas.

Lai tos visus izlasītu, mēs sākam ar pirmo reģistru, un, izmantojot funkciju RequestFrom (), mēs lūdzam nolasīt visus 6 X, Y un Z asu reģistrus. Tad mēs nolasām datus no katra reģistra un, tā kā izvadi papildina divus, mēs tos pareizi apvienojam, lai iegūtu pareizās vērtības.

5. darbība: izpratne par slīpuma leņķi

Akselerometrs

Zemes gravitācija ir pastāvīgs paātrinājums, kurā spēks vienmēr ir vērsts uz Zemes centru.

Kad akselerometrs ir paralēls gravitācijai, izmērītais paātrinājums būs 1G, un, ja akselerometrs ir perpendikulārs gravitācijai, tas mērīs 0G.

Slīpuma leņķi var aprēķināt no izmērītā paātrinājuma, izmantojot šo vienādojumu:

θ = sin-1 (izmērītais paātrinājums / gravitācijas paātrinājums)

GyroGyro (pazīstams arī kā ātruma sensors) tiek izmantots leņķiskā ātruma (ω) mērīšanai.

Lai iegūtu robota slīpuma leņķi, mums ir jāintegrē žiroskopa dati, kā parādīts zemāk esošajā vienādojumā:

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

Pēc žiroskopu un akselerometra raksturlielumu izpētīšanas mēs zinām, ka tiem ir savas stiprās un vājās puses. Akselerometra datiem aprēķinātajam slīpuma leņķim ir lēns reakcijas laiks, savukārt integrētajam žiroskopu slīpuma leņķim noteiktā laika periodā ir tendence mainīties. Citiem vārdiem sakot, mēs varam teikt, ka akselerometra dati ir noderīgi ilgtermiņā, bet žiroskopu dati ir noderīgi īstermiņā.

Saite labākai izpratnei: noklikšķiniet šeit

Ieteicams: