Spisu treści:

Żyroskop MPU 6050, komunikacja z akcelerometrem z Arduino (Atmega328p): 5 kroków
Żyroskop MPU 6050, komunikacja z akcelerometrem z Arduino (Atmega328p): 5 kroków

Wideo: Żyroskop MPU 6050, komunikacja z akcelerometrem z Arduino (Atmega328p): 5 kroków

Wideo: Żyroskop MPU 6050, komunikacja z akcelerometrem z Arduino (Atmega328p): 5 kroków
Wideo: Komunikacja między dwoma modułami Bluetooth HC-05 2024, Listopad
Anonim
MPU 6050 Żyroskop, akcelerometr Komunikacja z Arduino (Atmega328p)
MPU 6050 Żyroskop, akcelerometr Komunikacja z Arduino (Atmega328p)
MPU 6050 Żyroskop, akcelerometr Komunikacja z Arduino (Atmega328p)
MPU 6050 Żyroskop, akcelerometr Komunikacja z Arduino (Atmega328p)
MPU 6050 Żyroskop, akcelerometr Komunikacja z Arduino (Atmega328p)
MPU 6050 Żyroskop, akcelerometr Komunikacja z Arduino (Atmega328p)

MPU6050 IMU ma zarówno 3-osiowy akcelerometr, jak i 3-osiowy żyroskop zintegrowany na jednym chipie.

Żyroskop mierzy prędkość obrotową lub tempo zmian położenia kątowego w czasie wzdłuż osi X, Y i Z.

Dane wyjściowe żyroskopu są podawane w stopniach na sekundę, więc aby uzyskać pozycję kątową, wystarczy zintegrować prędkość kątową.

Z drugiej strony akcelerometr MPU6050 mierzy przyspieszenie, mierząc przyspieszenie grawitacyjne wzdłuż 3 osi i korzystając z matematyki trygonometrii, możemy obliczyć kąt, pod którym znajduje się czujnik. Tak więc, jeśli połączymy lub połączymy dane z akcelerometru i żyroskopu, możemy uzyskać bardzo dokładne informacje o orientacji czujnika.

3-osiowy żyroskop MPU-6050 składa się z 3-osiowego żyroskopu, który może wykrywać prędkość obrotową wzdłuż osi x, y, z za pomocą technologii mikroelektromechanicznej (MEMS). Gdy czujnik jest obracany wzdłuż dowolnej osi, powstają wibracje z powodu efektu Coriolisa, który jest wykrywany przez MEMS. 16-bitowy przetwornik ADC służy do digitalizacji napięcia w celu spróbkowania każdej osi. +/- 250, +/- 500, +/- 1000, +/- 2000 to pełny zakres skali wyjściowej. Prędkość kątowa jest mierzona wzdłuż każdej osi w jednostkach stopni na sekundę.

Przydatny link:…………….

Płytka Arduino:.……….

MPU6050 IMU ……………https://compoindia.com/product/mpu6050-3-axis-accelerometer-and-giroscope-sens/

Krok 1: Moduł MPU-6050

Moduł MPU-6050
Moduł MPU-6050

Moduł MPU-6050 posiada 8 pinów,

INT: pin wyjścia cyfrowego przerwania.

AD0: I2C Slave Adres pin LSB. Jest to 0 bit w 7-bitowym adresie urządzenia podrzędnego. Jeśli jest podłączony do VCC, jest odczytywany jako logiczny i zmienia się adres urządzenia podrzędnego.

XCL: pomocniczy pin zegara szeregowego. Ten pin służy do podłączenia innych czujników obsługujących interfejs I2C pin SCL do MPU-6050.

XDA: pomocniczy pin danych szeregowych. Ten pin służy do podłączenia innych czujników obsługujących interfejs I2C pin SDA do MPU-6050.

SCL: pin zegara szeregowego. Podłącz ten pin do pinu SCL mikrokontrolera. SDA: pin danych szeregowych. Podłącz ten pin do pinu SDA mikrokontrolera.

GND: Uziemienie. Podłącz ten pin do uziemienia.

VCC: pin zasilania. Podłącz ten pin do zasilania +5V DC. Moduł MPU-6050 posiada adres Slave (gdy AD0 = 0, czyli nie jest podłączony do Vcc) jako, Adres zapisu Slave (SLA+W): 0xD0

Adres odczytu Slave (SLA + R): 0xD1

Krok 2: Obliczenia

Obliczenia
Obliczenia

Dane czujnika żyroskopu i akcelerometru modułu MPU6050 składają się z 16-bitowych nieprzetworzonych danych w formie uzupełnienia do dwóch.

Dane czujnika temperatury modułu MPU6050 składają się z danych 16-bitowych (nie w formie uzupełnienia do dwójek).

Załóżmy teraz, że wybraliśmy,

  • - Pełen zakres skali akcelerometru +/- 2g ze współczynnikiem skali czułości 16, 384 LSB (liczba)/g.
  • - Pełny zakres skali żyroskopu +/- 250 ° / s ze współczynnikiem skali czułości 131 LSB (liczba) / ° / s. następnie,

Aby uzyskać surowe dane z czujnika, musimy najpierw wykonać uzupełnienie dwójek na danych czujnika akcelerometru i żyroskopu. Po uzyskaniu nieprzetworzonych danych z czujnika możemy obliczyć przyspieszenie i prędkość kątową, dzieląc nieprzetworzone dane z czujnika z ich współczynnikiem skali czułości w następujący sposób:

Wartości akcelerometru w g (siła g)

  • Przyspieszenie wzdłuż osi X = (dane surowe akcelerometru osi X/16384) g.
  • Przyspieszenie wzdłuż osi Y = (surowe dane osi Y akcelerometru/16384) g.
  • Przyspieszenie wzdłuż osi Z = (dane surowe akcelerometru osi Z/16384) g.

Wartości żyroskopu w °/s (stopnie na sekundę)

  • Prędkość kątowa wzdłuż osi X = (surowe dane osi X żyroskopu/131) °/s.
  • Prędkość kątowa wzdłuż osi Y = (surowe dane osi Y żyroskopu/131) °/s.
  • Prędkość kątowa wzdłuż osi Z = (surowe dane osi Z żyroskopu/131) °/s.

Wartość temperatury w °/c (stopni na Celsjusza)

Temperatura w stopniach C = ((dane czujnika temperatury)/340 + 36,53) °/c.

Na przykład, Załóżmy, że po dopełnieniu 2’ otrzymamy akcelerometr osi X surową wartość = +15454

Wtedy topór = +15454/16384 = 0,94 g.

Więcej,

Wiemy więc, że działamy z czułością +/-2G i +/-250deg/s, ale jak nasze wartości odpowiadają tym przyspieszeniom/kątom.

Oba wykresy są proste i możemy z nich wywnioskować, że dla 1G odczytamy 16384, a dla 1 stopnia/sek. odczytamy 131,07 (chociaż.07 zostanie zignorowane z powodu binarnego) te wartości zostały właśnie obliczone poprzez narysowanie wykres liniowy z 2G przy 32767 i -2G przy -32768 i 250/-250 przy tych samych wartościach.

Więc teraz znamy nasze wartości czułości (16384 i 131.07), musimy tylko odjąć przesunięcia od naszych wartości, a następnie podzielić przez czułość.

Będą one działać dobrze dla wartości X i Y, ale ponieważ Z zostało zarejestrowane przy 1G, a nie 0, będziemy musieli odjąć 1G (16384), zanim podzielimy przez naszą czułość.

Krok 3: Połączenia MPU6050-Atmega328p

Połączenia MPU6050-Atmega328p
Połączenia MPU6050-Atmega328p
Połączenia MPU6050-Atmega328p
Połączenia MPU6050-Atmega328p
Połączenia MPU6050-Atmega328p
Połączenia MPU6050-Atmega328p

Wystarczy podłączyć wszystko, jak podano na schemacie…

Połączenia są podane w następujący sposób:-

MPU6050 Arduino Nano

Pin wyjściowy VCC 5v

GND Pin uziemiający

SDA A4 pin//dane szeregowe

SCL A5 pin // zegar szeregowy

Obliczanie skoku i przechyłu: Przechylenie to obrót wokół osi x, a skok to obrót wzdłuż osi y.

Wynik jest w radianach. (przekonwertuj na stopnie, mnożąc przez 180 i dzieląc przez pi)

Krok 4: Kody i wyjaśnienia

Kody i wyjaśnienia
Kody i wyjaśnienia

/*

Samouczek dotyczący akcelerometru i czujnika żyroskopowego Arduino i MPU6050 autorstwa Dejana, https://howtomechatronics.com */ #include const int MPU = 0x68; // MPU6050 adres I2C float AccX, AccY, AccZ; pływak GyroX, GyroY, GyroZ; pływak accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; pływak, skok, zbaczanie; błąd pływaka AccErrorX, AccError, błąd żyroskopu, błąd żyroskopu, błąd żyroskopu; float elapsedTime, currentTime, previousTime; int c = 0; void setup() { Serial.begin(19200); Wire.początek(); // Zainicjuj komunikację Wire.beginTransmission(MPU); // Rozpocznij komunikację z MPU6050 // MPU=0x68 Wire.write(0x6B); // Porozmawiaj z rejestrem 6B Wire.write(0x00); // Wykonaj reset - umieść 0 w rejestrze 6B Wire.endTransmission(true); //zakończ transmisję /* // Konfiguruj czułość akcelerometru - zakres pełnej skali (domyślnie +/- 2g) Wire.beginTransmission(MPU); Wire.write(0x1C); //Porozmawiaj z rejestrem ACCEL_CONFIG (szesnastkowy 1C) Wire.write(0x10); //Ustaw bity rejestru na 00010000 (+/- 8g pełnego zakresu skali) Wire.endTransmission(true); // Konfiguruj czułość żyroskopu - pełny zakres skali (domyślnie +/- 250 stopni/s) Wire.beginTransmission(MPU); Wire.write(0x1B); // Porozmawiaj z rejestrem GYRO_CONFIG (1B hex) Wire.write(0x10); // Ustaw bity rejestru na 00010000 (pełna skala 1000 stopni/s) Wire.endTransmission(true); opóźnienie(20); */ // Wywołaj tę funkcję, jeśli chcesz uzyskać wartości błędów IMU dla Twojego modułu oblicz_IMU_error(); opóźnienie(20); } void loop() { // === Odczyt danych akcelerometru === // Wire.beginTransmission(MPU); Wire.write(0x3B); // Zacznij od rejestru 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU, 6, prawda); // Odczytaj łącznie 6 rejestrów, każda wartość osi jest przechowywana w 2 rejestrach //Dla zakresu +-2g musimy podzielić nieprzetworzone wartości przez 16384, zgodnie z arkuszem danych AccX = (Wire.read() << 8 | Drut.odczyt()) / 16384.0; // Wartość osi X AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Wartość osi Y AccZ = (Przewód.odczyt() << 8 | Przewody.odczyt()) / 16384.0; // Wartość osi Z // Obliczanie Roll and Pitch z danych akcelerometru accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) Aby uzyskać więcej informacji, zobacz funkcję niestandardową translate_IMU_error() accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1,58; // AccErrorY ~(-1.58) // === Odczyt danych żyroskopu === // previousTime = currentTime; // Poprzedni czas jest przechowywany przed aktualnym odczytanym czasem currentTime = millis(); // Aktualny czas aktualny czas odczytany elapsedTime = (currentTime - previousTime) / 1000; // Podziel przez 1000, aby otrzymać sekundy Wire.beginTransmission(MPU); Wire.write(0x43); // adres pierwszego rejestru danych żyroskopowych 0x43 Wire.endTransmission(false); Wire.requestFrom(MPU, 6, prawda); // Odczytaj łącznie 4 rejestry, każda wartość osi jest przechowywana w 2 rejestrach GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // Dla zakresu 250 st./s musimy najpierw podzielić surową wartość przez 131,0, zgodnie z arkuszem danych GyroY = (Wire.read() << 8 | Wire.read()) / 131.0; Żyroskop = (Przewód.odczyt() << 8 | Przewod.odczyt()) / 131,0; // Skoryguj wyjścia obliczonymi wartościami błędów GyroX = GyroX + 0.56; // Błąd żyroskopuX ~(-0.56) żyroskop = żyroskop - 2; // GyroErrorY ~(2) GyroZ = GyroZ + 0,79; // GyroErrorZ ~ (-0,8) // Obecnie nieprzetworzone wartości są w stopniach na sekundę, deg/s, więc musimy pomnożyć przez sendond (s), aby otrzymać kąt w stopniach gyroAngleX = gyroAngleX + GyroX * elapsedTime; // deg/s * s = deg kąt żyroskopuY = kąt żyroskopuY + żyroskop * elapsedTime; zbaczanie = zbaczanie + GyroZ * upływ czasu; // Filtr komplementarny - połącz wartości akceleromtera i kąta odchylenia żyroskopowego roll = 0,96 * gyroAngleX + 0,04 * accAngleX; skok = 0,96 * kąt odchylenia żyroskopowego + 0,04 * kąt kąta odchylenia; // Wydrukuj wartości na monitorze szeregowym Serial.print(roll); Serial.print("/"); Serial.print(rozstaw); Serial.print("/"); Serial.println(odchylenie); } void generate_IMU_error() { // Możemy wywołać tę funkcję w sekcji ustawień, aby obliczyć błąd danych akcelerometru i żyroskopu. Stąd otrzymamy wartości błędów użyte w powyższych równaniach wydrukowanych na monitorze szeregowym. // Zwróć uwagę, że powinniśmy ustawić IMU płasko, aby uzyskać prawidłowe wartości, tak abyśmy mogli następnie otrzymać prawidłowe wartości // Odczytać wartości akcelerometru 200 razy while (c < 200) { Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(fałsz); Wire.requestFrom(MPU, 6, prawda); AccX = (Przewód.odczyt() << 8 | Przewod.odczyt()) / 16384.0; AccY = (Przewód.odczyt() << 8 | Przewod.odczyt()) / 16384.0; AccZ = (Przewód.odczyt() << 8 | Przewod.odczyt()) / 16384.0; // Sumuj wszystkie odczyty 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++; } //Podziel sumę przez 200, aby uzyskać wartość błędu AccErrorX = AccErrorX / 200; AccErrorY = AccErrorY / 200; c = 0; // Odczytaj wartości żyroskopu 200 razy while (c < 200) { Wire.beginTransmission(MPU); Wire.write(0x43); Wire.endTransmission(fałsz); Wire.requestFrom(MPU, 6, prawda); GyroX = Drut.odczyt() << 8 | Drut.odczyt(); Żyroskop = Drut.odczyt() << 8 | Drut.odczyt(); Żyroskop = Drut.odczyt() << 8 | Drut.odczyt(); // Sumuj wszystkie odczyty GyroErrorX = GyroErrorX + (GyroX / 131.0); Błąd żyroskopu = błąd żyroskopu + (żyroskop / 131,0); GyroErrorZ = GyroErrorZ + (GyroZ/131,0); c++; } //Podziel sumę przez 200, aby otrzymać wartość błędu GyroErrorX = GyroErrorX / 200; Błąd żyroskopu = błąd żyroskopu / 200; Błąd żyroskopuZ = Błąd żyroskopuZ / 200; // Wydrukuj wartości błędów na monitorze szeregowym Serial.print("AccErrorX: "); Serial.println(AccErrorX); Serial.print("AccErrorY: "); Serial.println(AccErrorY); Serial.print("GyroErrorX: "); Serial.println(GyroErrorX); Serial.print("Błąd żyroskopu: "); Serial.println(Błąd żyroskopu); Serial.print("GyroErrorZ: "); Serial.println(GyroErrorZ); } -------------------------------------------------- ---------------------------------------------- Wyniki:- X = Y = Z = ------------------------------------------------- ----------------------------------------------- Ważna uwaga: -----------------

W sekcji pętli zaczynamy od odczytania danych z akcelerometru. Dane dla każdej osi są przechowywane w 2 bajtach lub rejestrach i możemy zobaczyć adresy tych rejestrów z arkusza danych czujnika.

Aby odczytać je wszystkie, zaczynamy od pierwszego rejestru i za pomocą funkcji requiestFrom() żądamy odczytania wszystkich 6 rejestrów dla osi X, Y i Z. Następnie odczytujemy dane z każdego rejestru, a ponieważ wyjścia są komplementarne do dwójek, łączymy je odpowiednio, aby uzyskać prawidłowe wartości.

Krok 5: Zrozumienie kąta pochylenia

Akcelerometr

Grawitacja ziemska to stałe przyspieszenie, w którym siła jest zawsze skierowana w dół do środka Ziemi.

Gdy akcelerometr jest równoległy do grawitacji, zmierzone przyspieszenie wyniesie 1G, gdy akcelerometr jest prostopadły do grawitacji, zmierzy 0G.

Kąt pochylenia można obliczyć na podstawie zmierzonego przyspieszenia za pomocą tego równania:

θ = sin-1 (zmierzone przyspieszenie / przyspieszenie grawitacyjne)

GyroGyro (czyli czujnik prędkości) służy do pomiaru prędkości kątowej (ω).

Aby uzyskać kąt nachylenia robota, musimy zintegrować dane z żyroskopu, jak pokazano w poniższym równaniu:

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

Fuzja czujnika żyroskopu i akcelerometruPo przestudiowaniu charakterystyk żyroskopu i akcelerometru wiemy, że mają one swoje mocne i słabe strony. Obliczony kąt nachylenia z danych akcelerometru ma długi czas odpowiedzi, podczas gdy zintegrowany kąt nachylenia z danych żyroskopowych podlega dryfowi przez pewien okres czasu. Innymi słowy, możemy powiedzieć, że dane z akcelerometru są przydatne w dłuższej perspektywie, podczas gdy dane z żyroskopu są przydatne w krótkim okresie.

Link do lepszego zrozumienia: Kliknij tutaj

Zalecana: