M

dıjıtal sensörler

Başlatan musa, 03 Mart 2014, 08:54:59

musa

herkese merhaba forumu uzun süredir takip ediyorum çok güzel bilgiler mevcut emeği gecen herkese saygılar.

dıjıtal sensörlere merak sardım birkaç tane sensör hallettikten sonra nihayet bir tanesini  çalıştırdım

HMC5883L fakat sorunum sensör sabit durmasına rağmen değerler sürekli değişiyor bu konuda bilgisi olanlardan yardım bekliyorum



  kullandığım kodlar ( bu kodların tamamı bana ait değildir sadece bazı değişiklikler yaparak kullandım)

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NODEBUG,NOCPD
#use delay (clock=20000000)
#include <HDM64GS12.c>
#include <graphics.c>


//**********************************************************

#use i2c(Master, sda=PIN_C1, scl=PIN_C0) 
// i2c slave addresses

#define HMC5883L_WRT_ADDR 0x3C
#define HMC5883L_READ_ADDR 0x3D

// Register addresses

#define HMC5883L_CFG_A_REG 0x00
#define HMC5883L_CFG_B_REG 0x01
#define HMC5883L_MODE_REG 0x02
#define HMC5883L_X_MSB_REG 0x03


//**********************************************************
 
   char yazi1[]="HMC5883L TEST";
   char yazi2[]="X        ";
   char yazi3[]="Y        ";
   char yazi4[]="Z        ";   
   char yazi5[]="         "; 


//*****************************************************
// Low level routines
//------------------------------


void hmc5883l_write_reg (int8 reg, int8 data)
{
   i2c_start();
   i2c_write(HMC5883L_WRT_ADDR);
   i2c_write(reg);
   i2c_write(data);
   i2c_stop();
}

//------------------------------

int8 hmc5883l_read_reg(int8 reg)
{
   int8 retval;

   i2c_start();
   i2c_write(HMC5883L_WRT_ADDR);
   i2c_write(reg);
   i2c_start();
   i2c_write(HMC5883L_READ_ADDR);
   retval = i2c_read(0);
   i2c_stop();

   return(retval);
}

//------------------------------

  typedef struct
  {
   int16 x;
   int16 y;
   int16 z;
  }

  hmc5883l_result;

// This global structure holds the values read
// from the HMC5883L x,y,z registers.

hmc5883l_result compass = {0,0,0};

//------------------------------    HMC DEN OKUMA ALT PROGRAMI  ---------------------------------------------

void hmc5883l_read_data(void)
  {
   int8 x_lsb;
   int8 x_msb;
   int8 y_lsb;
   int8 y_msb;
   int8 z_lsb;
   int8 z_msb;

   i2c_start();
   i2c_write(HMC5883L_WRT_ADDR);
   i2c_write(HMC5883L_X_MSB_REG);    // Point to X-msb register
   i2c_start();
   i2c_write(HMC5883L_READ_ADDR);

   x_msb = i2c_read();
   x_lsb = i2c_read();

   y_msb = i2c_read();
   y_lsb = i2c_read();

   z_msb = i2c_read();
   z_lsb = i2c_read(0);          // do a NACK on last read

   i2c_stop();

// Combine high and low bytes into 16-bit values.

   compass.x = make16(x_msb, x_lsb);
   compass.y = make16(y_msb, y_lsb);
   compass.z = make16(z_msb, z_lsb);
  }



//*****************************************************************************
void main ()
{
   setup_psp(PSP_DISABLED);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_CCP1(CCP_OFF);
   setup_CCP2(CCP_OFF);
   
   setup_adc_ports(OFF);
   
   
   set_tris_A(0xFF);
   set_tris_E(0xFF);
   set_tris_C(0x00);


   
     
       glcd_init(ON); 
     
      glcd_text57(10, 5, yazi1, 1, on);
      delay_ms(1000);

     
     
//**********************************************************************     
   


   delay_ms(500); // A power-on init delay may be needed

//   printf("\n\rStart:\n\r");

// Init the HMC5883L. Set Mode register for
// continuous measurements.

   hmc5883l_write_reg(HMC5883L_CFG_A_REG, 0x70);
   hmc5883l_write_reg(HMC5883L_CFG_B_REG, 0xA0);
   hmc5883l_write_reg(HMC5883L_MODE_REG, 0x00);

// Continuously read and display the x,y,z results.
// Wait at least 67 ms between reads, re the HMC5883L data sheet.



   while(1)   
   
    {
   
        glcd_init(ON);

   
//       sprintf(yazi5,"son  %Lu",voltaj);
//       glcd_text57(5, 20, yazi5, 1,on);   
//        delay_ms(3000);
     
     
     
     hmc5883l_read_data();     
     
           
      sprintf(yazi2,"X=  %Ld",compass.x);
      glcd_text57(5, 10, yazi2, 1,on);
      delay_ms(20);
   
   
      sprintf(yazi3,"Y=  %Ld",compass.y);
      glcd_text57(5, 30, yazi3, 1,on);
      delay_ms(20);
   
   
      sprintf(yazi4,"Z=  %Ld",compass.z);
      glcd_text57(5, 50, yazi4, 1,on);
      delay_ms(20);
   
      delay_ms(1000);
//********************************************************************
   }

   

musa

Anlaşılan yardım edecek kimse yok vatan sağolsun  :'(

ete

Yardım edecek kimse var da konuyu anlayan kimse yok. Ne sensörü kullandın onu bile yazma zahmetinde bulunmamışsın.
Belliki I2C ile haberleşen bir sensör. Bir yerlerden kod alıp çalıştırdığında belli oluyor. Peki karşılaştığın sorunun bir çok sebebi olabileceğini düşündünmü hiç?. Bu sebep de daha ziyade yazılımdan çok devre veya çevre ile alakalı gibi gözüküyor.
Bir sensör okuma değeri sabit durmuyorsa ya devrenin beslemesinde sorun vardır yada ortamda sensörü etkileyen unsurlar var demektir.
Ne sensörü olduğunu bilemediğim için fazlaca yorum yapamıyorum.
Yazılımla ancak okunan değerde az da olsa stabilizasyon sağlanabilir. Burada yine ne sensörü olduğu gündeme geliyor.
Bir sıcaklık sensörü olsa bir çok okuma yapıp bunların arasından çok küçükler ile çok büyükleri bırakıp ortada yer alanların ortalamasını alarak gerekli stabilizasyon sağlanabilir. Ama sen sensörün her neyse onunla ilgili ne yapılır bilemiyorum.

Ete


musa

Sayın Ete herşeyden önce cevap verdiğiniz için teşekkürler. Bir çok yazınızı okudum ve çok faydalandım.
 
  Kullandığımsensör HMC5883L dijital 3 eksen pusula sensörü amacım üç eksende eğim bilgilerini derece cinsinden alıp bu verileri bir model uçağı kumanda etmek ı2c protokolünü çok az biliyorum hem kendimi geliştirmek hemde işe yarar birşeyler yapmak istiyorum.
  Hemen şunuda söyliyeyim akademisyen değilim elektronikçiyim sadece merak ettiğim için pıc proramlamayı kitaplardan ve örnek kodlardan faydalanarak öğrenmeye çalışıyorum.
   hmc5883l yi çalıştırdım fakat modülü yatay eksende veya dikey eksende döndürdüğümde diğer eksenlerdede çok fazla değişme oluyor. sebebini çözemedim bu tip sensörlerde ne yazıkki Türkçe kaynak pek yok.İlginize tekrar teşekkürler.   

ete

Çevresel etken dediğim şey etkin galiba. Aleti çalıştırdığınız yerde etrafınızda manyetik kaynak (sabit mıknatıs, elektro mıknatıs , elektrikli bobin) vs varsa etkiler.

Hemen belirteyim bende akedemisyen değilim . Kimya mühendisiyim ve elektronik konusunda öğrendiklerimin tamamını kendi kendime okuyarak ve eşeleyerek öğrendim.
Ete

musa

  Sayın ete çevresel faktörleri gözönune aldım fakat sonuç değişmedi videosunu çektim en kısa sürede yükleyeceğim
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NODEBUG,NOCPD
#use delay (clock=20000000)
#include <HDM64GS12.c>
#include <graphics.c>

#include <math.h>


//X=atan2(compass.x, compass.y) * 180 / 3.14159265 + 180;

//**********************************************************

#use i2c(Master, sda=PIN_C1, scl=PIN_C0,slow=100000) 
// i2c slave addresses

#define HMC5883L_WRT_ADDR 0x3C     // SENSÖRE YAZMA KOMUTU
#define HMC5883L_READ_ADDR 0x3D    // SENSÖRDEN OKUMA KOMUTU

// Register addresses

#define HMC5883L_CFG_A_REG 0x00   // A REGISTERİ ADRESİ
#define HMC5883L_CFG_B_REG 0x01   // B REGISTER ADRESİ
#define HMC5883L_MODE_REG 0x02    // MOD. REGISTER ADRESİ
#define HMC5883L_X_MSB_REG 0x03   // MSB KISMININ BULUNDUĞU ADRES



//******************************** DEĞİŞKEN TANIMLAMALARI  *******************
 
   char yazi1[]="HMC5883L TEST";
   char yazi2[]="X        ";
   char yazi3[]="Y        ";
   char yazi4[]="Z        ";   
   char yazi5[]="         "; 


   int16 Y,Z;
   float xm;
   float xl,X ;
//*****************************************************

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX         

void hmc5883l_write_reg (int8 reg, int8 data)
{
   i2c_start();
   i2c_write(HMC5883L_WRT_ADDR);
   i2c_write(reg);
   i2c_write(data);
   i2c_stop();
}

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

int8 hmc5883l_read_reg(int8 reg)
{
   int8 retval;

   i2c_start();
   i2c_write(HMC5883L_WRT_ADDR);
   i2c_write(reg);
   i2c_start();
   i2c_write(HMC5883L_READ_ADDR);    //  HMCL5883 OKUMA ADRESİ 
   retval = i2c_read(0);
   i2c_stop();

   return(retval);
}

//------------------------------

  typedef struct
  {
   int16 x;
   int16 y;
   int16 z;
  }

  hmc5883l_result;

// This global structure holds the values read
// from the HMC5883L x,y,z registers.

hmc5883l_result compass = {0,0,0};

//------------------------------    HMC DEN OKUMA ALT PROGRAMI  ---------------------------------------------

void hmc5883l_read_data(void)
  {
   int8 x_lsb;
   int8 x_msb;
   int8 y_lsb;
   int8 y_msb;
   int8 z_lsb;
   int8 z_msb;

   i2c_start();
   i2c_write(HMC5883L_WRT_ADDR);
   i2c_write(HMC5883L_X_MSB_REG);    // Point to X-msb register
   i2c_start();
   i2c_write(HMC5883L_READ_ADDR);

   x_msb = i2c_read();              //  X,Y,Z DEĞERLERİ DÜŞÜK VE YÜKSEK BAYTLARI  OKUNUYOR
   x_lsb = i2c_read();   
 
   y_msb = i2c_read();
   y_lsb = i2c_read();

   z_msb = i2c_read();
   z_lsb = i2c_read(0);          //

   i2c_stop();

 



   compass.x = make16(x_msb, x_lsb);    // 8 BİTLİK MSB VE LSB VERİLERİ 16 BİTLİK DEĞİŞKENLERE  BİRLEŞTİRİLİYOR
   compass.y = make16(y_msb, y_lsb);
   compass.z = make16(z_msb, z_lsb);
 
   
  }

   

//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX



void main ()
{
   setup_psp(PSP_DISABLED);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_CCP1(CCP_OFF);
   setup_CCP2(CCP_OFF);   
   setup_adc_ports(OFF);
   
     
       glcd_init(ON); 
     
      glcd_text57(10, 5, yazi1, 1, on);  // GRAFİK EKRANA " HMC5883L TEST " YAZISI YAZILIYOR
      delay_ms(1000);
   
     
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX   
   

         hmc5883l_write_reg(HMC5883L_CFG_A_REG, 0x70);     //
         delay_ms(100);
         hmc5883l_write_reg(HMC5883L_CFG_B_REG, 0x20);     //           
         delay_ms(100);                                                               
         hmc5883l_write_reg(HMC5883L_MODE_REG, 0x00);      //           
         delay_ms(100);

   

   while(1)   
   
    {

        glcd_init(ON);

     
       hmc5883l_read_data();               //HMC DEN OKUMA FONKSİYONU ÇAĞRILIYOR
 
     
           
      sprintf(yazi2,"X= %Ld", compass.x);    // 16 BİTLİK DEĞERLER EKRANA YAZILIYOR
      glcd_text57(5, 10, yazi2, 1,on);
     
   
      sprintf(yazi3,"Y=  %Ld", compass.y);
      glcd_text57(5, 30, yazi3, 1,on);
     
   
      sprintf(yazi4,"Z=  %Ld", compass.z);
      glcd_text57(5, 50, yazi4, 1,on);
      delay_ms(300);         
     

   }

   
      Proplemim bahsettiğim gibi  compass.x  değeri değişirken  compass.y ve  compass.z değeride değişiyor sorun kodlardamı çözemedim.
   
   
   
   

zengar

#6
Sensörün y ve z eksenlerine ait çıktıları read işlemi başladığında x'in ardından geliveriyomu. Yoksa farklı adreslerden mi okuyacaksın, data sheet inden öğrenin.
Yoksa X e gelecek veriler, x e yüklendikten sonra y ve z yede yükleniyor, yani x 30 olduğunda, y 40, z 60-75 olduğunu görürsünüz lcd ekranında.
Başka bir ihtimal fırçasız motorlar ki üstünde neodimyum magnet mıknatıs taşıyor olabilir,
ve bu sensörü hayli etkiler. 6352 sensörü ile metal bir levhadan 30 cm uzakta bile değerlerin etkilendiğini gördüm.
Selametle.

musa

http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/HMC5883L_3-Axis_Digital_Compass_IC.pdf


Sayın hahula devreyi sadece grafik lcd üzerinde denedim yani motor veya metal aksamlardan uzak sensörün data bilgilerinden anladığım kadarıyla
oku komutundan sonra her eksene ait 8 bitlik msb ve lsb bilgisi okunuyor aynı adresten diye anladım ama pek emin değilim cünkü ingilizcem pek yok fakat dediğiniz mantıklı geliyor kodlarda bir eksiklik veya bir yanlışlık var fakat cözemedim.Saygılar

zengar

Data sheet inde hazır bir örnek var şunu bir deneyebilirmisiniz,
program başladığında şu bilgileri sırasıyla yazdır 
i2c_write------>   0x3C, 0x00, 0x70;
sonrada şunları
i2c_write------>    0x3C, 0x01, 0xA0;

sonra aşağıdaki kodları bir döngüye koyup her sensörü okumak istediğinde bu bilgileri tekrarla;
i2c_write------> 0x3C, 0x02, 0x01;
6 ms bekleme ver
i2c_write------> 0x3D, 0x06;
3 çift çıktını al, programında yazıldığı gibi.


sensörün değişik çalışma fonksiyonları mevcut senin programda değişik modlar seçilmiş data sheetine
detaylı bakmak lazım üsteki programdan 15 hz de veri çekebilirsin, 75 hz kadar çekilebiliyor, dediğim gibi, bunları iyice okuyup denemek lazım
Selametle

musa

İlginize teşekkürler sayın hahula en kısa zamanda yeniden değişik modları deniyeceğim

musa

Alıntı yapılan: musa - 05 Mart 2014, 21:28:05
İlginize teşekkürler sayın hahula en kısa zamanda yeniden değişik modları deniyeceğim

Sayın hahula verdiğiniz kod u denedim çalışmadı bütün çıkışlar -1 de sabit kaldı okuma rutininde verdiğiniz 0x06 adresi z ekseninin lsb adresi modül bunu kabul etmiyor datasından anladığım kadarıyla x ekseninin msb adresinden okumaya başlıyor ve modül otomatik olarak register adreslerini artırıyor.
Saygılar.

musa

Evet arkadaşlar video yükliyemedim resimlerle sorunumu anlatmaya çalışayımi

x ekseninde aldığım değer  5  y ekseni 155  90 derece ceviriyorum değerler x 115 ve y 176  iki ekseninde değer değiştirmesi normalmi  teşekkürler.

     

pwm3434

musa  kardeş   sensörün  nasıl  kulanırlığını  araştırdın mı. yani  xzy eksenleri  hangi  durumlarda  sinyal  üretir.

musa

Sayın pwm3434  web ten edindiğim kadarıyla bilgim var yani tam olarak bilniyorum pusula sensörü diye geciyor yardım istememim bedenide bu
  datası bu linkte

http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/HMC5883L_3-Axis_Digital_Compass_IC.pdf

pwm3434

#14
kardeşim  çok  çalışmak  kovalamak  gerekiyor  hele helede  ileri  düzey  projeler  olunca  çünkü  türkçe  kaynak  bulmaktan  insan  zorlanıyor.  neyse  başarılar

Powered by EzPortal