Innehållsförteckning:

MPU 6050 Gyro, accelerometerkommunikation med Arduino (Atmega328p): 5 steg
MPU 6050 Gyro, accelerometerkommunikation med Arduino (Atmega328p): 5 steg

Video: MPU 6050 Gyro, accelerometerkommunikation med Arduino (Atmega328p): 5 steg

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

MPU6050 IMU har både 3-axlig accelerometer och 3-axligt gyroskop integrerat på ett enda chip.

Gyroskopet mäter rotationshastigheten eller förändringshastigheten för vinkelpositionen över tiden, längs X-, Y- och Z -axeln.

Gyroskopets utgångar är i grader per sekund, så för att få vinkelläget behöver vi bara integrera vinkelhastigheten.

Å andra sidan mäter MPU6050 -accelerometern acceleration genom att mäta gravitationell acceleration längs de 3 axlarna och med hjälp av lite trigonometri -matematik kan vi beräkna vinkeln vid vilken sensorn är placerad. Så om vi smälter ihop eller kombinerar accelerometer- och gyroskopdata kan vi få mycket exakt information om sensorriktningen.

3-axligt gyroskop MPU-6050 består av ett 3-axligt gyroskop som kan detektera rotationshastigheten längs x-, y-, z-axeln med mikroelektromekanisk systemteknik (MEMS). När sensorn roteras längs någon axel produceras en vibration på grund av Coriolis-effekten som detekteras av MEMS. 16-bitars ADC används för att digitalisera spänning för att sampla varje axel. +/- 250, +/- 500, +/- 1000, +/- 2000 är hela skalningsområdet för utdata. Vinkelhastighet mäts längs varje axel i grad per sekund enhet.

Användbar länk: …………….

Arduino Board:. ……….

MPU6050 IMU ……………

Steg 1: MPU-6050-modul

MPU-6050-modul
MPU-6050-modul

MPU-6050-modulen har 8 stift,

INT: Avbryt digital utgångsstift.

AD0: I2C Slave Address LSB pin. Detta är enhetens 0: e bit i 7-bitars slavadress. Om den är ansluten till VCC läses den som logisk en och slavadressändringar.

XCL: Auxiliary Serial Clock pin. Denna pin används för att ansluta andra I2C-gränssnittsaktiverade sensorer SCL-pin till MPU-6050.

XDA: Auxiliary Serial Data pin. Denna pin används för att ansluta andra I2C-gränssnittsaktiverade sensorer SDA-pin till MPU-6050.

SCL: Seriell klockstift. Anslut denna stift till mikrokontroller SCL -stift. SDA: Serial Data pin. Anslut denna stift till mikrokontroller SDA -stift.

GND: Markstift. Anslut denna stift till jordanslutning.

VCC: Strömförsörjningsstift. Anslut denna stift till +5V DC matning. MPU-6050-modulen har slavadress (när AD0 = 0, det vill säga den inte är ansluten till Vcc) som, Slavskrivningsadress (SLA+W): 0xD0

Slavläsadress (SLA+R): 0xD1

Steg 2: Beräkningar

Beräkningar
Beräkningar

Gyroskop- och accelerometermätardata för MPU6050-modulen består av 16-bitars rådata i 2: s komplementform.

Temperaturgivardata för MPU6050-modulen består av 16-bitars data (inte i 2: s komplementform).

Antag nu att vi har valt,

  • - Accelerometer fullt skalaintervall på +/- 2g med känslighetsskalefaktor på 16, 384 LSB (antal)/g.
  • - Gyroskop fullt skalaintervall på +/- 250 °/s med känslighetsskalefaktor på 131 LSB (antal)/°/s. sedan,

För att få sensordata måste vi först utföra 2: s komplement på sensordata från Accelerometer och gyroskop. Efter att ha fått sensordata kan vi beräkna acceleration och vinkelhastighet genom att dela sensordata med deras känslighetsskalfaktor enligt följande-

Accelerometervärden i g (g kraft)

  • Acceleration längs X -axeln = (Accelerometer X -axel rådata/16384) g.
  • Acceleration längs Y -axeln = (Accelerometer Y -axel rådata/16384) g.
  • Acceleration längs Z -axeln = (Accelerometer Z -axel rådata/16384) g.

Gyroskopvärden i °/s (grad per sekund)

  • Vinkelhastighet längs X -axeln = (Gyroskop X -axel rådata/131) °/s.
  • Vinkelhastighet längs Y -axeln = (Gyroskop Y -axel rådata/131) °/s.
  • Vinkelhastighet längs Z -axeln = (Gyroskop Z -axel rådata/131) °/s.

Temperaturvärde i °/c (grad per Celsius)

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

Till exempel, Antag att efter 2’komplement får vi accelerometer X -axlar råvärde = +15454

Då Ax = +15454/16384 = 0,94 g.

Mer,

Så vi vet att vi kör med en känslighet på +/- 2G och +/- 250deg/s men hur överensstämmer våra värden med dessa accelerationer/vinklar.

Dessa är båda raka linjediagram och vi kan räkna ut dem att för 1G kommer vi att läsa 16384 och för 1degree/sec kommer vi att läsa 131.07 (Även om.07 kommer att bli ignorera på grund av binär) har dessa värden bara räknats ut genom att rita raklinjediagram med 2G vid 32767 och -2G vid -32768 och 250/-250 vid samma värden.

Så nu vet vi våra känslighetsvärden (16384 och 131.07) vi behöver bara minus förskjutningarna från våra värden och sedan dividera med känsligheten.

Dessa kommer att fungera bra för X- och Y -värdena men eftersom Z registrerades vid 1G och inte 0 måste vi minus 1G (16384) innan vi dividerar med vår känslighet.

Steg 3: MPU6050-Atmega328p-anslutningar

MPU6050-Atmega328p-anslutningar
MPU6050-Atmega328p-anslutningar
MPU6050-Atmega328p-anslutningar
MPU6050-Atmega328p-anslutningar
MPU6050-Atmega328p-anslutningar
MPU6050-Atmega328p-anslutningar

Anslut bara allt enligt diagrammet …

Anslutningarna ges enligt följande:-

MPU6050 Arduino Nano

VCC 5v ut stift

GND Jordstift

SDA A4 -stift // seriell data

SCL A5 -stift // seriell klocka

Beräkning av tonhöjd och rulle: Rulla är rotationen runt x-axeln och tonhöjd är rotationen längs y-axeln.

Resultatet är i radianer. (konvertera till grader genom att multiplicera med 180 och dividera med pi)

Steg 4: Koder och förklaringar

Koder och förklaringar
Koder och förklaringar

/*

Arduino och MPU6050 Accelerometer och Gyroscope Sensor Tutorial av Dejan, https://howtomechatronics.com */#include const int MPU = 0x68; // MPU6050 I2C adress 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 (); // Initiera kommunikation Wire.beginTransmission (MPU); // Starta kommunikation med MPU6050 // MPU = 0x68 Wire.write (0x6B); // Prata med registret 6B Wire.write (0x00); // Gör återställning - placera en 0 i 6B -registret Wire.endTransmission (true); // avsluta överföringen/* // Configure Accelerometer Sensitivity - Full Scale Range (standard +/- 2g) Wire.beginTransmission (MPU); Wire.write (0x1C); // Prata med ACCEL_CONFIG -registret (1C hex) Wire.write (0x10); // Ställ in registerbitarna som 00010000 (+/- 8g full skala) Wire.endTransmission (true); // Configure Gyro Sensitivity - Full Scale Range (standard +/- 250deg/s) Wire.beginTransmission (MPU); Wire.write (0x1B); // Prata med GYRO_CONFIG -registret (1B hex) Wire.write (0x10); // Ställ in registerbitarna som 00010000 (1000deg/s full skala) Wire.endTransmission (true); fördröjning (20); */ // Ring den här funktionen om du behöver hämta IMU -felvärdena för din modul calc_IMU_error (); fördröjning (20); } void loop () {// === Läs acceleromter data === // Wire.beginTransmission (MPU); Wire.write (0x3B); // Börja med register 0x3B (ACCEL_XOUT_H) Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); // Läs totalt 6 register, varje axelvärde lagras i 2 register // För ett intervall på +-2g måste vi dela råvärdena med 16384, enligt databladet AccX = (Wire.read () << 8 | Wire.read ()) / 16384.0; // X-axelvärde AccY = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Y-axelvärde AccZ = (Wire.read () << 8 | Wire.read ()) / 16384.0; // Z -axelvärde // Beräkning av rulle och tonhöjd från accelerometerdata accAngleX = (atan (AccY / sqrt (pow (AccX, 2) + pow (AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~ (0.58) Se den anpassade funktionen calculate_IMU_error () för mer information accAngleY = (atan (-1 * AccX / sqrt (pow (AccY, 2) + pow (AccZ, 2))) * 180 / PI) + 1,58; // AccErrorY ~ (-1.58) // === Läs gyroskopdata === // previousTime = currentTime; // Tidigare tid lagras före den aktuella tiden läs aktuellTime = millis (); // Aktuell tid aktuell tid läst elapsedTime = (currentTime - previousTime) / 1000; // Dela med 1000 för att få sekunder Wire.beginTransmission (MPU); Wire.write (0x43); // Gyrodata registrerar först adressen 0x43 Wire.endTransmission (false); Wire.requestFrom (MPU, 6, true); // Läs totalt 4 register, varje axelvärde lagras i 2 register GyroX = (Wire.read () << 8 | Wire.read ()) / 131.0; // För ett intervall på 250 grader/ s måste vi först dela råvärdet med 131,0, enligt databladet GyroY = (Wire.read () << 8 | Wire.read ())/ 131,0; GyroZ = (Wire.read () << 8 | Wire.read ()) / 131.0; // Korrigera utmatningarna med de beräknade felvärdena GyroX = GyroX + 0,56; // GyroErrorX ~ (-0,56) GyroY = GyroY - 2; // GyroErrorY ~ (2) GyroZ = GyroZ + 0,79; // GyroErrorZ ~ (-0.8) // För närvarande är råvärdena i grader per sekunder, deg/s, så vi måste multiplicera med sendonds (s) för att få vinkeln i grader gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg gyroAngleY = gyroAngleY + GyroY * elapsedTime; yaw = yaw + GyroZ * elapsedTime; // Kompletterande filter - kombinera acceleromter och gyrovinkelvärden rulle = 0,96 * gyroAngleX + 0,04 * accAngleX; tonhöjd = 0,96 * gyroAngleY + 0,04 * accAngleY; // Skriv ut värdena på seriell bildskärm Serial.print (rulle); Serial.print ("/"); Serial.print (tonhöjd); Serial.print ("/"); Serial.println (yaw); } void calculate_IMU_error () {// Vi kan anropa denna funktion i installationsdelen för att beräkna accelerometer- och gyrodatafelet. Härifrån kommer vi att få de felvärden som används i ovanstående ekvationer tryckta på seriemonitorn. // Observera att vi bör placera IMU platt för att få rätt värden, så att vi sedan kan rätt värden // Läs accelerometervärden 200 gånger medan (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; // Summa alla avläsningar 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 ++; } // Dela summan med 200 för att få felvärdet AccErrorX = AccErrorX /200; AccErrorY = AccErrorY / 200; c = 0; // Läs gyrovärden 200 gånger medan (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 (); // Summa alla avläsningar GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c ++; } // Dela summan med 200 för att få felvärdet GyroErrorX = GyroErrorX /200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Skriv ut felvärdena 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); } ------------------------------------------------- ---------------------------------------------- Resultat:-X = Y = Z = ----------------------------------------------------- ----------------------------------------------- Viktig notering: -----------------

I loop -sektionen börjar vi med att läsa accelerometerdata. Data för varje axel lagras i 2 byte eller register och vi kan se adresserna till dessa register från sensorns datablad.

För att kunna läsa dem alla börjar vi med det första registret och med funktionen requiestFrom () begär vi att läsa alla 6 registren för X-, Y- och Z -axlarna. Sedan läser vi data från varje register, och eftersom utgångarna kompletterar två, kombinerar vi dem på lämpligt sätt för att få rätt värden.

Steg 5: Förstå lutningsvinkel

Accelerometer

Jordens tyngdkraft är en konstant acceleration där kraften alltid pekar ner till jordens centrum.

När accelerometern är parallell med gravitationen kommer den uppmätta accelerationen att vara 1G, när accelerometern är vinkelrät mot gravitationen mäter den 0G.

Lutningsvinkel kan beräknas från den uppmätta accelerationen med hjälp av denna ekvation:

θ = sin-1 (uppmätt acceleration / tyngdacceleration)

GyroGyro (aka hastighetssensor) används för att mäta vinkelhastigheten (ω).

För att få en robotens lutningsvinkel måste vi integrera data från gyro som visas i ekvationen nedan:

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

Gyro och accelerometer sensorfusion Efter att ha studerat egenskaperna hos både gyro och accelerometer vet vi att de har sina egna styrkor och svagheter. Den beräknade lutningsvinkeln från accelerometerdata har långsam responstid, medan den integrerade lutningsvinkeln från gyrodata utsätts för drift över en tidsperiod. Med andra ord kan vi säga att accelerometerdatan är användbar på lång sikt medan gyrodata är användbar på kort sikt.

Länk för bättre förståelse: Klicka här

Rekommenderad: