MPU6050 İvme ve Gyro Sensör Uygulaması
Merhaba arkadaşlar, bu yazımızda Trudyo Geliştirme Kartı ile MPU6050 İvme ve Gyro Sensörü kullanımından bahsedeceğiz. Ayrıca uygulamamızda verileri bir mobil uygulamaya göndermek için HC-06 Bluetooth Modülü kullanacağız. Uygulamaya ait gerekli malzeme ve kütüphane dosyalarını sizin için derlediğimiz bu yazımız öncelikle MPU6050 İvme ve Gyro Sensörü hakkında kısa bir bilgi edinerek başlayabiliriz.
MPU6050 İvme ve Gyro Sensörü Modülü Hakkında Kısa Bir Bilgi
MPU6050 Modülü, dahili 3 eksenli ivmeölçer ve 3 gyroskop (gyro) sensörü içeren 6 eksenli bir modüldür. Bu modül ile, herhangi bir cihazın 6 serbestlik derecesinde (6 DOF – Degrees of Freedom) hareket etmesini ölçebilirsiniz.
İçerdiği ivmeölçer sensörü sayesinde, bir cihazın ivmelenmesini ölçer. Yatay, dikey veya eğik hareketlerini algılar. Ayrıca, hızlanma durumunu belirlemeye yardımcı olur.
İçerdiği Gyroskop (Gyro) sensörü sayesinde, cihazın dönme hızını ve dönme yönünü ölçer. Yani, bir cihazın ne kadar hızlı döndüğünü ve hangi yöne döndüğünü belirlemeye yardımcı olur.
MPU6050 Modülü, drone kontrolünde, giyilebilir teknolojilerde, robotik uygulamalarda ve diğer birçok elektronik alanda kullanılmaktadır. Çeşitli mikrodenetleyici platformlarıyla kolayca entegre edilebilmektedir.
Pin No | İsim | Açıklama |
1 | VCC | +3.3V Bağlantı Pini |
2 | GND | GND Bağlantı Pini |
3 | SCL | I2C Seri Clock Bağlantı Pini |
4 | SDA | I2C Seri Data Bağlantı Pini |
5 | XDA | Yardımcı Seri Data Bağlantı Pini |
6 | XCL | Yardımcı Seri Clock Bağlantı Pini |
7 | AD0 | Cihaz Adres Değiştirme Pini |
8 | INT | Kesme Pini |
MPU6050, HC-06 ve Trudyo Geliştirme Kartı Bağlantısı
Yukarıdaki görsellerde açıkladığı üzere MPU6050 İvme ve Gyro Sensörü Trudyo Geliştirme Kartı‘nın B0 ve B1 pinlerine (I2C) bağlanmıştır. Ayrıca HC-06 Bluetooth Modülü ise C6 ve C7 pinlerine (UART) bağlanmıştır.
Bu Uygulamada Kullanılan Malzemeler
Trudyo Geliştirme Kartı
400 Pin Orta Boy Breadboard
HC-06 Bluetooth Modül
MPU6050 6 Eksen İvme ve Gyro Sensörü Modülü
Başlamadan Önce
HC-06 AT Komutları
HC-06 Bluetooth Modülü kullanımı hakkında ayrıntılı bilgi ve örnek uygulamayı incelemek için daha önce yayınlanan “HC-06 AT Komutları” yazımızı okuyabilirsiniz. Ayrıca dilerseniz modülünüzün adını, şifresini, iletişim bilgilerini ve daha fazlasını da ayarlayabilirsiniz.
Trudyo Konfigürasyon Ayarları
Trudyo Geliştirme Kartı ile programlama yapabilmek için kartınızın konfigürasyon ayarlarını yapmanız gerekmektedir. Gerekli konfigürasyon ayarlarını yapmak için “Trudyo Konfigürasyon Ayarları” yazımızı okuyabilirsiniz.
MPU6050 İvme ve Gyro Sensörü Uygulama Kodları
#include "MPU6050.c" // MPU6050 Kütüphanesi
// Baglantilar
sbit LED at LATA4_bit; // Dahili LED RA4 Pinine Bagli
// Global Degiskeler
int accelX, accelY, accelZ, temp, gyroX, gyroY, gyroZ;
// HC-06 bluetooth modülüne Veri gönderme fonksiyonu
void SendHC06(int value){
char txt[7]; // IntToStr fonksiyonu için txt dizisi
IntToStr(value,txt); // value degerini stringe cevir ve txt dizisine yaz
UART_Write_Text(txt); // txt dizisini uart üzerinden gönder
UART_Write_Text(" "); // Bosluk karakteri gönder
}
void main() {
// Port Giris-Çikis Seçimi (0:Çikis, 1:Giris)
TRISA=0b00000000; // [][][][LED][][][][]
TRISB=0b00000000; // [][][][][][][SCK][SDA]
TRISC=0b10000000; // [RX][TX][][][][][][]
TRISD=0b00000000; // [][][][][][][][]
TRISE=0b00000000; // [][][][][][][][]
// Port Analog-Dijital Giris Seçimi (0:Dijital, 1:Analog)
ANSELA=0b00000000; // [][][][][][][][]
ANSELB=0b00000000; // [][][][][][][][]
ANSELC=0b00000000; // [][][][][][][][]
ANSELD=0b00000000; // [][][][][][][][]
ANSELE=0b00000000; // [][][][][][][][]
// Port Temizleme
LATA=0x00;
LATB=0x00;
LATC=0x00;
LATD=0x00;
LATE=0x00;
UART1_Init(9600);
// I2C Hazirlama
I2C1_Init(400000); // MPU6050 kütüphanesi dahili I2C donanimi ile çalismaktadir.
MPU6050_Init(); // MPU6050 hazirlama
// Kalibrasyon
MPU6050_Read(&accelX, &accelY, &accelZ, &temp, &gyroX, &gyroY, &gyroZ); // Sensör verilerini oku
MPU6050_SetOffset(accelX,accelY,accelZ,gyroX,gyroY,gyroZ); // Okunan degerleri offset degerleri ile güncelle
// Sonsuz Dongu
while(1){
delay_ms(100); // 100ms bekleme
MPU6050_Read(&accelX, &accelY, &accelZ, &temp, &gyroX, &gyroY, &gyroZ); // Sensör verilerini oku
SendHC06(accelX); // X ekseni accel verisini gönder
SendHC06(accelY); // Y ekseni accel verisini gönder
SendHC06(temp); // Sicaklik verisini gönder
SendHC06(gyroX); // X ekseni gyro verisini gönder
SendHC06(gyroY); // Y ekseni gyro verisini gönder
SendHC06(gyroZ); // Z ekseni gyro verisini gönder
UART_Write_Text("\r\n"); // CRLF karakterlerini göndererek veri gönderimini tamamla
LED=!LED; // LED durumunu tersle
}
}
MPU6050 Kütüphane Kodları
// MPU6050 Register Map
#define XG_OFFS_TC 0x00
#define YG_OFFS_TC 0x01
#define ZG_OFFS_TC 0x02
#define X_FINE_GAIN 0x03
#define Y_FINE_GAIN 0x04
#define Z_FINE_GAIN 0x05
#define XA_OFFS_H 0x06
#define XA_OFFS_L_TC 0x07
#define YA_OFFS_H 0x08
#define YA_OFFS_L_TC 0x09
#define ZA_OFFS_H 0x0A
#define ZA_OFFS_L_TC 0x0B
#define XG_OFFS_USRH 0x13
#define XG_OFFS_USRL 0x14
#define YG_OFFS_USRH 0x15
#define YG_OFFS_USRL 0x16
#define ZG_OFFS_USRH 0x17
#define ZG_OFFS_USRL 0x18
#define SMPLRT_DIV 0x19
#define CONFIG 0x1A
#define GYRO_CONFIG 0x1B
#define ACCEL_CONFIG 0x1C
#define FF_THR 0x1D
#define FF_DUR 0x1E
#define MOT_THR 0x1F
#define MOT_DUR 0x20
#define ZRMOT_THR 0x21
#define ZRMOT_DUR 0x22
#define FIFO_EN 0x23
#define I2C_MST_CTRL 0x24
#define I2C_SLV0_ADDR 0x25
#define I2C_SLV0_REG 0x26
#define I2C_SLV0_CTRL 0x27
#define I2C_SLV1_ADDR 0x28
#define I2C_SLV1_REG 0x29
#define I2C_SLV1_CTRL 0x2A
#define I2C_SLV2_ADDR 0x2B
#define I2C_SLV2_REG 0x2C
#define I2C_SLV2_CTRL 0x2D
#define I2C_SLV3_ADDR 0x2E
#define I2C_SLV3_REG 0x2F
#define I2C_SLV3_CTRL 0x30
#define I2C_SLV4_ADDR 0x31
#define I2C_SLV4_REG 0x32
#define I2C_SLV4_DO 0x33
#define I2C_SLV4_CTRL 0x34
#define I2C_SLV4_DI 0x35
#define I2C_MST_STATUS 0x36
#define INT_PIN_CFG 0x37
#define INT_ENABLE 0x38
#define DMP_INT_STATUS 0x39
#define INT_STATUS 0x3A
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define EXT_SENS_DATA_00 0x49
#define EXT_SENS_DATA_01 0x4A
#define EXT_SENS_DATA_02 0x4B
#define EXT_SENS_DATA_03 0x4C
#define EXT_SENS_DATA_04 0x4D
#define EXT_SENS_DATA_05 0x4E
#define EXT_SENS_DATA_06 0x4F
#define EXT_SENS_DATA_07 0x50
#define EXT_SENS_DATA_08 0x51
#define EXT_SENS_DATA_09 0x52
#define EXT_SENS_DATA_10 0x53
#define EXT_SENS_DATA_11 0x54
#define EXT_SENS_DATA_12 0x55
#define EXT_SENS_DATA_13 0x56
#define EXT_SENS_DATA_14 0x57
#define EXT_SENS_DATA_15 0x58
#define EXT_SENS_DATA_16 0x59
#define EXT_SENS_DATA_17 0x5A
#define EXT_SENS_DATA_18 0x5B
#define EXT_SENS_DATA_19 0x5C
#define EXT_SENS_DATA_20 0x5D
#define EXT_SENS_DATA_21 0x5E
#define EXT_SENS_DATA_22 0x5F
#define EXT_SENS_DATA_23 0x60
#define MOT_DETECT_STATUS 0x61
#define I2C_SLV0_DO 0x63
#define I2C_SLV1_DO 0x64
#define I2C_SLV2_DO 0x65
#define I2C_SLV3_DO 0x66
#define I2C_MST_DELAY_CTRL 0x67
#define SIGNAL_PATH_RESET 0x68
#define MOT_DETECT_CTRL 0x69
#define USER_CTRL 0x6A
#define PWR_MGMT_1 0x6B
#define PWR_MGMT_2 0x6C
#define BANK_SEL 0x6D
#define MEM_START_ADDR 0x6E
#define MEM_R_W 0x6F
#define DMP_CFG_1 0x70
#define DMP_CFG_2 0x71
#define FIFO_COUNTH 0x72
#define FIFO_COUNTL 0x73
#define FIFO_R_W 0x74
#define WHO_AM_I 0x75
// Device Address
unsigned short MPU6050_ADDRESS=0xD0;
// Offset Values
int accelX_Offset=0,accelY_Offset=0,accelZ_Offset=0,gyroX_Offset=0,gyroY_Offset=0,gyroZ_Offset=0;
// MPU6050 Write Data to Selected Data Address
void MPU6050_Write(unsigned short address, unsigned short value){
I2C1_Start(); // Start I2C Communication
I2C1_Wr(MPU6050_ADDRESS); // Send Device Address
I2C1_Wr(address); // Select Register Addres
I2C1_Wr(value); // Write Register Value
I2C1_Stop(); // Stop I2C Communication
}
// MPU6050 Initialize Func.
void MPU6050_Init(){
// Power-up Delay
delay_ms(100);
// Setting The Clock Source
MPU6050_Write(PWR_MGMT_1, 0x00); // Internal 8MHz
// Configure The DLPF
MPU6050_Write(CONFIG, 0x06); // Accelerometer and Gyroscope Bandwidth
// Configure The GYRO
MPU6050_Write(GYRO_CONFIG, 0x18); // FS_SEL=±2000°/s
// Configure The ACCEL
MPU6050_Write(ACCEL_CONFIG, 0x18); // AFS_SEL=±2g
}
// MPU6050 Offset Func.
void MPU6050_SetOffset(int accelX, int accelY, int accelZ, int gyroX, int gyroY, int gyroZ){
accelX_Offset=accelX;
accelY_Offset=accelY;
accelZ_Offset=accelZ;
gyroX_Offset=gyroX;
gyroY_Offset=gyroY;
gyroZ_Offset=gyroZ;
}
// MPU6050 Read Func.
void MPU6050_Read(int *accelX, int *accelY, int *accelZ, int *temp, int *gyroX, int *gyroY, int *gyroZ){
// Prepare For Reading, Starting From ACCEL_XOUT_H
I2C1_Start(); // Start I2C Communication
I2C1_Wr(MPU6050_ADDRESS); // Send Device Address
I2C1_Wr(ACCEL_XOUT_H); // Select ACCEL_XOUT_H Register Addres
I2C1_Stop(); // Stop I2C Communication
I2C1_Start(); // Start I2C Communication
I2C1_Wr(MPU6050_ADDRESS+1); // Ready to Read
*accelX = (I2C1_Rd(1)<<8) | I2C1_Rd(1); // Read accelX Data
*accelY = (I2C1_Rd(1)<<8) | I2C1_Rd(1); // Read accelY Data
*accelZ = (I2C1_Rd(1)<<8) | I2C1_Rd(1); // Read accelZ Data
*temp = (I2C1_Rd(1)<<8) | I2C1_Rd(1); // Read temp Data
*gyroX = (I2C1_Rd(1)<<8) | I2C1_Rd(1); // Read gyroX Data
*gyroY = (I2C1_Rd(1)<<8) | I2C1_Rd(1); // Read gyroY Data
*gyroZ = (I2C1_Rd(1)<<8) | I2C1_Rd(0); // Read gyroZ Data
I2C1_Stop(); // Stop I2C Communication
*accelX-=accelX_Offset; // Decrease accelX_Offset
*accelY-=accelY_Offset; // Decrease accelY_Offset
*accelZ-=accelZ_Offset; // Decrease accelZ_Offset
*temp = (*temp/340)+36; // Convert Temperature °C
*gyroX-=gyroX_Offset; // Decrease gyroX_Offset
*gyroY-=gyroY_Offset; // Decrease gyroY_Offset
*gyroZ-=gyroZ_Offset; // Decrease gyroZ_Offset
}
Uygulamaya ait dosyaları buraya tıklayarak indirebilirsiniz. Merak ettiğiniz ve aklınıza takılan soruları aşağıda 👇 yorum olarak bize iletebilirsiniz. İyi çalışmalar. 🙂 #geliştirmeyebaşla
5 thoughts on “MPU6050 İvme ve Gyro Sensör Uygulaması”
Ben Trudyo ile gy-neo6mv2 gps modülü kullanarak konum bilgilerini LCD ekrana yazdırmak istiyorum.Birçok kod yazdım ama başaramadım.Yardımcı olursanız çok sevinirim.
Merhaba, modülü incelediğimde aslında modülün sürekli olarak veri gönderdiğini ve herhangi bir istekte bulunmanın gerekli olmadığını farkettim. Örnek vermek gerekirse periyodik olarak aşağıdaki gibi veriler gelmekte;
// Örnek Datalar
//$GPGGA,110617.00,41XX.XXXXX,N,00831.54761,W,1,05,2.68,129.0,M,50.1,M,,*42
//$GPGSA,A,3,06,09,30,07,23,,,,,,,,4.43,2.68,3.53*02
//$GPGSV,3,1,11,02,48,298,24,03,05,101,24,05,17,292,20,06,71,227,30*7C
//$GPGSV,3,2,11,07,47,138,33,09,64,044,28,17,01,199,,19,13,214,*7C
//$GPGSV,3,3,11,23,29,054,29,29,01,335,,30,29,167,33*4E
//$GPGLL,41XX.XXXXX,N,00831.54761,W,110617.00,A,A*70
//$GPRMC,110618.00,A,41XX.XXXXX,N,00831.54753,W,0.078,,030118,,,A*6A
//$GPVTG,,T,,M,0.043,N,0.080,K,A*2C
Burada her bir satır bir seferde gelen veri örneklerini göstermekte. Bu verileri daha iyi yorumlamak için ürün datasheet’ini (https://content.u-blox.com/sites/default/files/products/documents/NEO-6_DataSheet_%28GPS.G6-HW-09005%29.pdf) incelemeni öneririm.
Test edebilmen için bir örnek kod bloğu hazırladım. Bu kod bloğunu “HC-06 AT Komutları” uygulamasının (https://trudyo.com/hc-06-at-komutlari/) proje dosyası üzerinde hazırladığımı belirmek isterim. Yazının en alt kısmından ilgili dosyayı indirebilirsin.
Program Kodları:
// Connections
sbit LED at LATA4_bit;
// LCD module connections
sbit LCD_RS at LATD0_bit;
sbit LCD_EN at LATD1_bit;
sbit LCD_D4 at LATD2_bit;
sbit LCD_D5 at LATD3_bit;
sbit LCD_D6 at LATD4_bit;
sbit LCD_D7 at LATD5_bit;
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D7_Direction at TRISD2_bit;
sbit LCD_D6_Direction at TRISD3_bit;
sbit LCD_D5_Direction at TRISD4_bit;
sbit LCD_D4_Direction at TRISD5_bit;
// Global Degisken Tanimlamalari
unsigned short i=0;
unsigned short receivedDataCount=0;
char receivedData[80];
unsigned short dataReceived=0;
void Interrupt(){ // Kesme Fonksiyonu
if(RCIF_bit){ // Eger GPS'den bir veri gelmis ise
receivedData[receivedDataCount]=UART1_Read(); // Gelen veriyi receivedData dizisine yaz.
receivedDataCount++; // Gelen veri sayisini bir arttir
if(receivedData[receivedDataCount]=='\r'){ // Eger \r sembolü gelmis ise
dataReceived=1; // Veri geldi degiskenini 1 yap
receivedDataCount=0; // Gelen verileri en bastan yazmasi için sayaci sifirla
}
RCIF_bit=0; // Kesme bayragini temizle
}
}
void main() {
TRISA=0b00000000;// [][][][LED][][][][]
TRISB=0b00000000;// [][][][][][][][]
TRISC=0b10000000;// [RX][TX][][][][][][]
TRISD=0b00000000;// [][][][][][][][]
TRISE=0b00000000;// [][][][][][][][]
// Tüm portlar dijital I/O olarak secildi
ANSELA=0x00;
ANSELB=0x00;
ANSELC=0x00;
ANSELD=0x00;
ANSELE=0x00;
// Tüm portlar lojik-0 yapildi
LATA=0x00;
LATB=0x00;
LATC=0x00;
LATD=0x00;
LATE=0x00;
UART1_Init(9600); // UART1'i 9600 baud hizinda hazirla
GIE_bit=1; // Global kesmeleri aktif et
PEIE_bit=1; // Çevresel kesmeleri aktif et
RCIE_bit=1; // UART veri alma kesmesini aktif et
Lcd_Init(); // LCD ekrani hazirla
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor'ü kapat
Lcd_Cmd(_LCD_CLEAR); // Ekrani temizle
Lcd_Out(1,1," NEO-6 ");
Lcd_Out(2,1," GPS MODULU ");
delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR);
while(1){
if(dataReceived){
for(i=0;i<16;i++){
Lcd_Chr(1,i+1,receivedData[i]); // Gelen ilk 16 karakter veriyi 1.satira yaz
Lcd_Chr(2,i+1,receivedData[i+16]); // Gelen ikinci 16 karakter veriyi 2.satira yaz
}
dataReceived=0; // gelen yeni verileri almak için sifirla
}
}
}
Burada bulunan program kodlarında receivedData dizisi içerisine gelen veriler yazılmakta ve for döngüsünde ilk 32 karakter veri ekrana yazdırılmaktadır. Eğer bu konuda sorun yaşamaz ve ekrana yazdırma işlemini yapabilirsen yapman gereken asıl iş bu metinsel verileri değişkenlere atayabilmek olacaktır. Mikrodenetleyicili sistemlerde float değerlerin kullanılmasını genel olarak tavsiye etmiyorum. Float değerler program hafızasında çok fazla alan kullanılmasına neden olabiliyor. Örneğin 24.11 değerini ekranda göstermek için ondalıklı kısımdan vazgeçebilir veya değeri 100 ile çarparak int formatına çevirebilirsin. Bu int veriyi ekrana yazdırırken nokta eklemesi yapmak oldukça kolaydır. Bağlantı için GPS modülünün RX pinini C7, TX pinini ise C6'ye bağlayarak test etmelisin.
Örnek uygulama ile test edip sonuçları hakkında bilgi verebilirsen sevinirim. İyi çalışmalar 😊
Verdiğiniz bilgilerden ötürü çok teşekkür ederim. Trudyo bağlantılarını nasıl yapmam gerektiği hakkında da bilgi verirseniz çok sevinirim.
Merhaba. Ben Trudyo ile gy-neo6mv2 gps modülü kullanarak konum bilgilerini bluetooh modülü ile telefon üzerinden görüntülemek istiyorum. Birçok kod yazdım ama başaramadım.Yardımcı olursanız çok sevinirim. Kullandığım bluetooth modülü HC-05.
Merhaba, Uart_Write fonksiyonları ile mobil uygulama veya masaüstü terminal uygulamalarına veri göndermek için genellikle sonlandırıcı CRLF karakterleride gönderilmelidir.
Örnek vermek gerekirse
UART1_Write_Text("Hello World!"); // Hello World! mesajı gönder
UART1_Write_Text("\r\n"); // CRLF karakterlerini gönder
Yorum yapmak için giriş yapmalısınız.