İçindekiler:

MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p): 5 Adım
MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p): 5 Adım

Video: MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p): 5 Adım

Video: MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p): 5 Adım
Video: Nasıl Otonom Araç Yapılır | Bilmen Gereken 4 Modül 2024, Temmuz
Anonim
MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p)
MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p)
MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p)
MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p)
MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p)
MPU 6050 Gyro, Arduino ile İvmeölçer İletişimi (Atmega328p)

MPU6050 IMU, tek bir çip üzerine entegre edilmiş hem 3 Eksenli ivmeölçer hem de 3 Eksenli jiroskopa sahiptir.

Jiroskop, X, Y ve Z ekseni boyunca dönme hızını veya açısal konumun zaman içindeki değişim oranını ölçer.

Jiroskopun çıktıları derece/saniye cinsindendir, bu nedenle açısal konumu elde etmek için açısal hızı entegre etmemiz yeterlidir.

Öte yandan, MPU6050 ivmeölçer, 3 eksen boyunca yerçekimi ivmesini ölçerek ivmeyi ölçer ve bazı trigonometri matematiği kullanarak sensörün konumlandığı açıyı hesaplayabiliriz. Dolayısıyla, ivmeölçer ve jiroskop verilerini birleştirirsek veya birleştirirsek, sensör oryantasyonu hakkında çok doğru bilgiler elde edebiliriz.

3 eksenli Jiroskop MPU-6050, mikro elektro mekanik sistem teknolojisi (MEMS) ile x, y, z ekseni boyunca dönme hızını algılayabilen 3 eksenli bir jiroskoptan oluşur. Sensör herhangi bir eksen boyunca döndürüldüğünde, MEMS tarafından algılanan Coriolis etkisi nedeniyle bir titreşim üretilir. 16-bit ADC, voltajı her eksenden örneklemek için sayısallaştırmak için kullanılır.+/- 250, +/- 500, +/- 1000, +/- 2000, çıktının tam ölçek aralığıdır. Açısal hız, her eksen boyunca saniye başına derece cinsinden ölçülür.

Yararlı Bağlantı:…………….

Arduino Kurulu:.……….

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

Adım 1: MPU-6050 Modülü

MPU-6050 Modülü
MPU-6050 Modülü

MPU-6050 modülünün 8 pini vardır,

INT: Dijital çıkış pinini kesin.

AD0: I2C Slave Adresi LSB pini. Bu, cihazın 7 bitlik slave adresindeki 0. bittir. VCC'ye bağlanırsa, lojik bir olarak okunur ve bağımlı adres değişir.

XCL: Yardımcı Seri Saat pimi. Bu pin, diğer I2C arayüzü etkin sensörlerin SCL pinini MPU-6050'ye bağlamak için kullanılır.

XDA: Yardımcı Seri Veri pini. Bu pin, diğer I2C arayüzü etkin sensörlerin SDA pinini MPU-6050'ye bağlamak için kullanılır.

SCL: Seri Saat pimi. Bu pini mikrodenetleyicilerin SCL pinine bağlayın. SDA: Seri Veri pini. Bu pini mikrodenetleyicilerin SDA pinine bağlayın.

GND: Topraklama pimi. Bu pimi toprak bağlantısına bağlayın.

VCC: Güç kaynağı pimi. Bu pimi +5V DC kaynağına bağlayın. MPU-6050 modülü Slave adresine sahiptir (AD0 = 0 iken yani Vcc'ye bağlı değilken), Slave Yazma adresi(SLA+W): 0xD0

Bağımlı Okuma adresi(SLA+R): 0xD1

2. Adım: Hesaplamalar

hesaplamalar
hesaplamalar

MPU6050 modülünün Jiroskop ve İvmeölçer sensör verileri, 2'li tamamlayıcı formda 16 bitlik ham verilerden oluşmaktadır.

MPU6050 modülünün sıcaklık sensörü verileri, 16 bitlik verilerden oluşur (2'nin tamamlayıcı formunda değil).

Şimdi seçtiğimizi varsayalım,

  • - 16, 384 LSB(Sayı)/g Duyarlılık Ölçek Faktörü ile +/- 2g ivmeölçer tam ölçek aralığı.
  • - 131 LSB (Sayı)/°/s'lik Hassasiyet Ölçek Faktörü ile +/- 250 °/s'lik jiroskop tam ölçek aralığı. sonra,

Sensör ham verilerini elde etmek için, önce İvmeölçer ve jiroskopun sensör verileri üzerinde 2'nin tamamlayıcısını yapmamız gerekiyor. Sensör ham verilerini aldıktan sonra, sensör ham verilerini hassasiyet ölçek faktörlerine bölerek ivme ve açısal hızı aşağıdaki gibi hesaplayabiliriz:

g (g kuvveti) cinsinden ivmeölçer değerleri

  • X ekseni boyunca ivme = (İvmeölçer X ekseni ham verisi/16384) g.
  • Y ekseni boyunca hızlanma = (İvmeölçer Y ekseni ham verisi/16384) g.
  • Z ekseni boyunca ivme = (İvmeölçer Z ekseni ham verisi/16384) g.

°/s (derece/saniye) cinsinden jiroskop değerleri

  • X ekseni boyunca açısal hız = (Jiroskop X ekseni ham verisi/131) °/s.
  • Y ekseni boyunca açısal hız = (Jiroskop Y ekseni ham verisi/131) °/s.
  • Z ekseni boyunca açısal hız = (Jiroskop Z ekseni ham verisi/131) °/s.

°/c cinsinden sıcaklık değeri (Santigrat derece)

Derece cinsinden sıcaklık = ((sıcaklık sensörü verileri)/340 + 36,53 °/c.

Örneğin, Diyelim ki, 2' tamamlayıcıdan sonra ivmeölçer X ekseni ham değeri = +15454 olsun

O zaman Ax = +15454/16384 = 0.94 gr.

Daha,

+/-2G ve +/- 250deg/s hassasiyette çalıştığımızı biliyoruz, ancak değerlerimiz bu ivmelere/açılara nasıl karşılık geliyor.

Bunların ikisi de düz çizgi grafiklerdir ve onlardan 1G için 16384 okuyacağımızı ve 1 derece/sn için 131.07 okuyacağımızı çıkarabiliriz (.07 ikili nedeniyle göz ardı edilecek olsa da) bu değerler sadece çizerek elde edildi. 32767'de 2G ve -32768'de -2G ve aynı değerlerde 250/-250 ile düz çizgi grafiği.

Artık hassasiyet değerlerimizi (16384 ve 131.07) biliyoruz, sadece değerlerimizden ofsetleri çıkarmamız ve sonra hassasiyete göre ayırmamız gerekiyor.

Bunlar, X ve Y değerleri için iyi çalışacaktır, ancak Z, 0 değil 1G'de kaydedildiği için, duyarlılığımıza bölmeden önce eksi 1G'yi (16384) çıkarmamız gerekecek.

Adım 3: MPU6050-Atmega328p Bağlantıları

MPU6050-Atmega328p Bağlantıları
MPU6050-Atmega328p Bağlantıları
MPU6050-Atmega328p Bağlantıları
MPU6050-Atmega328p Bağlantıları
MPU6050-Atmega328p Bağlantıları
MPU6050-Atmega328p Bağlantıları

Sadece şemada verilen her şeyi bağlayın…

Bağlantılar şu şekilde verilmiştir: -

MPU6050 Arduino Nano

VCC 5v çıkış pimi

GND Topraklama pimi

SDA A4 pin // seri veri

SCL A5 pin // seri saat

Eğim ve Yuvarlanma Hesaplaması: Yuvarlanma, x ekseni etrafındaki dönüş ve adım, y ekseni etrafındaki dönüştür.

Sonuç radyan cinsindendir. (180 ile çarpıp pi ile bölerek dereceye dönüştürün)

4. Adım: Kodlar ve Açıklamalar

Kodlar ve Açıklamalar
Kodlar ve Açıklamalar

/*

Arduino ve MPU6050 İvmeölçer ve Jiroskop Sensör Eğitimi, Dejan, https://howtomechatronics.com */ #include const int MPU = 0x68; // MPU6050 I2C adresi kayan nokta AccX, AccY, AccZ; float GyroX, GyroY, GyroZ; float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ; şamandıra rulosu, eğim, sapma; float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ; float elapsedTime, currentTime, öncekiTime; int c = 0; geçersiz kurulum() { Serial.begin(19200); Wire.begin(); // Haberleşmeyi başlat Wire.beginTransmission(MPU); // MPU6050 ile iletişimi başlat // MPU=0x68 Wire.write(0x6B); // Register ile konuşun 6B Wire.write(0x00); // Sıfırla - 6B kaydına bir 0 yerleştirin Wire.endTransmission(true); //iletiyi sonlandır /* // İvmeölçer Hassasiyetini Yapılandır - Tam Ölçek Aralığı (varsayılan +/- 2g) Wire.beginTransmission(MPU); Wire.write(0x1C); //ACCEL_CONFIG kaydıyla (1C hex) konuşun Wire.write(0x10); //Kayıt bitlerini 00010000 (+/- 8g tam ölçek aralığı) olarak ayarlayın Wire.endTransmission(true); // Gyro Hassasiyetini Yapılandır - Tam Ölçek Aralığı (varsayılan +/- 250deg/s) Wire.beginTransmission(MPU); Wire.write(0x1B); // GYRO_CONFIG kaydı ile konuşun (1B hex) Wire.write(0x10); // Kayıt bitlerini 00010000 (1000deg/s tam ölçek) olarak ayarlayın Wire.endTransmission(true); gecikme(20); */ // Modülünüz için IMU hata değerlerini almanız gerekiyorsa bu işlevi çağırın hesapla_IMU_error(); gecikme(20); } void loop() { // === Hızlandırıcı verilerini oku === // Wire.beginTransmission(MPU); Wire.write(0x3B); // register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false) ile başlayın; Wire.requestFrom(MPU, 6, doğru); // Toplam 6 kaydı oku, her eksen değeri 2 kayıtta saklanır // +-2g aralığı için, AccX = (Wire.read() << 8 veri sayfasına göre ham değerleri 16384'e bölmemiz gerekir) | Wire.read()) / 16384.0; // X ekseni değeri AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y ekseni değeri AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z ekseni değeri // İvmeölçer verilerinden Roll ve Pitch hesaplama accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0,58; // AccErrorX ~(0.58) Daha fazla ayrıntı için hesaplama_IMU_error()özel işlevine bakın accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58) // === Jiroskop verilerini oku === // öncekiTime = currentTime; // Önceki zaman, okunan gerçek zamandan önce saklanır currentTime = millis(); // Geçerli zaman gerçek zaman okuma elapsedTime = (currentTime - öncekiTime) / 1000; // 1000'e bölerek saniyeyi elde edin Wire.beginTransmission(MPU); Wire.write(0x43); // Gyro verileri ilk kayıt adresi 0x43 Wire.endTransmission(false); Wire.requestFrom(MPU, 6, doğru); // Toplam 4 kayıt oku, her eksen değeri 2 kayıtta saklanır GyroX = (Wire.read() << 8 | Wire.read()) / 131.0; // 250deg/s aralığı için önce ham değeri 131.0'a bölmemiz gerekiyor, veri sayfasına göre GyroY = (Wire.read() << 8 | Wire.read()) / 131.0; GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0; // Çıktıları hesaplanan hata değerleriyle düzeltin GyroX = GyroX + 0,56; // GyroErrorX ~(-0.56) GyroY = GyroY - 2; // GyroErrorY ~(2) GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8) // Şu anda ham değerler derece/saniye, derece/s cinsindendir, bu nedenle açıyı derece cinsinden elde etmek için gönderiler (s) ile çarpmamız gerekir gyroAngleX = gyroAngleX + GyroX * elapsedTime; // derece/s * s = derece gyroAngleY = gyroAngleY + GyroY * geçen Zaman; sapma = sapma + GyroZ * geçenZaman; // Tamamlayıcı filtre - ivmeölçer ve cayro açısı değerlerini birleştirir roll = 0.96 * gyroAngleX + 0.04 * accAngleX; adım = 0.96 * gyroAngleY + 0.04 * acAngleY; // Değerleri seri monitöre yazdırın Serial.print(roll); Seri.print("/"); Seri.baskı(aralık); Seri.print("/"); Serial.println(yaw); } void hesapla_IMU_error() { // İvmeölçer ve gyro data hatasını hesaplamak için setup kısmında bu fonksiyonu çağırabiliriz. Buradan Seri Monitörde basılan yukarıdaki denklemlerde kullanılan hata değerlerini alacağız. // Doğru değerleri alabilmek için IMU'yu düz yerleştirmemiz gerektiğini unutmayın, böylece doğru değerleri alabiliriz // İvmeölçer değerlerini 200 kez okuyun while (c < 200) { Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(yanlış); Wire.requestFrom(MPU, 6, doğru); AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Tüm okumaların toplamı 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++; } //Hata değerini almak için toplamı 200'e bölün AccErrorX = AccErrorX / 200; AccErrorY = AccErrorY / 200; c = 0; // Gyro değerlerini 200 kez oku while (c < 200) { Wire.beginTransmission(MPU); Wire.write(0x43); Wire.endTransmission(yanlış); Wire.requestFrom(MPU, 6, doğru); GyroX = Wire.read() << 8 | Tel.read(); GyroY = Wire.read() << 8 | Tel.read(); GyroZ = Wire.read() << 8 | Tel.read(); // Tüm okumaları toplayın GyroErrorX = GyroErrorX + (GyroX / 131.0); GyroErrorY = GyroErrorY + (GyroY / 131.0); GyroErrorZ = GyroErrorZ + (GyroZ / 131.0); c++; } //GyroErrorX = GyroErrorX / 200; GyroErrorY = GyroErrorY / 200; GyroErrorZ = GyroErrorZ / 200; // Hata değerlerini Seri Monitöre yazdırın Serial.print("AccErrorX: "); Serial.println(AccErrorX); Serial.print("Hata: "); Serial.println(AcErrorY); Serial.print("GyroErrorX: "); Serial.println(GyroErrorX); Serial.print("GyroErrorY: "); Serial.println(GyroErrorY); Serial.print("GyroErrorZ: "); Serial.println(GyroErrorZ); } ------------------------------------------------- ---------------------------------------------- Sonuçlar:- X = Y = Z = --------------------------------------------- ----------------------------------------------- Önemli Not: -----------------

Döngü bölümünde ivmeölçer verilerini okuyarak başlıyoruz. Her eksen için veriler 2 bayt veya kayıtlarda saklanır ve bu kayıtların adreslerini sensörün veri sayfasından görebiliriz.

Hepsini okumak için ilk kayıtla başlıyoruz ve requiestFrom() işlevini kullanarak X, Y ve Z eksenleri için 6 kaydın tümünü okumamızı istiyoruz. Daha sonra her kayıttan verileri okuruz ve çıktılar ikinin tümleyeni olduğundan, doğru değerleri elde etmek için bunları uygun şekilde birleştiririz.

Adım 5: Eğim Açısını Anlama

ivmeölçer

Dünyanın yerçekimi, kuvvetin her zaman Dünya'nın merkezine doğru baktığı sabit bir ivmedir.

İvmeölçer yerçekimine paralel olduğunda ölçülen ivme 1G, ivmeölçer yerçekimine dik olduğunda 0G ölçecektir.

Eğim açısı, bu denklem kullanılarak ölçülen ivmeden hesaplanabilir:

θ = sin-1 (Ölçülen İvme / Yerçekimi İvmesi)

GyroGyro (a.k.a. hız sensörü) açısal hızı (ω) ölçmek için kullanılır.

Bir robotun eğim açısını elde etmek için jiroskoptan gelen verileri aşağıdaki denklemde gösterildiği gibi entegre etmemiz gerekir:

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

Gyro ve İvmeölçer Sensör FüzyonuHem jiro hem de ivmeölçerin özelliklerini inceledikten sonra, onların kendi güçlü ve zayıf yönleri olduğunu biliyoruz. İvmeölçer verilerinden hesaplanan eğim açısı yavaş tepki süresine sahipken, jiroskop verilerinden entegre eğim açısı bir süre boyunca kaymaya maruz kalır. Başka bir deyişle, ivmeölçer verilerinin uzun vadede faydalı olduğunu, gyro verilerinin ise kısa vadede faydalı olduğunu söyleyebiliriz.

Daha iyi anlamak için bağlantı: Buraya Tıklayın

Önerilen: