18F4550 ve MPU-6050 ile haberleşmede takılıyor

Başlatan Cemre., 27 Kasım 2015, 00:36:52

Cemre.

Herkese iyi geceler.

Elimde çalıştığından emin olduğum bir adet mpu-6050 acc., gyro. 6DOF sensör mevcut.
MikroC kütüphane örneğinden yola çıkarak bir kod yazmaya çalıştım ancak sensörün adresini gönderip register adresini yazmaya çalıştığım satırda takılı kalıyor program. Bunu da her satıra LCD'de # simgesi ekleterek gördüm, kodu incelerseniz söylemek istediğimi anlayacaksınızdır.

// Durum LED'leri
#define LED1 LATE.B0
#define LED2 LATE.B1
#define LED3 LATE.B2

unsigned int temp;
char txt1[] = "                ";

// LCD bağlantıları tanımlanıyor
sbit LCD_RS at  LATD.B4;
sbit LCD_EN at  LATD.B5;
sbit LCD_D4 at  LATD.B0;
sbit LCD_D5 at  LATD.B1;
sbit LCD_D6 at  LATD.B2;
sbit LCD_D7 at  LATD.B3;

sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
// LCD bağlantıları tanımlandı
void init_mcu(){
     ADCON1     = 0x1F;                          // Analog özellikli tüm pinler Dijital G/Ç yapıldı.
     CMCON      = 0x07;                          // Karşılaştırıcılar kapatıldı.
     PORTB      = 0x00;
     TRISB      = 0x00;
     TRISE      = 0x00;                          // PORTE çıkış yapıldı.
}
void main() {
     init_mcu();
     LED1 = 1;
     Lcd_Init();                         // LCD Kurulumu
     Lcd_Cmd(_LCD_CLEAR);                // Ekranı Temizle
     Lcd_Cmd(_LCD_CURSOR_OFF);           // İmleç Kapalı
     LED2 = 1;
     I2C1_Init(400000);
     Lcd_Out(1,1,"START");
     Lcd_Cmd(_LCD_SECOND_ROW);
     Lcd_Out_CP("#");
     if (I2C1_Is_Idle()) {
                         I2C1_Start();
                         Lcd_Out_CP("#");
                         while(!I2C1_Is_Idle());
                         Lcd_Out_CP("#");
                         I2C1_Wr(0x68);
                         Lcd_Out_CP("#");
                         while(!I2C1_Is_Idle());
                         Lcd_Out_CP("#");
                         I2C1_Wr(0x6B);
                         Lcd_Out_CP("#");
                         while(!I2C1_Is_Idle());
                         Lcd_Out_CP("#");
                         I2C1_Wr(0x00);
                         Lcd_Out_CP("#");
                         while(!I2C1_Is_Idle());
                         Lcd_Out_CP("#");
                         I2C1_Stop();
                         Lcd_Out_CP("#");
     }else{
           Lcd_Out(1,1,"busy   ");
     }
     Lcd_Out(1,1,"#1 OK!          ");
     Delay_ms(100);
     if (I2C1_Is_Idle()) {
                         I2C1_Start();
                         while(!I2C1_Is_Idle());
                         I2C1_Wr(0x68);
                         while(!I2C1_Is_Idle());
                         I2C1_Wr(0x75);
                         while(!I2C1_Is_Idle());
                         I2C1_Repeated_Start();
                         while(!I2C1_Is_Idle());
                         I2C1_Wr(0x68);
                         while(!I2C1_Is_Idle());
                         temp = I2C1_Rd(0u);
                         while(!I2C1_Is_Idle());
                         I2C1_Stop();
     }else{
           Lcd_Out(1,1,"busy   ");
     }
     Lcd_Out(1,1,"#2 OK!          ");
     Delay_ms(100);
     IntToStr(temp,txt1);
     Lcd_Out(1,1,txt1);
}


SDA SCL pinlerine 4k7R ile pull-up yaparak ve pull-up olmadan her iki şekilde denedim. @selimkoc hocamın yaptığı deneme kartıyla çalışıyorum, şemasının linki aşağıda. Onun dışında standart bağlantı. Deneme kartı tarafında RB0'a pull-up ile buton bağlı, problem oluşturur mu bilmiyorum.

PIC'i enerjilendirdiğimde LCD'nin ikinci satırında toplam 5 adet # işareti görüyorum, buradan hangi satırda takılı kaldığını anlıyorum.
Neyi yanlış yapıyorum sizce?


Cemre.

#2
Bugün biraz daha uğraştım ve aslında modülle iletişim kuramadığımı farkettim. Bunu

void check_device(unsigned short dev_address){
 I2C1_Start();
 if (I2C1_Wr(dev_address)){
  Lcd_Out(2,1,"Device not found");
 }
 else Lcd_Out(2,1,"Device is OK");
 I2C1_Stop();
}


böyle bir fonksiyonla anlıyorum. Ne yaptıysam OK cevabı döndüremedim. Sorunun kaynağı ne olabilir?
MPU6050 arduino ile 5V seviyesinde haberleşebiliyor. Ancak modül 3.3V ile çalışmaya uygun, acaba sorunum bu olabilir mi?

Edit: Tabi ki iletişim hattımdaki gerilim seviyesi farklılığından dolayı bu problemi yaşıyordum. Aşağıdaki dönüştürücü devreyi kurmaya üşendiğimden tam bir gün kaybettim. Ben yandım eller yanmasın :(

http://forums.parallax.com/discussion/download/55613/3.3V%20to%205V.JPG

Gökhan BEKEN

Mpu6050 bozulmuş olabilir. Hatta bozulmamışsa iyi dayanmış diyebliriz. :)
Özel mesaj okumuyorum, lütfen göndermeyin.

Cemre.

Yok hocam bozulmamış, zaten üzerinde 3v3 LDO varmış, ben hiç incelemediğimden, daha doğrusu arduinoda problem yaşamadığımdan modülü 5v sanıyordum :D

koray692

mpu6050 default ayarları uyku konumunda geliyor sensoru uyandırmanız gerekiyor :) register map te hangi registera hangi degeri göndermeniz gerektiği yazıyor..iyi çalışmalar kolay gelsin hat çok uzun olmadığı sürece dirençsizde çalışabiliyor diye biliyorum.Can haberleşmede dirençleri tez hocam sökmüştü bak çalışıyor anlat bakalım neden çalışıyor demişti :) geçen i2c deki direnleride çektim çalışıyordu :)

erdtur

Merhaba , ben 16F628 ile aşağıdaki kodu kullanarak haberleştirmiştim.
device adresi, 7 bit 0x68 olacak şekilde düşün, 8 bitlik registere yerleştirdiğinde 0xD0 oluyor.
Değer okuyabilmek için  0x6B registerindeki reset bitini aktif edip, 1 saniye bekledikten sonra, cycle bitini aktif ederek sensörü çalışır hale getiriyorsun. sonrada registerlerden dataları okuyorsun. Aşağıda örnek olsun diye  accelerometer datalarının bulunduğu 0x3B,0x3D,0x3F registerlerinden okuma komutlarını verdim. Register map dökümanına bakarak diğer datalarıda okuyabilirsin.   


'AD0=0 ADDRESS B`1101000X`,$68
'AD0=1 ADDRESS B`1101001X`,$69

I2CWRITE DPIN,CPIN,$D0,$6B,[%10000000]  ' 'RESITER 6B CONFIG (PWR MANAGEMENT)
pause 1000
I2CWRITE DPIN,CPIN,$D0,$6B,[%00100000]  ' 'RESITER 6B CONFIG (PWR MANAGEMENT)
pause 100
I2CWRITE DPIN,CPIN,$D0,$6B,[%00100000]  ' 'RESITER 6B CONFIG (PWR MANAGEMENT)
pause 100
I2CWRITE DPIN,CPIN,$D0,$6C,[%00000000]  ' 'RESITER 6C CONFIG (PWR MANAGEMENT)
PAUSE 100
I2CWRITE DPIN,CPIN,$D0,$1A,[%00000000]  ' 'RESITER 1A CONFIG (FILTER CONFIG)
pause 100
I2CWRITE DPIN,CPIN,$D0,$1B,[%00000000]  ' 'RESITER 1B CONFIG (GYRO CONFIG)
pause 100
I2CWRITE DPIN,CPIN,$D0,$1C,[%00000000]  ' 'RESITER 1C CONFIG (ACC CONFIG)
pause 100




Mainloop:


OKU:

I2CREAD DPIN, CPIN,$D0,$3B,[DEGER]  '
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
ACCX=DEGER+1
ISARET_AX=11
ELSE
ACCX=DEGER
ISARET_AX=10
ENDIF

I2CREAD DPIN, CPIN,$D0,$3D,[DEGER]'
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
ACCY=DEGER+1
ISARET_AY=11
ELSE
ACCY=DEGER
ISARET_AY=10
ENDIF

I2CREAD DPIN, CPIN,$D0,$3F,[DEGER]  '
IF DEGER.15 = 1 THEN
DEGER.15=0
DEGER=32767-DEGER
ACCZ=DEGER+1
ISARET_AZ=11
ELSE
ACCZ=DEGER
ISARET_AZ=10
ENDIF


kolaygelsin
Erdtur

Cemre.

Cevabınız için teşekkürler, bu sorunu halletmiştim ancak cevap olarak çözümü yazmayı unutmuşum. Şimdi de hatırlayamadım malesef.

Kolay gelsin, iyi akşamlar.