Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

ADXL345 3 Yön Sensör hakkında

Başlatan ertsen, 09 Ocak 2013, 20:51:24

ertsen

Arkadaşlar merhaba,
   Bir meslek lisesinde görev yapıyorum. Allah izin verirse baharda "elektronik hobi" sergisi açmayı düşünüyorum. Amacımız mesleki tanıtım için gelen ilköğretim öğrencilerine elektronik ve kontrol hakkında fikir vermek ve meslek liselerine kaliteli öğrencileri kazandırmak.
    Bu dönem yaklaşık 10 tane projeyi öğrencilerimizle bitirdik. En son olarak ta Adxl345 hareket sensörü ile çift servo kontrol ederek bir denge sistemi kurmayı düşünüyorum. İnternette hep Aurdunio yada Assemly örnekleri buldum. Ancak bana CCs için yazılmış Adxl345 kütüphanesi lazım.
    Daha önceden I2C ile ds1307 saat  uygulaması yaptım. Servoda da sorun yaşamıyorum. Ancak ya Adxl345 için bir kütüphane bulacağım yada kendim yazacağım(bayağı zor benim için)

   Yardımcı olabilirseniz sevinirim..

kantirici

ADXL335 kullanın.Sensör analog oldgu için direk analog değerler üzerinden işlem yaparak istediginizi yapabilirsiniz.

mistek

#2
Bu kodu örnek alabilirsiniz CCS için düzenleyebilirsiniz takıldığınız yer olursa yardımcı olmaya çalışırım.
#define ADXL345_ADR   0xA6 //Write           0xA7//Read
#define BW_RATE       0x2C
#define POWER_CTRL    0x2D
#define DATA_FORMAT   0x31

#define ADXL345_xLSB  0x32
#define ADXL345_xMSB  0x33
#define ADXL345_yLSB  0x34
#define ADXL345_yMSB  0x35
#define ADXL345_zLSB  0x36
#define ADXL345_zMSB  0x37

int16_t adxl345_data_x=0;
int16_t adxl345_data_y=0;
int16_t adxl345_data_z=0;

void adxl345_init()
{
   i2c_write(ADXL345_ADR, POWER_CTRL, 0x00);
   i2c_write(ADXL345_ADR, POWER_CTRL, 0x08);
   i2c_write(ADXL345_ADR, BW_RATE, 0x09);  //BW_RATE     -- value: rate=50hz, bw=20hz
   i2c_write(ADXL345_ADR, DATA_FORMAT, 0x0B); //DATA_FORMAT -- value: Set bits 3(full range) and 1 0 on (+/- 16g-range)

}

int16_t adxl345_get_xaxis()
{
   
   int16_t adxl345_msb_x = i2c_read(ADXL345_ADR, ADXL345_xMSB);
   int16_t adxl345_lsb_x = i2c_read(ADXL345_ADR, ADXL345_xLSB);

   adxl345_data_x = ((adxl345_msb_x << 8) + adxl345_lsb_x);
      
   /*
   if((adxl345_data_x)& 0x2000) adxl345_data_x |= 0xC000;
 
      adxl345_data_x = adxl345_data_x;
    */
   return(adxl345_data_x - 11);
}

int16_t adxl345_get_yaxis()
{
   
   int16_t adxl345_msb_y = i2c_read(ADXL345_ADR, ADXL345_yMSB);
   int16_t adxl345_lsb_y = i2c_read(ADXL345_ADR, ADXL345_yLSB);

   adxl345_data_y = ((adxl345_msb_y << 8) + adxl345_lsb_y);
      /*
   if((adxl345_data_y)& 0x2000) adxl345_data_y |= 0xC000;
 
      adxl345_data_y = adxl345_data_y;
    */
   return(adxl345_data_y);
}

int16_t adxl345_get_zaxis()
{
   
   int16_t adxl345_msb_z = i2c_read(ADXL345_ADR, ADXL345_zMSB);
   int16_t adxl345_lsb_z = i2c_read(ADXL345_ADR, ADXL345_zLSB);

   adxl345_data_z = ((adxl345_msb_z << 8) + adxl345_lsb_z);
      
   /*
   if((adxl345_data_z)& 0x2000) adxl345_data_z |= 0xC000;
 
      adxl345_data_z = adxl345_data_z;
   */
   return(adxl345_data_z + 20);
}
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

ertsen

kantirici Artık sensörü almış durumdayım. Değiştiremem mümkün değil şu anda. Yinede teşekkürler.
muhamm@, kodlar için teşekkürler.  CCS ye uyarlamaya çalışırım.Eğer takıldığım yer olursa yardımını isterim. Yinede elince CCS için kod olan arkadaşların fikirlerine de açığım.

halilgalic

#4
adxl335 ile rf kontrollü araç yapmıştım kodlar basıc ama işinize yarayabilir.
pc rf robot.mp4
'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : ********BY GALİÇ*********                         *
'*  Notice  : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 13.11.2010                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
@ DEVICE pic16F877A 'islemci 16F877
@ DEVICE pic16F877A, WDT_OFF 'Watch Dog timer kapalı
@ DEVICE pic16F877A, PWRT_OFF 'Power on timer KAPALI
@ DEVICE pic16F877A, PROTECT_ON 'Kod Korum kapalı
@ DEVICE pic16F877A, HS_OSC

INCLUDE "MODEDEFS.BAS" 'İLETİŞİM PROTOKOLLERİNİ YÜKLE 

DEFINE OSC  20 ;OSİLATÖRÜ 20 MHz HS AYARLA

TrisA=%11111111:PortA=0 
TrisB=0:PortB=0   
TrisC=0:PortC=0  
TrisD=0:PortD=0   
TRisE=0:PortE=0


DEFINE	ADC_BITS	10	    'A/D çevirim sonucu kaç bit olacak
DEFINE	ADC_CLOCK	2	    'Clock kaynağı (3=rc)
DEFINE	ADC_SAMPLEUS	80	'Örnekleme zamanı mikro saniye cinsinden.
 SYMBOL TX=PORTC.6

ADCON1=%10000000 '7. bit 1 yapıldı 10 bit sonuç almak için. a0 analog

 
 
X VAR WORD
Y VAR WORD

 
 
 GIDEN VAR WORD
 
                 
BASLA:
 
 

 
 
 ADCIN 2,Y    
YY:IF ADCON0.2=1 THEN YY 
 

 
ADCIN 3,X
XX:  IF ADCON0.2=1 THEN XX  


;--------------------------DUR-------------------------------------------------
IF (X>320&X<340) AND (Y>325&Y<345) THEN
GIDEN=251
GOSUB SERI_GONDER 
ENDIF 
;----------------------------------------------------------------------------


;------------------------------İLERİ-----------------------------------------
IF X<=300 THEN
GIDEN=250  
GOSUB SERI_GONDER  
ENDIF
;----------------------------------------------------------------------------


 ;-------------------------------GERİ-----------------------------------------
IF X=>360 THEN
GIDEN=252  
GOSUB SERI_GONDER  
ENDIF
;----------------------------------------------------------------------------



;--------------------------------SAG-------------------------------------------
IF Y=>360 THEN
GIDEN=253  
GOSUB SERI_GONDER  
ENDIF

;----------------------------------SOL---------------------------------------
IF Y=<315 THEN
GIDEN=254  
GOSUB SERI_GONDER  
ENDIF
       
   
 
PAUSE 50


GOTO BASLA
 
 
SERI_GONDER:
    SEROUT2 TX,16780,[REP$AA\5,REP$00\5,REP$FF\5]; preambl sinyali 
    SEROUT2 TX,16780,["TEKE",GIDEN] 
    SEROUT2 TX,16780,["TEKE",GIDEN]
   
    RETURN

mistek

CCS de yaptığım bma180 ivme sensörü için olan kodlarıda veriyorum çok benzerler birbirine sadece data registerlarını kaydırma işleminde ufak bir farklılık var sınavlarımdan dolayı pek ilgilenemiyorum kusura bakmayın.

BMA180 adxl345 ile çok benzerdir registerlerı modifiye ederek çalıştırabilirsiniz.


#define offset_lsb1 0x35
#define bw_tcs 0x20

#use i2c(master, sda=pin_c4, scl=pin_c3, fast=400000) 

unsigned int value=0;

unsigned int16 acc_lsb_x = 0;               
unsigned int16 acc_msb_x = 0;
unsigned int16 acc_lsb_y = 0;               
unsigned int16 acc_msb_y = 0;
unsigned int16 acc_lsb_z = 0;               
unsigned int16 acc_msb_z = 0;
signed int16 acc_data_x = 0;                   
signed int16 acc_data_y = 0;
signed int16 acc_data_z = 0; 



void bma180_init(void)
{

   delay_ms(10);
   
   i2c_start();
   i2c_write(0x80);
   i2c_write(bw_tcs);
   i2c_start();
   i2c_write(81);
   value=i2c_read(0);
   i2c_stop();
   value &= 0b00001111;
   i2c_start();
   i2c_write(0x80);
   i2c_write(bw_tcs);   //bandwidth = 10Hz
   i2c_write(value);
   i2c_stop();
   
   
   i2c_start();
   i2c_write(0x80);
   i2c_write(offset_lsb1);
   i2c_start();
   i2c_write(81);
   value=i2c_read(0);
   i2c_stop();
   value &= 0b11110001;
   value |= 0b00000100;
   i2c_start();
   i2c_write(0x80);
   i2c_write(offset_lsb1);
   i2c_write(value);    //range= 2g mode   0.25mg/LSB
   i2c_stop();
}

int16 bma180_get_xaxis()
{
   
   i2c_start();
   i2c_write(0x80);
   i2c_write(0x03);
   i2c_start();
   i2c_write(0x81);
   acc_msb_x=i2c_read(0);
   i2c_stop();
 
   i2c_start();
   i2c_write(0x80);
   i2c_write(0x02);
   i2c_start();
   i2c_write(0x81);
   acc_lsb_x=i2c_read(0);
   i2c_stop();
 
   acc_data_x = ((acc_msb_x << 8)+acc_lsb_x);
   acc_data_x = acc_data_x >> 2;
   
   if((acc_data_x)& 0x2000) acc_data_x |= 0xC000;
  
   acc_data_x = acc_data_x + 135 ;
   
   return(acc_data_x);
}

int16 bma180_get_yaxis()
{
   i2c_start();
   i2c_write(0x80);
   i2c_write(0x05);
   i2c_start();
   i2c_write(0x81);
   acc_msb_y=i2c_read(0);
   i2c_stop();

   i2c_start();
   i2c_write(0x80);
   i2c_write(0x04);
   i2c_start();
   i2c_write(0x81);
   acc_lsb_y=i2c_read(0);
   i2c_stop();

   acc_data_y = ((acc_msb_y << 8)+acc_lsb_y);
   acc_data_y = acc_data_y >> 2;
   
   if((acc_data_y)& 0x2000) acc_data_y |= 0xC000;

   acc_data_y = acc_data_y - 121;
      
   return(acc_data_y);
}

int16 bma180_get_zaxis()
{
   i2c_start();
   i2c_write(0x80);
   i2c_write(0x07);
   i2c_start();
   i2c_write(0x81);
   acc_msb_z=i2c_read(0);
   i2c_stop();
 
   i2c_start();
   i2c_write(0x80);
   i2c_write(0x06);
   i2c_start();
   i2c_write(0x81);
   acc_lsb_z=i2c_read(0);
   i2c_stop();
   
   acc_data_z = ((acc_msb_z << 8)+acc_lsb_z);
   acc_data_z = acc_data_z >> 2;
   
   if((acc_data_z)& 0x2000) acc_data_z |= 0xC000;
 
   acc_data_z = acc_data_z - 24;
 
   return(acc_data_z);
}
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

skara1214

kod optimizasyonu için okuma yaptığınız yerdeki i2c_stop() dan sonra i2c_start() yazacağınız yere i2c_restart() ta koyabilirsiniz ama elinize sağlık güzel paylaşım olmuş
Herkes ölür ama herkes gerçekten yaşamaz

ertsen


ertsen

#8
sensor ile bir türlü bağlantı kuramıyorum.
#define ADXL345_ADR   0xA6 //Write           0xA7//Read
#define BW_RATE       0x2C
#define POWER_CTRL    0x2D
#define DATA_FORMAT   0x31
#define FIFO_MODE     0x38


#define RTC_SDA  PIN_C7 //C4
#define RTC_SCL  PIN_C6 //C3

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)


void adxl345_init(void)
{ 
 output_high(PIN_C0);
 delay_ms(100);

 i2c_start(); 
 i2c_write(ADXL345_ADR);  // bu satırın altında led sönmesi lazım ama hiç sönmüyor

 delay_ms(100);
 output_low(PIN_C0);

 delay_ms(100);
  i2c_write(ADXL345_ADR); 


 i2c_write(POWER_CTRL);
 i2c_write(0x00); 
    
 i2c_write(DATA_FORMAT);
 i2c_write(0x01);
 i2c_stop();

}


yukarıdaki bağlantıya göre pic 18f2550 bağlantısını yaptım

artapon

hocam ben de tez konusu olarak aldım ama hala bir türlü başlayamadım... bu sensörü kullanarak bilgisayar arayüzünde bir uygulamada kullanacağım...
Aldanma İnsanların Samimiyetine, Menfaatleri İçin Gelirler Vecde, Vaad Etmeseydi Allah cenneti, O'na Bile Etmezlerdi Secde!   (NFK)

artapon

#10
burda bir uygulama var ama üye olmak bayağı bi zor...

http://www.elektrotekno.com/about59956.html

mesaj birleştirme:: 11 Ocak 2013, 03:19:26

hocam sensör ile bağlantı kurabilmeniz için ack bitlerini kontrol etmeniz gerekir. acaba bunu göz önünde bulundurdunuz mu.. ben görmedim/göremedim.



bu sıraya göre olmalı I2C protokol yürütmeniz. ds1307 de ack biti yok bildiğim kadarıyla ama burda o var...
Aldanma İnsanların Samimiyetine, Menfaatleri İçin Gelirler Vecde, Vaad Etmeseydi Allah cenneti, O'na Bile Etmezlerdi Secde!   (NFK)

ertsen

#11
dün yaklaşık 4 saatlik uğraştan sonra bağlantı gerçekleşti. Ben 3.2 V luk bios pili ile deniyordum. pili ölçtüğümde 2.9 V gösteriyordu ancak yüke girdiğinde 2V'a düşüyormuş. Bir pot ile 5 voltu böldüm 3V'a. öyle çalıştırabildik.

  muhamm@ hocamın yazdığı ve internetten bulduğum bazı kodlara göre I2C yi kurdum. Ancak bir türlü stabil bir rakam alamıyorum.
adxl345.c aşağıdaki gibi
#define ADXL345_ADR   0xA6 //Write           0xA7//Read
#define BW_RATE       0x2C
#define POWER_CTRL    0x2D
#define DATA_FORMAT   0x31
#define FIFO_MODE     0x38

#define ADXL345_xLSB  0x32
#define ADXL345_xMSB  0x33
#define ADXL345_yLSB  0x34
#define ADXL345_yMSB  0x35
#define ADXL345_zLSB  0x36
#define ADXL345_zMSB  0x37
#define BIR           0x01

#define RTC_SDA  PIN_C7 //C4
#define RTC_SCL  PIN_C6 //C3

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)


void adxl345_init(void)
{

i2c_start(); 
i2c_write(ADXL345_ADR);
i2c_write(POWER_CTRL);
i2c_write(0x00);
i2c_stop();
delay_ms(1);

i2c_start();
i2c_write(ADXL345_ADR);
i2c_write(DATA_FORMAT);
i2c_write(0x01);
i2c_stop();
delay_ms(1);

i2c_start(); 
i2c_write(ADXL345_ADR); 
i2c_write(FIFO_MODE); 
i2c_write(0x40);
i2c_stop();
delay_ms(1); 

i2c_start(); 
i2c_write(ADXL345_ADR);
i2c_write(BW_RATE); 
i2c_write(0x0c); 
i2c_stop(); 
delay_ms(1); 

i2c_start(); 
i2c_write(ADXL345_ADR); 
i2c_write(POWER_CTRL); 
i2c_write(0x08); //Measurement mode  
i2c_stop();
delay_ms(1);
}


Ana program da sadee x koordinatlarını almaya çalıştım. Sanki sürekli sırasıyla 2 ayrı değeri alıyorum.

#include <18F2550.h>

#fuses  HSPLL,NOWDT,NOPROTECT,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN      // dont change
#use    delay(clock=48000000)  

#build (reset=0x1000, interrupt=0x1008)                              // new addresses
#org 0x0,0xfff {}                                             // reserved space 
//!#include "adxl345.c" 
#include "LCD_FLEX.c" 
#include "adxl345.c"

//!#use i2c(master, sda=PIN_C6, scl=PIN_C7)

void main ()
{
   int i;
   signed int16 values[6];   
   
   signed int16 acc_data_x;
   
    lcd_init();  
    adxl345_init();

    //delay_ms(1);


while(true) {

 i2c_start();
 i2c_write(0xA6);    //SDO pini topraklı ise A6 write modu ve a7 read mode
 i2c_write(0x32);    //X0 yani lsb_x     
 i2c_start();
 i2c_write(0xA7);   //SDO pini topraklı ise A6 write modu ve a7 read mode
 values[0]=i2c_read();
 i2c_stop();
 
 
 i2c_start(); 
 i2c_write(0xA6);    //SDO pini topraklı ise A6 write modu ve a7 read mode
 i2c_write(0x33);    //X1 yani msb_x 
 i2c_start(); 
 i2c_write(0xA7);    //SDO pini topraklı ise A6 write modu ve a7 read mode
 values[1]=i2c_read();
 i2c_stop();


acc_data_x=(int16) (values[1]+ values[0]);


//!if((acc_data_x)& 0x2000) {
//!   acc_data_x|=0xc000;
//!}
acc_data_x=acc_data_x -11;
lcd_gotoxy(1,1);
printf(lcd_putc,"X0:%x",values[0]);
lcd_gotoxy(7,1);
printf(lcd_putc,"X1:%x",values[1]);
lcd_gotoxy(1,2);
printf(lcd_putc,"X:%x",acc_data_x);



output_toggle(PIN_C0);

delay_ms(300);

   }
}


mistek

MSB den okuduğunuzu 16bitlik registerda üst byte a kaydırın. siz şuan xmsb ve xlsb den okuduğunuz 8 bitlik veriyi topluyorsunuz.
adxl345_data_x = ((value[1] << 8 ) + value[0]); olarak denermisiniz?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

ertsen

#13
arkadaşlar bi yardım edin bir haftadır işin içinden çıkamadım.
okuduğum değer sensör sabit olmasına rağmen sürekli değişiyor ve öyle birbirine yakın değerler de değil.
Video linki:
video 2013 01 16 19 51 58

pisayisi

Sensör bağlantılarından gürültü kuple olmuyorsa, sensörün data rate register değerini 50 hz in altında tutarak ve sensörün besleme voltajını 3.3 v - 3.6 volt arası değerde tutarak gürültü azaltılabilir...
Murat