3-osiowy żyroskop i akcelerometr MPU6050
MPU6050 jest układem, który łączy w sobie 3-osiowy żyroskop, 3-osiowy akcelerometr oraz cyfrowy termometr. Z powodzeniem może zastąpić opisywane już wcześniej układy ADXL345 oraz L3G4200D. Jego szczególną cechą jest wbudowana sprzętowa jednostka DMP (Digital Motion Processor), która ułatwia przeliczanie przetwarzanych danych z wszystkich trzech czujników na konkretne położenie względem Ziemi, odciążając tym samym mikrokontroler. Jednostkę DMP można zaprogramować tak, aby wykorzystywała do swoich obliczeń również zewnętrzny magnetometr.
W odróżnieniu od opisywanego już żyroskopu L3G4200D, oprócz możliwości pracy w zakresach pomiarowych ±250°/s, ±500°/s oraz ±2000°/s posiada dodatkowy tryb ±1000°/s, co czyni go bardziej uniwersalnym rozwiązaniem. Za przetwarzanie danych odpowiada również 16 bitowy przetwornik. Przewagą MPU6050 nad ADXL345 jest również dokładniejszy 16-bitowy przetwornik zamiast 13-bitowego. Praktycznie MPU6050 posiada takie same funkcje jak ADXL345 oraz L3G4200D, jednak rozszerza swoje właściwości o programowalny filtr dolnoprzepustowy, dodatkową szynę do komunikacji z innymi układami oraz dodatkowe tryby oszczędzania energii. Wszystko to przy maksymalnym poborze prądu 4.1mA (w duecie L3G4200D oraz ADXL345 potrafi przekroczyć 6mA)
Napięcie zasilania może mieścić się w zakresie od 2.375V ÷ 3.46V, natomiast poziomy logiczne mogą mieścić się w zakresie od 1.71V do wartości napięcia zasilania
Wyprowadzania linii układu oraz orientacja osi
Podłączenie MPU6050 do Arduino
Układ MPU6050 toleruje zasilanie z przedziału 2.375V ÷ 3.46V, więc jeśli planujemy podłączyć go do Arduino UNO, nie zapomnijmy o konwerterze napięć poziomów logicznych. W przypadku modułu IMU GY-86 oraz IMU GY-87, możemy skorzystać z 5V zasilania. Pin oznaczony SCL (adapter) podłączamy do pinu A5 (Arduino), natomiast pin SDA (adapter) do pinu A4 (Arduino). W moim układzie wykorzystałem również dwie diody z rezystorami 220Ω, sterowane wyjściami cyfrowymi Arduino (4,7) do sygnalizacji przerwań.
Do obsługi modułów z układami MPU6050 przygotowałem również odpowiednią do nich bibliotekę dla Arduino, którą można pobrać z repozytorium Git: https://github.com/jarzebski/Arduino-MPU6050
Odczyt danych z żyroskopu
Odczyt z żyroskopu realizowany jest w podobny sposób jak w L3G4200D. Mamy możliwość odczytu danych bezpośrednich za pomocą funkcji readRawGyro() oraz przeliczonych na jednostkę dps za pomocą funkcji readNormalizeGyro(). Praktycznie jedyną różnicą jest inicjalizacja układu, gdzie konfigurujemy jednocześnie akcelerometr jak i żyroskop.
- #include <Wire.h>
- #include <MPU6050.h>
- MPU6050 mpu;
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Inicjalizacja MPU6050");
- while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
- {
- Serial.println("Nie mozna znalezc MPU6050 - sprawdz polaczenie!");
- delay(500);
- }
- // Kalibracja żyroskopu
- mpu.calibrateGyro();
- // Ustawienie czułości
- mpu.setThreshold(3);
- }
- void loop()
- {
- Vector rawGyro = mpu.readRawGyro();
- Vector normGyro = mpu.readNormalizeGyro();
- Serial.print(" Xraw = ");
- Serial.print(rawGyro.XAxis);
- Serial.print(" Yraw = ");
- Serial.print(rawGyro.YAxis);
- Serial.print(" Zraw = ");
- Serial.println(rawGyro.ZAxis);
- Serial.print(" Xnorm = ");
- Serial.print(normGyro.XAxis);
- Serial.print(" Ynorm = ");
- Serial.print(normGyro.YAxis);
- Serial.print(" Znorm = ");
- Serial.println(normGyro.ZAxis);
- delay(10);
- }
Odczyt danych z akcelerometru
W przypadku odczytu danych z akcelerometru, analogicznie posługujemy się funkcjami readRawAccel() oraz readNormalizeAccel(). Znormalizowaną jednostką są tutaj m/s.
- #include <Wire.h>
- #include <MPU6050.h>
- MPU6050 mpu;
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Inicjalizacja MPU6050");
- while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
- {
- Serial.println("Nie mozna znalezc MPU6050 - sprawdz polaczenie!");
- delay(500);
- }
- }
- void loop()
- {
- Vector rawAccel = mpu.readRawAccel();
- Vector normAccel = mpu.readNormalizeAccel();
- Serial.print(" Xraw = ");
- Serial.print(rawAccel.XAxis);
- Serial.print(" Yraw = ");
- Serial.print(rawAccel.YAxis);
- Serial.print(" Zraw = ");
- Serial.println(rawAccel.ZAxis);
- Serial.print(" Xnorm = ");
- Serial.print(normAccel.XAxis);
- Serial.print(" Ynorm = ");
- Serial.print(normAccel.YAxis);
- Serial.print(" Znorm = ");
- Serial.println(normAccel.ZAxis);
- delay(10);
- }
Odczyt temperatury
Jeśli chodzi odczyt temperatury, realizujemy ją za pomocą funkcji readTemperature().
- #include <Wire.h>
- #include <MPU6050.h>
- MPU6050 mpu;
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Inicjalizacja MPU6050");
- while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
- {
- Serial.println("Nie mozna znalezc MPU6050 - sprawdz polaczenie!");
- delay(500);
- }
- }
- void loop()
- {
- float temp = mpu.readTemperature();
- Serial.print(" Temp = ");
- Serial.print(temp);
- Serial.println(" *C");
- delay(500);
- }
Filtr Kalmana
Układ MPU6050 z racji posiadania zarówno akcelerometru jak i żyroskopu, pozwala na zastoswanie filtru Kalmana, inaczej mówiąc algorytmu rekurencyjnego. Ponieważ nie jestem wybitnym matematykiem, nie odważę się dokładnie tłumaczyć zasady jego działania, ale w ogólnym uproszczeniu wykorzystuje on dane żyroskopu do korekcji odczytanych danych z akcelerometru, dzięki czemu całość działa wyjątkowo stabilnie. Jeśli masz ochotę, możesz poczytać o nim tutaj: Odczyty Pitch & Roll oraz filtr Kalmana
Detekcja ruchu i bezruchu
MPU6050 pozwala na detekcję ruchu i bezruchu całego układu z wykorzystaniem przerwań. Na potrzeby tego przykładu, nie będziemy jednak obsługiwali sprzętowej obsługi przerwania, a jedynie programowej. Zasada działania została opisana w programie poniżej.
- #include <Wire.h>
- #include <MPU6050.h>
- MPU6050 mpu;
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Inicjalizacja MPU6050");
- while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_16G))
- {
- Serial.println("Nie mozna znalezc MPU6050 - sprawdz polaczenie!");
- delay(500);
- }
- // Dodatkowe opoznienie zasilania akcelerometru 3ms
- mpu.setAccelPowerOnDelay(MPU6050_DELAY_3MS);
- // Wylaczamy sprzetowe przerwania dla wybranych zdarzen
- mpu.setIntFreeFallEnabled(false);
- mpu.setIntZeroMotionEnabled(false);
- mpu.setIntMotionEnabled(false);
- // Ustawiamy filtr gorno-przepustowy
- mpu.setDHPFMode(MPU6050_DHPF_5HZ);
- // Ustawiamy granice wykrywania ruchu na 4mg (zadana wartosc dzielimy przez 2)
- // oraz minimalny czas trwania na 5ms
- mpu.setMotionDetectionThreshold(2);
- mpu.setMotionDetectionDuration(5);
- // Ustawiamy granice wykrywania bezruchu na 8mg (zadana wartosc dzielimy przez 2)
- // oraz minimalny czas trwania na 2ms
- mpu.setZeroMotionDetectionThreshold(4);
- mpu.setZeroMotionDetectionDuration(2);
- // Ustawiamy piny 4 i 5 na wyjscia w stanie niskim.
- // Diody podlaczone do tych wyjsc beda sygnalizowaly nasze stany
- pinMode(4, OUTPUT);
- digitalWrite(4, LOW);
- pinMode(7, OUTPUT);
- digitalWrite(7, LOW);
- }
- void loop()
- {
- Vector rawAccel = mpu.readRawAccel();
- Activites act = mpu.readActivites();
- // Jesli wyrkryto ruch - zapal diode na pinie 4
- if (act.isActivity)
- {
- digitalWrite(4, HIGH);
- } else
- {
- digitalWrite(4, LOW);
- }
- // Jesli wyrkryto bezruch - zapal diode na pinie 7
- if (act.isInactivity)
- {
- digitalWrite(7, HIGH);
- } else
- {
- digitalWrite(7, LOW);
- }
- delay(50);
- digitalWrite(4, LOW);
- }
Detekcja upadku swobodnego
Poniższy przykład pokazuje w jaki sposób za pomocą MPU6050 można wykryć upadek swobodny. Tym razem wykorzystamy już przerwanie sprzętowe.
- #include <Wire.h>
- #include <MPU6050.h>
- MPU6050 mpu;
- boolean ledState = false; // aktualny stan diody LED
- boolean freefallDetected = false; // czy wykryto upadek swobodny
- boolean freefallBlinkCount = 0; // liczba mrugniec diody LED
- void setup()
- {
- Serial.begin(115200);
- Serial.println("Inicjalizacja MPU6050");
- while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_16G))
- {
- Serial.println("Nie mozna znalezc MPU6050 - sprawdz polaczenie!");
- delay(500);
- }
- // Dodatkowe opoznienie zasilania akcelerometru 3ms
- mpu.setAccelPowerOnDelay(MPU6050_DELAY_3MS);
- // Wlaczamy obsluge przerwania sprzetowego dla akcji upadku swobodnego
- mpu.setIntFreeFallEnabled(true);
- mpu.setIntZeroMotionEnabled(false);
- mpu.setIntMotionEnabled(false);
- // Ustawiamy filtr gorno-przepustowy
- mpu.setDHPFMode(MPU6050_DHPF_5HZ);
- // Aby ruch zostal wykryty jako upadek swobodny, musi wystapic przeciazenie minimum 34mg w czasie 3ms.
- mpu.setFreeFallDetectionThreshold(17);
- mpu.setFreeFallDetectionDuration(2);
- // Dioda podlaczona do pinu 4 bedzie sygnalizowac wykryty stan
- pinMode(4, OUTPUT);
- digitalWrite(4, LOW);
- // Aktywujemy obsuge przerwania na pinie 2, aktywne na zbocze narastajace
- attachInterrupt(0, doInt, RISING);
- }
- // Funkcja obslugi przerwania
- void doInt()
- {
- // resetujemy licznik mrugniec i informujemy program, ze akcja zostala rozponana
- freefallBlinkCount = 0;
- freefallDetected = true;
- }
- void loop()
- {
- Vector rawAccel = mpu.readRawAccel();
- Activites act = mpu.readActivites();
- // Jesli wykryto upadek swobodny, dioda LED bedzie mrugac okreslona liczbe razy
- if (freefallDetected)
- {
- ledState = !ledState;
- digitalWrite(4, ledState);
- freefallBlinkCount++;
- if (freefallBlinkCount == 20)
- {
- freefallDetected = false;
- ledState = false;
- digitalWrite(4, ledState);
- }
- }
- delay(100);
- }
Prezentacja działania
Materiały dodatkowe
Biblioteka MPU6050: https://github.com/jarzebski/Arduino-MPU6050
Filtr Kalmana: https://github.com/jarzebski/Arduino-KalmanFilter
MPU6050 rev 3.2: https://www.jarzebski.pl/datasheets/MPU6050_rev32.pdf
MPU6050 rev 3.4: https://www.jarzebski.pl/datasheets/MPU6050_rev34.pdf
MPU6050 rev 4.0: https://www.jarzebski.pl/datasheets/MPU6050_rev40.pdf
MPU6050 rev 4.2: https://www.jarzebski.pl/datasheets/MPU6050_rev42.pdf
Reklama
Komentarze
Robiłem na magisterkę robota i szukałem taniego akcelerometru na I2C, trafiłem na płytkę z MPU-6050. Jak się okazało, ten układ to prawdziwy kombajn(to ma w środku nawet procesor do obróbki danych) biblioteki do tego niestety chyba nie dostępne nie komercyjnie. Dostępne są binarne zrzuty oprogramowania.
Do wyznaczenia orientacji w przestrzeni korzystałem z kodu tego Pana:
http://davidegironi.blogspot.com/2013/02/avr-atmega-mpu6050-gyroscope-and.html
Do fuzji odczytów stosuje się tam filtr proporcjonalno-całkujący mahonnego tu w miarę omówiony:
http://www.olliw.eu/2013/imu-data-fusing/
Wykorzystano tam kwateriony i dzięki temu nie ma problemu gimball lock.
Ode mnie wielki szacunek dla autorów tego algorytmu, wygląda to na mega skomplikowane, ale jak się wczytać w kod, to w rzeczywistości kilka operacji. W dodatku w drugim linku na końcu strony są implementacje w C dla 6 i 9 stopi swobody(z magnetometrem).
Piszę o tym, bo to najlepszy sposób na w miarę wydajną estymację obrotów w przestrzeni, jeszcze lepiej wykorzystać wewnętrzny procesor i czytać współrzędne kwateriona wprost ze scalaka.
Kapitalne odnośniki! Wielkie dzięki Qba - jutro zabieram się do czytania :)
Czesc, czy mógłbys dać jakiś kontakt do siebie? Siedzę już dłuższy czas nad tym i mam pewien problem. Gdy zmieniam kąt pitch o 90 stopni to kąt yaw również się zmienia. Próbowałem już chyba wszystkich dostępnych bibliotek i bez efektu. Nie miałeś takiego problemu? Używam mpu-6050 + hmc5883l
Witam,
Mam pytanie co może być powodem, iż dostaje takie komunikaty błędów?
MPU6050_accel_pitch_roll.ino: In function \'void setup()\':
MPU6050_accel_pitch_roll:20: error: \'class MPU6050\' has no member named \'begin\'
MPU6050_accel_pitch_roll:20: error: \'MPU6050_SCALE_2000DPS\' was not declared in this scope
MPU6050_accel_pitch_roll:20: error: \'MPU6050_RANGE_2G\' was not declared in this scope
MPU6050_accel_pitch_roll.ino: In function \'void loop()\':
MPU6050_accel_pitch_roll:30: error: \'Vector\' was not declared in this scope
MPU6050_accel_pitch_roll:30: error: expected `;\' before \'normAccel\'
MPU6050_accel_pitch_roll:33: error: \'normAccel\' was not declared in this scope
Cześć! Na moje masz dwie biblioteki MPU6050 :)
I am getting the same errors, please help me out
i had this similar problem so i deleted all the mpu6050 libraries and then added the zip file of it so then it worked.
Hope it might help you.
Dzień dobry,
w programie KalmanFilter_processing w metodzie createGraphics brakuje argumentu string. Zadeklarowałem pusty string i podstawiłem, teraz program przynajmniej się kompiluje jednak wyświetla tylko czarne okno.
Co powinno znajdować się jako argument string ?
https://processing.org/reference/createGraphics_.html
Która wersja processing? Może w nowszej wersji jest wymagany trzeci, jako metoda graficzna (P2D, P3D lub PDF)
Hi,
i have one question. did you solved the problem with the black image? HOW?!
Thanks
Michael
Cześć Korneljusz, jak myślisz, można jakoś w prosty sposób przerobić Twój kod "tap" z ADXL 345 tak żeby działał na MPU6050? czy jest z tym więcej zabawy?
Zdecydowanie więcej zabawy - ADXL ma do tego specjalne mechanizmy - w MPU jest to możliwe, ale na piechotkę
Testowałem program podczas jazdy samochodem. Prawidłowe jest to, że dla pomiarów znormalizowanych żyroskopu tylko czasami zmienia się składowa Z? X i Y wynoszą cały czas 0. Pomiary surowe zmieniają się cały czas. Akcelerometru zarówno znormalizowane jak i surowe również.
Żyroskop odczytuje prędkość kątową podczas obrotu
witam, można udostępnić źródła oprogramowania "Processing" widoczny na filmie?
dziękuję
Witam,
Po załączeniu Pańskiej biblioteki i przeklejeniu kodu:
Oryginalny obraz posiada rozmiar 1276x881
kompilator sypie błędami. Wymagał też dodania I2Cdev.h, czego nie widziałem w kodzie. Jakieś sugestie? Czy może być to związane z tym, że przedtem testowałem inną bibliotekę do tego układu?
Pozdrawiam,
A.
Cześć,
Czy mógłbyś napisać na czym bazowałeś projektując filtr Kalmana? Chciałbym go wykorzystać i zmodyfikować, jednak potrzebuję do tego celu jakieś informacje teoretyczne (np. jakie były zmienne stanu w tym modelu, przyjęte macierze, postacie zakłóceń itp.). Ten filtr działa naprawdę dobrze stąd wolałbym go wykorzystać zamiast pisać coś niepewnego od nowa. Link, który jest wyżej przenosi do grafiki programu processing, a nie do informacji na temat filtru Kalmana.
Pozdrawiam,
Michał
Witam,
Świetny materiał!
Testowałem programy i wszystko działa, ale jest jedno ale ... Problem pojawia się przy podłączeniu drugiego modułu do I2C, mianowicie modułu RTC 1307. Okazało się, że korzystają z tego samego adresu 0x68. W MPU6050 można zmienić adres na 0x69 przez wprowadzenie stanu wysokiego (podpięcie 3,3V) na ADO. Wtedy oba moduły, zaczynają działać, RTC radzi sobie świetnie, natomiast MPU podaje wtedy zawyżone wartości. Ma ktoś może pomysł co jest tego powodem i jak to rozwiązać, może przeoczyłem coś oczywistego.
Dzięki za wszelką pomoc.
Pozdrawiam.
Cześć!
Chciałbym zapytać w jaki sposób odczytujesz dane z MPU6050 po zmianie adresu na 0x69? Czy zmieniałeś w MPU6050.h stałą adresu MPU na 0x69? Bo na liście stałych jest już ta wartość przypisana innej - MPU6050_REG_MOT_DETECT_CTRL. W każdym razie mam problem postaci: po zmianie podłączeniu 3.3V do AD0 ani nie wyrzuca błędu ani nie pokazuje danych.
Witam,
Chciałbym pogratulować i jednoczenie podziękować za rewelacyjne artykuły ! :)
Jednak podczas uruchamiania aplikacji KalmanFilter_processing po kompilacji pojawia się pusty czarny ekran i następujące błędy:
- OpenGL error 1280 at bot beginDraw(): invalid enumerant
- OpenGL error 1286 at top endDraw(): invalid framebuffer operation
- OpenGL error 1286 at beginDraw(): invalid framebuffer operation
Szukałem pomocy jednak nigdzie nie mogłem znaleźć. Może jest Pan w stanie napisać, z jakiego aplikacja nie może się uruchomić ?
Pozdrawiam serdecznie.
Jaka wersja Processinga? Pod Windowsem chyba odrobinę inaczej obsługuje się rysowanie.
Czołem:)
Po wgraniu biblioteki sypie błędem:
In file included from /Users/konradkoterba/Documents/Arduino/akcelerometr_simple/akcelerometr_simple.ino:10:0:
/Users/konradkoterba/Documents/Arduino/libraries/MPU6050/MPU6050.h:40:20: fatal error: I2Cdev.h: No such file or directory
#include "I2Cdev.h"
Czy ta biblioteka faktycznie jest potrzebna czy coś robię nie tak?
Po dodaniu tej biblioteki sypie mnóstwo błędów m. in:
error: \'Vector\' was not declared in this scope
Witam
Pytanie, czy upadku swobodnego analizowana jest jedna oś "Z" czy działa to na zmianę przyśpieszenia we wszystkich trzech osiach ?.
Z tego co się orientuję to we wszystkich
Witam, mam pytanie odnośnie błędu który mi wyskakuje. Czy koś miał problem, że kod sie kompiluje, ale podczas wgrywania za pomocą programatora wyskakuje błąd
avrdude: usbdev_open(): did not find any USB device "usb"
będę wdzięczny za szybką pomoc :)
To brak odpowiedniego sterownika - program Zadig polecam do instalacji sterownika
http://zadig.akeo.ie/
Thank you very much for the code!
You make my day!
Hi Kornelisz, I\'m working with zeromotion interrupts in a sleep- wake-up routine in a pro mini 3,3.
I\'m using yours example code, all work fine, but sometimes when I reset or rewrite the arduino interrups work in inverse way.
When they must be a rest, is working and visceversa.
it\'s necesary reset, int, flag, etc?.
interrupt funtion is similar freefall example.
1000 thanks and sorry to bother and my eng
atte Emilio
hmmm strange thing, i\'m not notice this problem on my mpu
Hi Korneliusz, i want to use accelerometer to record values over 2g. I isn\'t able to interpretare i risultati. Can you help me? if i want record values over 2g i write:
MPU. setMotionDetectionThreshold ( 1000 ) ;
MPU. setZeroMotionDetectionThreshold ( ? ) ; //I don\'t know what i have to insert;
Than i have read that the results of readNormalized.Zaxis are in m/s.what is the misure unit of offset that in this case is 1202?
Witam,
Przede wszystkim chcialbym podziekowac za super ilustracje jak dziala plytka GY-86! Z przyjemnoscia oglada sie cwiczenia i wiele juz sie stad nauczylem. Mam pytanie, gdy programuje plytke przez USB (zasilanie jest z komputera) wszystko wydaje sie dzialac ok - sensory przesylaja dane jak nalezy. Natomiast jak plytka jest podlaczona do baterii 3.6V ma inne zachowanie np. Accelerometr pokazuje 2g zamiast 1g na osi Z. A zyroskop nie podaje wartosci znormalizowanych tylko surowe w zasiegu 0 - 65000. Chcialbym zapytac czy ktos mial juz taka sytuacje i moglby pomoc.
Pozdrawiam,
Pawel
Hi, currently I am acquiring data from mpu6050 sensor. using https://github.com/jarzebski/Arduino-MPU6050 this library. But the problem is when I am changing the position of the sensor and bring back to its reference position the angles are not 0. It is different than 0. What is the problem? How to solve it?
i am having the same problems is there a soln to it.
Używałem do testow moduł MPU6050 taki jak tu http://allegro.pl/mpu-6050-3osiowy-zyroskop-akcelerometr-arduino-avr-i5082764471.html. Niestety coś jest nie tak ponieważ nie wykonuje sie kalibracja, a ponadto podczas używania filtru kalmana po kilkunastu sekundach odczytów na monitorze portu pojawiają się olbrzymie liczby i na koniec komunikat ovf.
Odczytując wartości accPitch i accRoll wszystko jest ok, przepełnienie pojawia się tylko podczas odczytu kalPitch i kalRoll
Nie wiem czy temat aktualny ale jest błąd w KalmanFilter.cpp. Poniżej prawidłowo licząca zawartość tego pliku:
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "KalmanFilter.h"
KalmanFilter::KalmanFilter(double angle, double bias, double measure)
{
Q_angle = angle;
Q_bias = bias;
R_measure = measure;
K_angle = 0;
K_bias = 0;
P[0][0] = 0;
P[0][1] = 0;
P[1][0] = 0;
P[1][1] = 0;
kt = (double)micros();
}
double KalmanFilter::update(double newValue, double newRate)
{
dt = (double)(micros() - kt) / 1000000;
K_rate = newRate - K_bias;
K_angle += dt * K_rate;
P[0][0] += dt * (dt*P[1][1] - P[0][1] - P[1][0] + Q_angle); /poprawine!
P[0][1] -= dt * P[1][1];
P[1][0] -= dt * P[1][1];
P[1][1] += Q_bias * dt;
S = P[0][0] + R_measure;
K[0] = P[0][0] / S;
K[1] = P[1][0] / S;
y = newValue - K_angle;
K_angle += K[0] * y;
K_bias += K[1] * y;
P[0][0] -= K[0] * P[0][0];
P[0][1] -= K[0] * P[0][1];
P[1][0] -= K[1] * P[0][0];
P[1][1] -= K[1] * P[0][1];
kt = (double)micros();
return K_angle;
};
Wyniki sa juz OK.niestety nie działa funkcja mpu.calibrateGyro();. Czy to z powodu zastosowania niewłaściwego modułu??
Na jakim Arduino to robisz?
UNO z procesorem 328
Witam ponownie i ponowię swoje zapytanie o funkcję mpu.calibrateGyro(). Nie zeruje ona wskazań kąta, co może być przyczyną?
Ja wprawdzie przy pierwszych moich próbach korzystam z innej biblioteki, ale ta jest inna i też ciekawa. Nie rozumiem procedury kalibracji (wiersze 572-574). Może tu jest błąd, a może coś przeoczyłem. Nie lubię stosować rzeczy, których nie rozumiem, zastosowałem więc prostą funkcję liczenia średniej arytmetycznej n (wystarczy 10) pomiarów w bezruchu dla każdej osi. Wynik podzielony przez 4 wpisuję do rejestrów z odwrotnym znakiem. Działa i wiem dla czego.
UNO R3
Hello friend.
Nie mogę obsługiwać część przetwarzaniem z mega wyświetlaczem PITCH ROLL Accelero GYRO plus 2 kulki, jak on umieścić pliki?
Jeszcze raz dziękuję za wspaniałą miejscu i swojej pasji.
Witam z Francji!
Witam,
Czy jest możliwość uzyskania na MPU6050 dokładności 0.01 stopnia?
Podejrzewam, że na tej pozycji i tak by strasznie pływały wartości
Dzień dobry
Próbuję za pomocą MPU-6050 zrobić klinometr. Chodzi mi o prosty pomiar kątów pionowych w odniesieniu do płaszczyzny poziomej. W oparciu akcelerometr i utworzony model: http://home.agh.edu.pl/~bartus/images/arduino/23/23_katomierz_zasada_dzialania.png wyprowadziłem wzór na kąt nachylenia wektora siły grawitacji (pomiar w stanie spoczynku). Wyprowadzony wzór:
http://home.agh.edu.pl/~bartus/images/arduino/23/23_wz_2.gif
Korzystając z biblioteki Math.h, formuła obliczająca wartość kąta to:
AR = (sin (z / sqrt(square(x) + square(y) + square(z))))/(pi/180);
Niestety obliczone wartości kątów nie odzwierciedlają stanu faktycznego. Gdzieś popełniłem błąd/błędy. Ale nie wiem gdzie...
Zwracam się do Pana z prośba o pomoc.
pozdrawiam
Tomek Bartuś
prześlij może kod na dev (at) jarzebski (dot) pl
Witam, czy ma Pan jakieś wskazówki jak uruchomić aplikację do Kalmana w processing na windowsie? Niestety nie mam możliwości instalacji linuxa
Odczyt danych z żyroskopu, 4 linijka - MPU6050 mpu;
wyskakuje błąd, nie wiem o co chodzi ; (
Dzień dobry.
Co należy zrobić, aby możliwe było użycie Pana biblioteki w arduino nano 328p?
witam,
potrzebuję dokonywać szybkich (z maksymalną prędkością) odczytów gyro i akceleratora w przynajmniej jednej osi na Nano 328.
Czy odczytu z FIFO dokonuje się tak samo jak odczytu bezpośredniego? Z dokumentacji rejestrów wnioskuję, że tak, ale nie mam pewności, czy dobrze wszystko rozumiem.
Nie znalazłem przykładów ani z Pana biblioteką, ani z biblioteką Jeffa Rowberga.
Pozdrawiam wszystkich.
Pytanie nieaktualne
Dla zainteresowanych: do odczytu FIFO jest rejestr 116, przesyła dane w kolejności zgodnej z numerami zadeklarowanych rejestrów
Panie Korneliuszu,
mam pewien dziwny niezidentyfikowany problem z układem MPU6050 + Nano + SD slot. Nie mam pomysłu co może być przyczyną tak dziwnego zachowania.
Mianowicie,
kiedy cały układ mam podpięty do PC przez USB na karcie i przez port szeregowy dane które szczytuję są wg, mnie poprawne (x = 0,12 y = 0,05, z = 9,94) Natomiast kiedy cały układ odłączę od PC i zaczynam go zasilać z power-banka żeby działał jako logger. Na karcie pojawiają się dane jakby zmultiplikowane o ok. 8 (czyli np. (x = 0,96 y = 0,52, z = 83,6). Wspomnę jeszcze że cały program polega na odczycie danych i dopisywanie ich do jednej zmiennej string po czym cała zmienna zostaje zapisana na karcie.
Bardzo proszę o jakąś sugestię.
Witam, korzystając z tej biblioteki można tylko wykorzystać piny A4 i A5, można jakoś to zmienić?
Nie da się, bo to są port I2C, sprzętowo wymuszone.
To, co tutaj znalazłem po godzinach eksperymentowania i guglania baardzo mi pomogło! Działa! Aaaaaa! Jak się wysyła piwo do Autora? Przelewem? Blog wygląda rewelacyjnie, jak tylko polutuję, co muszę, zabieram się do czytania.
Can I please contact you?
I have some problem running MPU 6050 with the Usart to run the motors relative to the error observed by the MPU6050 but it stuck very often.
Witam,
Jednostki znormalizowane akcelerometru to m/s, m/s^2 czy G. Pytam, ponieważ pomimo notatki rzadko już spotkam interpretację drgań w prędkości i zastanawiam się czy nie wkradł się gdzieś przez przypadek błąd.
Pozdrawiam
Wszystko działa bardzo fajnie, ale widzę, że gdy do funcji loop() dodam delay(100) to po chwili wartości lecą w kosmos, wychodzą poza zasięg i Adruino leży. Na razie tylko chciałem zasymulować obciążenie procesora innymi rzeczami.
Jest tu jakiś prosty sposób żeby zabezpieczyć się przed wywaleniem wartości w kosmos jeśli procesor zamuli?
How to change i2c address from 0x68 to 0x69 in your lib
W bibliotece mpu6050 w funkcji readRawAccel() jest mały błąd konwersji, który objawia się na architekturach innych niż AVR. Wartość przyspieszenia jaką zwraca MPU6050 przez 2 8-bitowe rejestry jest w kodzie U2, konieczna jest zatem odpowiednia konwersja przed zapisaniem wyniku do zmiennej float.
Jest:
ra.XAxis = xha << 8 | xla;
ra.YAxis = yha << 8 | yla;
ra.ZAxis = zha << 8 | zla;
Powinno być:
ra.XAxis = (int16_t)(xha << 8 | xla);
ra.YAxis = (int16_t)(yha << 8 | yla);
ra.ZAxis = (int16_t)(zha << 8 | zla);
He, do you speack english or Italian? I\'m from Italy and kiììlike ask you an info about 6050 gyroscope.
I\'m tunning this sketch:
/*
MPU6050 Triple Axis Gyroscope & Accelerometer. Pitch & Roll & Yaw Gyroscope Example.
Read more: http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-zyroskop-i-akcelerometr-mpu6050.html
GIT: https://github.com/jarzebski/Arduino-MPU6050
Web: http://www.jarzebski.pl
(c) 2014 by Korneliusz Jarzebski
*/
#include
#include
MPU6050 mpu;
// Timers
unsigned long timer = 0;
float timeStep = 0.01;
// Pitch, Roll and Yaw values
float pitch = 0;
float roll = 0;
float yaw = 0;
void setup()
{
Serial.begin(115200);
Serial.println("MPU6050_gyro_pitch_roll_yaw");
// Initialize MPU6050
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_16G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
delay(500);
}
// Calibrate gyroscope. The calibration must be at rest.
// If you don\'t want calibrate, comment this line.
mpu.calibrateGyro();
// Set threshold sensivty. Default 3.
// If you don\'t want use threshold, comment this line or set 0.
mpu.setThreshold(3);
}
void loop()
{
timer = millis();
// Read normalized values
Vector norm = mpu.readNormalizeGyro();
// Calculate Pitch, Roll and Yaw
pitch = pitch + norm.YAxis * timeStep;
roll = roll + norm.XAxis * timeStep;
yaw = yaw + norm.ZAxis * timeStep;
// Output raw
Serial.print(" Pitch = ");
Serial.print(pitch);
Serial.print(" Roll = ");
Serial.print(roll);
Serial.print(" Yaw = ");
Serial.println(yaw);
// Wait to full timeStep period
delay((timeStep*1000) - (millis() - timer));
}
I place target in a place with precise refferrals x,y,0,
It run and on terminal I read
Pitch = 0.00 Roll = 0.00 Yaw = 0.00
Then I move the target in all directions, rotations and more.
Then I place in original position, and on terminal i read:
Pitch = -7.16 Roll = 4.80 Yaw = 29.84
What about this offset ?
Many thanks. Best regards
p.s. please see my test on