Lojik Seviye Dönüştürücü neden çalışmadı?

Başlatan Cemre., 03 Aralık 2015, 16:31:34

Cemre.

Herkese iyi günler.

Bugün internetten satın aldığım lojik seviye (5V-3.3V çift yönlü) dönüştürücüm geldi. Ancak modülle hiç bir iletişim kuramıyorum

https://www.pololu.com/product/2595

Satın aldığım modül bu. Haberleştiğim modül ise MPU-6050. Pololu sitesinde I2C için kullanılabileceğinden hatta 400kHz seviyelerinden bahsetmiş. Ben şimdilik 100kHz tanımlıyorum ve modülü aşağıdaki fonksiyonla kontrol ediyorum.

Ana döngümde bu fonksiyonu
check_device(0x68); şeklinde çağırdığımda LCD'de Device not found yazısını görüyorum ama neden?

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


Daha önce bu kod ve aynı modül, aynı işlemci, aynı breadboard üzerinde (yani modülün gelmesini beklediğim sıralarda) Device OK yazısını görüyordum, modülün registerlarına yazma işlemi gerçekleştiriyordum, okumada sorun yaşıyordum. Şimdi hiç bir hareket yok, sizce sebebi ne olabilir? Neyi eksik, yanlış yapıyorum?

Teşekkürler, iyi günler.

Ekleme (birkaç gün önceki konu): https://www.picproje.org/index.php/topic,62180.0.html

Kodun tamamı;

//#include "mpu_fs.c"
// Durum LED'leri
#define LED1 LATE.B0
#define LED2 LATE.B1
#define LED3 LATE.B2

#include "register_map.h"

const int mpu_I2C_ADDR = 0x68;
// Variables used
unsigned int raw_data[7];
int gyro_x_temp, gyro_y_temp, gyro_z_temp, accel_x_temp, accel_y_temp, accel_z_temp, temp_raw;
char i, buff, gyro_x_out[15], gyro_y_out[15], gyro_z_out[15], accel_x_out[15], accel_y_out[15], accel_z_out[15], temp_out[15];
float temp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z;
char txt1[]     = "                ";
int lcd_x = 0;
// 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 check_device(unsigned short dev_address){
 I2C1_Start();
 while(I2C1_Wr(dev_address)){
  Lcd_Out(2,1,"Device not found");
  delay_ms(50);
 }
 Lcd_Out(2,1,"Device is OK");
 I2C1_Stop();
}

void MPU_I2C_Write(unsigned char s_addr, unsigned char r_addr, unsigned char len, unsigned char *dat) {
  unsigned int i;
  I2C1_Start();                      // issue I2C start signal
  I2C1_Wr(s_addr & 0xFE);            // send byte via I2C  (device address + W(&0xFE))
  I2C1_Wr(r_addr);                   // send byte (address of EEPROM location)
  for (i = 0 ; i < len ; i++){
    I2C1_Wr(*dat++);                 // send data (data to be written)
  }
  I2C1_Stop();                       // issue I2C stop signal
  lcd_x += 1;
}

void MPU_I2C_Read(unsigned char s_addr, unsigned char r_addr, unsigned char len, unsigned char *dat) {
  unsigned int i;
  I2C1_Start();                      // issue I2C start signal
  I2C1_Wr(s_addr & 0xFE);            // send byte via I2C  (device address + W(&0xFE))
  I2C1_Wr(r_addr);                   // send byte (data address)
  I2C1_Repeated_Start();             // issue I2C signal repeated start
  I2C1_Wr(s_addr | 0x01);            // send byte (device address + R(|0x01))
  for (i = 0; i < (len-1); i++){
    *dat++ = I2C1_Rd(_I2C_ACK);      // Read the data (acknowledge)
  }
  *dat = I2C1_Rd(_I2C_NACK);         // Read the data (NO acknowledge)
  I2C1_Stop();                       // issue I2C stop signal
  lcd_x += 1;
}

void init_mpu(){
  MPU_I2C_Write(mpu_I2C_ADDR, MPU6050_RA_PWR_MGMT_1 , 1, 0x80);
  Delay_ms(100);
  IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  MPU_I2C_Write(mpu_I2C_ADDR, MPU6050_RA_PWR_MGMT_1 , 1, 0x00);
  Delay_ms(100);
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  MPU_I2C_Write(mpu_I2C_ADDR, MPU6050_RA_FIFO_EN , 1, 0x78);
  Delay_ms(100);
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  MPU_I2C_Write(mpu_I2C_ADDR, MPU6050_RA_INT_ENABLE , 1, 0x10);
  Delay_ms(100);
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  MPU_I2C_Read (mpu_I2C_ADDR, MPU6050_RA_ACCEL_CONFIG, 1, &raw_data);
  Delay_ms(100);
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  raw_data[0] |= 0x18;
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  MPU_I2C_Write(mpu_I2C_ADDR, MPU6050_RA_ACCEL_CONFIG, 1, &raw_data[0]);
  Delay_ms(100);
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  MPU_I2C_Read (mpu_I2C_ADDR, MPU6050_RA_INT_ENABLE, 1, &raw_data);
  Delay_ms(100);
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  raw_data[0] |= 0x11;
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
  MPU_I2C_Write(mpu_I2C_ADDR, MPU6050_RA_INT_ENABLE, 1, &raw_data[0]);
  Delay_ms(100);
    IntToStr(lcd_x,txt1);
  Lcd_Out(2,1,txt1);
}

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(100000);
     Delay_ms(50);
     Lcd_Out(1,1,"START");
     check_device(0x68);
     Delay_ms(2000);
     init_mpu();
     Lcd_Out(2,1,"                 ");
     Lcd_Cmd(_LCD_SECOND_ROW);
     Lcd_Out_CP("#");
     Lcd_Out(1,1,"#1 OK!          ");
     Delay_ms(100);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,1,"#2 OK!          ");
     Delay_ms(100);
}

mehmet

1) İki cihaz GND olarak birleşmiş durumda mı?
2) 3.3V tarafinda SCL ve SDA pinleri pull-up mu?
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

Cemre.

Hocam öncelikle cevabınız için teşekkürler.

Elimde 3.3V bir gerilim kaynağım olmadığı için 5V ve 3.3V'u arduino uno kartımdan alıyorum. Yani PIC 5V arduino vasıtasıyla USB'den, modül 3.3V yine arduino'nun 3.3V regülatöründen besleniyorlar. Board üzerinde de ayrıca GND ortaklaması yapıyorum. Yani birinci sorunun cevabı kesinlikle evet.

İkinci sorunuzun cevabı ise  modülün şemasında gizli.


Yani evet, 10kOhm ile pull-up yapılmış durumda. Eğer harici pull-up gerekmiyorsa bu sorunun cevabı da evet.

İşin ilginç tarafı, arduino ile modül dönüştürücü olsun yada olmasın çatır çatır haberleşiyor, dataları seri porttan okuyorum. Hatta odam 23 dereceymiş ben de biryerlerden soğuk geliyor diyordum  ;D

Şaka bir yana, kafayı yemek üzereyim. Breadboard'dan şüphelenip devreyi tekrar kurmaktan b.boardun her yerini gezdim artık gidecek yer de kalmadı. Zaten yaptığım bağlantıları multimetrenin diyot kademesiyle de kontrol ediyorum, iyice paranoyak yaptı beni bu durum

OG

Alıntı Yap
Elimde 3.3V bir gerilim kaynağım olmadığı için 5V ve 3.3V'u arduino uno kartımdan alıyorum.
Arduino'dan anlamam da, sanki bir yerlerde okudum gibi, "beslemesi çok zayıf" şeklinde eleştiriliyordu.
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

Cemre.

#4
Alıntı yapılan: OG - 03 Aralık 2015, 18:19:58
Arduino'dan anlamam da, sanki bir yerlerde okudum gibi, "beslemesi çok zayıf" şeklinde eleştiriliyordu.

Hocam yazarken benim de aklıma geldi, aslında kendi haberleşebiliyorken PIC + mpu6050'yi besleyememesi ilginç geliyor ama belki de sorunun kaynağı budur. Ama şuan elimde başka bir güç kaynağı yok maalesef.

mesaj birleştirme:: 03 Aralık 2015, 18:53:24

Proteus ISIS simulasyonunda aynı kodla sadece adresi 0x90 olarak değiştirip DS1631 ile iletişim kurabiliyorum. Device is OK yazısı dönüyor. Yani sorunu kodlarımda değil board.da aramam gerekiyor sanırım. Peki bu yönde bir öneriniz olabilir mi?

drmp

yazılarda çift yönlü yazıyor ama
mosfetli şema  tek yönlü gibi     H side  >>> low side gibi

led ler ile bir kontrol yap çift yönlümü tek yönlü mü??...

Cemre.

Alıntı yapılan: drmp - 03 Aralık 2015, 20:10:44
yazılarda çift yönlü yazıyor ama
mosfetli şema  tek yönlü gibi     H side  >>> low side gibi

led ler ile bir kontrol yap çift yönlümü tek yönlü mü??...

Hocam HV tarafından HV 5V'a bağlıyken herhangi bir pine 5V verdiğimde yine LV tarafı 3v3'e bağlı iken karşısındaki pinden 3v3 okuyorum ölçü aletiyle. Bu durum tersi için de geçerli. Sizin önerebileceğiniz bir şema var mı bu durumu test etmek için?

Kabil ATICI

#7
Şemadaki dönüştürücü çalışıyor, emin olabilirsiniz. Hem de iki yönde.

farkli bir ürün için ama olsun... mosfet olarak BS170 kullanmıştım.
5 V tarafın sinyali diyot üzerinden iletilirken, 3.3V tarafın sinyali mosfet üzerinden iletilir.

sadece 5V tarafın sinyalini 3.3V tarafına iletmek için bu yeterlidir. Hatta diyot olarak schotky tipi kullanılırsa gerilim düşümü daha az olacaktır.
İletişim hızınızı kontrol edin, belli bir frekansın üzerinde mosfet kapasitif etkiler devreye girmeye başladığı için sinyal bozuluyor.

isis simülasyonuna fazla güvenmeyin. En olmadık durumlarda çalışmaya devam edebiliyor.. (özellikle dijital sinyallerde)

Hatta yerine göre gerilim bölücü dirençler bile iş görebilmektedir...
ambar7

Cemre.

#8
Hocam verdiğiniz bilgiler için teşekkürler. Kafam çok karışmış durumda. Bağlantılarımı onlarca kez kontrol ettim. Modül bozuk deyip atamıyorum, Arduino ile hem 5V seviyesinde hem de bahsettiğim 3.3V dönüştürücü ile çatır çatır çalışıyor. Şuan tek şüphelenebileceğim şey aşağıdaki devre şemasında da görülebileceği üzere RB0 pinindeki (SDA) butonun 10k pull-up direnci. Bu dirençten SCL (RB1)'de yok. Ancak lojik dönüştürücünün her iki gerilim tarafında 4k7 pull-up dirençleri mevcut. Karttaki direnci sökeceğim, bakalım değişen birşey olacak mı.



Edit. Maalesef değişen bir şey yok..

selimkoc

Bunun için size 5-6$ satılan lojik analizörü şiddetle tavsiye ederim. PIC  tarafı 3.3V zaten H olarak algılar. 3.3V tarafı için en basit dirençli gerilim bölücü bile yeterli olur.

Kart üzerinde LM78L33 var. Bundan ben kendi bilgisayarımda başka modüllere kartlara voltaj uyguladım. Voltaj düşüklüğü olmadı. Yani güç  yeterli oldu.

I2C haberleşmesi için pull-up direnç zaten gerekli. PCF8574 ile I2C haberleşmesi yaptım. Ama her iki taraf ta 5V idi. Haberleşmede problem yok.

Şunu yapabilirsin;

1- Modüle 3.3V geliyor mu? Bunu ölç.
2-Voltaj konvertörü test et. HV tarafına 5V uyguladığında diğer tarafta 3.3V alabiliyormusun?
3- LV tarafından 3.3V uyguladığında HV tarafından 5V alabiliyormusun bunlara bak.

Kolay gelsin...


Cemre.

#10
Alıntı yapılan: selimkoc - 03 Aralık 2015, 22:42:22
Bunun için size 5-6$ satılan lojik analizörü şiddetle tavsiye ederim. PIC  tarafı 3.3V zaten H olarak algılar. 3.3V tarafı için en basit dirençli gerilim bölücü bile yeterli olur.

Kart üzerinde LM78L33 var. Bundan ben kendi bilgisayarımda başka modüllere kartlara voltaj uyguladım. Voltaj düşüklüğü olmadı. Yani güç  yeterli oldu.

I2C haberleşmesi için pull-up direnç zaten gerekli. PCF8574 ile I2C haberleşmesi yaptım. Ama her iki taraf ta 5V idi. Haberleşmede problem yok.

Şunu yapabilirsin;

1- Modüle 3.3V geliyor mu? Bunu ölç.
2-Voltaj konvertörü test et. HV tarafına 5V uyguladığında diğer tarafta 3.3V alabiliyormusun?
3- LV tarafından 3.3V uyguladığında HV tarafından 5V alabiliyormusun bunlara bak.

Kolay gelsin...

Üç sorunuzun cevabı da evet hocam. Ben 78L33'ü kartın montajını yaptığım sırada kaybettim maalesef. Modülün üzerinde besleme için kendi 3v3LDO entegresi var 3.3V ve 5V beslemeyi kabul ediyor ve iki şekilde de deniyorum ancak bir cevap yok. Neyse direnci bari geri lehimleyeyim :(

Hocam yakın zamanda bahsettiğiniz lojik analizörü satın alma şansım yok ama elimde pickit3 klonu var. Bunun lojik analizör özelliğini kullanmaya çalıştım ancak oluşan görüntüler hiçte beklediğim gibi değildi. Daha önce pickit3'ü lojik analizör olarak kullanan oldu mu acaba?

Kabil ATICI

MPU-6050 çip olarak değilde modül olarak kullanıyorsan, modülünü veya şemasını bulabilirsen şemasını bir incele üzerinde 3.3V regülatör olabilir.

i2c kullanıyorsan işlemcinin bacaklarını i2c olarak ayarladıktan sonra,  MPU-6050 modül üzerindeki i2c için kullanılan pull-up dirençleri yeterli olması gerekir. Çünkü i2c 'de ne işlemci ne de çevre birimi i2c hatlarını lojik-1 için vcc hattına çekmez. Bu iş pull-up dirençlerine aittir.
Yani senin o çeviriciye ihtiyacın olmayabilir.
Sadece reset vs ek hatlar varsa bunları kontrol etmek için gerekli olabilir. 3.3V hem işlemcinin hem de modülün girişlerini lojik 1 seviyesinde tutmaya yeterlidir. (pull-up direnci)

geriye senin program ile gerekli ayarlamaları yapmana ve programı işletmene kalır.
ambar7

drmp

#12
mesela 
L1   0  olunca   H1  0 oluyor mu??


Cemre.

Alıntı yapılan: drmp - 04 Aralık 2015, 11:13:41
mesela 
L1   0  olunca   H1  0 oluyor mu??

Evet hocam oluyor, zaten dediğim gibi arduino ile mpu6050 bu modül üzerinden hatasız bir şekilde haberleşebiliyor. Devreyi hiç bozmadan arduinodan söktüğüm kabloları getirip PIC'e taktığımda sonuç hüsran. Hiç bir tepki yok.

drmp

sorun  lojik  seviye değiştiricide değil   
pic ve programı konrol et

hatta arduino daki programı pice uyarla

modul sağlam anlaşıldı..