Cześć dziś zajmiemy się modułem MPU6050, który możemy zakupić TUTAJ.
MPU6050 jest układem łączącym w sobie cyfrowy termometr, 3-osiowy żyroskop oraz 3-osiowy akcelerometr zapewniający szybki oraz stabilny pomiar położenia. MPU komunikuje się z mikrokontrolerem przy użyciu magistrali I2C.
Cechy modułu:
- Pobór prądu przez żyroskop: 3.6 mA
- Pobór prądu przez akcelerometr: 500 uA
- Pobór prądu przez MPU: 250 uA
- Komunikacja: Magistrala I²C 400 kHz
- Zakres pomiarowy żyroskopu: +/-250, +/-500, +/-1000, +/-2000 stopni/sekundę
- Zakres pomiarowy akcelerometru: +/-2 g, +/-4 g. +/- 8 g, +/-16 g
- Rozdzielczość: 16 bitowa dla każdej osi każdego czujnika
- Szybkość pomiaru żyroskopu: od 4 do 8000 Hz
- Szybkość pomiaru akcelerometru: od 4 do 1000 Hz
- Szybkość pomiaru MPU: od 5 do 200 Hz
- Programowalne wyjście przerwań informujące o poruszeniu urządzenia lub dokonaniu pomiaru
Opis wyjść:
- VDD – Zasilanie
- GND – Masa zasilania
- INT – Wyjście przerwania (typu otwarty dren)
- SCL – Wejście sygnału zegarowego magistrali i2c
- SDA – Sygnał danych magistrali i2c
- AD0 – Wybiera adres układu na magistrali I²C (podłączony do GND adres 0x68 – podłączony do Vcc, adres 0x69)
- XCL – Wyjście sygnału zegarowego magistrali i2c do magnetometru
- XDA – Sygnał danych magistrali i2c do magnetometru
Ale zanim zaczniemy omówmy trochę teorii.
Jak działa akcelerometr ?
Akcelerometr działa na zasadzie efektu piezoelektrycznego. Aby to dobrze zrozumieć musimy wyobrazić sobie prostopadłościan, oraz kulkę w jego wnętrzu. Jak na zdjęciu poniżej.
Ściany tego prostopadłościanu są wykonane z piezoelektrycznych kryształów. Gdy odchylimy nasz prostopadłościan kula jest zmuszona do przemieszczenia się w w kierunku nachylenia, pod wpływem siły ciężkości. Ściana z jaką kula zderza się ze ścianą prostopadłościanu tworzy prąd elektryczny. Istnieją trzy pary ścianek. Każda para odpowiada osi w przestrzeni 3D: X, Y i Z. W zależności od prądu wyprodukowanego ze ścian, możemy określić kierunek nachylenia oraz jego wychylenie.
Jak działa żyroskop?
Żyroskopy działają na zasadzie efektu Coriolisa . Musimy wyobrazić sobie, że kryształy są w ciągłym ruchu tam i z powrotem. Odbywa się to w miejscu za pomocą piezoelektrycznych kryształów. Za każdym razem ,gdy spróbujemy przechylić ten układ , kryształy doświadczają sił w kierunku nachylenia. Jest to spowodowane wskutek bezwładności ruchomego kryształu. W ten sposób kryształy wytwarzają prąd, a prąd ten jest wzmacniany przez mikrokontroler.
Podłączenie
Jak już wspomniałem MPU-6050 komunikuje się z naszą płytką przy pomocy magistrali I2C. Dzięki czemu możemy podłączyć czujnik za pomocą 4 przewodów.
Programowanie
Pisząc kod do tego czujnika skorzystamy z biblioteki I2Cdev
Dostępna jest ona TUTAJ.
Przejdźmy do pierwszego kodu, który umożliwi odczyt danych z akcelerometru oraz żyroskop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include "I2Cdev.h" #include "MPU6050.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 accelgyro; int16_t ax, ay, az; int16_t gx, gy, gz; #define OUTPUT_READABLE_ACCELGYRO #define LED_PIN 13 bool blinkState = false; void setup() { #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(38400); Serial.println("Initializing I2C devices..."); accelgyro.initialize(); Serial.println("Testing device connections..."); Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); pinMode(LED_PIN, OUTPUT); } void loop() { accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz) #ifdef OUTPUT_READABLE_ACCELGYRO Serial.print("a/g:\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.print("\t"); Serial.print(gx); Serial.print("\t"); Serial.print(gy); Serial.print("\t"); Serial.println(gz); #endif #ifdef OUTPUT_BINARY_ACCELGYRO Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF)); Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF)); Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF)); Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF)); Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF)); Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF)); #endif blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); } |
Dzięki czujnikowi możemy wykrywać ruch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include "Wire.h" #include "SPI.h" #include "I2Cdev.h" #include "MPU60X0.h" MPU60X0 accelgyro; int16_t ax, ay, az; int16_t gx, gy, gz; int8_t threshold, count; float temp; bool zero_detect; bool TurnOnZI = false; bool XnegMD, XposMD, YnegMD, YposMD, ZnegMD, ZposMD; #define LED_PIN 13 bool blinkState = false; void setup() { Wire.begin(); Serial.begin(38400); accelgyro.initialize(); accelgyro.setAccelerometerPowerOnDelay(3); accelgyro.setIntZeroMotionEnabled(TurnOnZI); accelgyro.setDHPFMode(1); accelgyro.setMotionDetectionThreshold(2); accelgyro.setZeroMotionDetectionThreshold(2); accelgyro.setMotionDetectionDuration(40); accelgyro.setZeroMotionDetectionDuration(1); pinMode(LED_PIN, OUTPUT); } void loop() { accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); XnegMD = accelgyro.getXNegMotionDetected(); XposMD = accelgyro.getXPosMotionDetected(); YnegMD = accelgyro.getYNegMotionDetected(); YposMD = accelgyro.getYPosMotionDetected(); ZnegMD = accelgyro.getZNegMotionDetected(); ZposMD = accelgyro.getZPosMotionDetected(); zero_detect = accelgyro.getIntMotionStatus(); threshold = accelgyro.getZeroMotionDetectionThreshold(); temp=(accelgyro.getTemperature()/340.)+36.53; Serial.print(temp);Serial.print(","); Serial.print(ax/16384.); Serial.print(","); Serial.print(ay/16384.); Serial.print(","); Serial.print(az/16384.); Serial.print(","); Serial.print(gx/131.072); Serial.print(","); Serial.print(gy/131.072); Serial.print(","); Serial.print(gz/131.072); Serial.print(","); Serial.print(zero_detect); Serial.print(","); Serial.print(XnegMD); Serial.print(","); Serial.println(XposMD); delay(80); blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); } |
Jest to dość niestabilny sposób, jednak działa jak powinien 🙂
Moduł ten możemy wykorzystać do wielu ciekawych projektów. Na przykład taki jak robot balansujący.
[su_youtube url=”https://www.youtube.com/watch?v=e336GLYCWEM”]
W kolejnych częściach poradnika dowiemy się jak graficznie przedstawić dane z czujnika.
Poradnik powstaje dzięki współpracy ze sklepem internetowym XBot.pl – roboty to lubią
[su_button url=”https://roboblog.eu/2016/03/12/nrf24l01/” size=”7″]Poprzednia część kursu[/su_button]