26 Temmuz 2015 Pazar

74HC595 Kullanımı






74 HC 595 entegresi piyasada çok sık kullanılan entegrelerden biridir.  Bu entegre seri olarak girilen verinin veya datanın paralele dönüştürmesini sağlar. [1]  Bu entegre, 8-bit seri giriş, paralel çıkış ve 8-bit D tipi flip-floba (latch) sahiptir. Bu entegre 8-bit seri olarak verdiğimiz dataları içinde depolar sonra  onları biz istediğimiz zaman parelele dönüştürür. Yani 75HC595 entegresinin DS pinine bir mikrodenetleyici tarafından 8-bit veri gönderilir ve sonra onlar Q1’den Q7 kadar o seri bit çıkışta gösterilir.  Tabi bunlar benim böyle anlattığım gibi direk olmuyor. Bazı kurallar var onlara göre yapmak gerekir. 




Özellikleri:

  •   İşlem yapması için gerekli çalışma gerilimi minimum 2V, maksimum 6V olamalıdır.

  •    Maksimum çekeceği akım bu entegrenin 80 uA’dir.

  •   Kaskad bağlama özelliğine sahiptir. 74HC595’in 9.pini yardımıyla bir başka 74HC595 ile kaskad bağlanabilir.

  •   Kaydırma frekansı 100Mhz.
 
 



 
Yukarıda 74HC595 hakkında pin açıklamaları verilmiştir. Gayet açık bir şekilde her bir pinin ne işe yaradığını belirtiyor tablo. Bizimyapmamız gereken şey, DS pinine seri olarak datalarımızı göndermek ama bunu yaparken her data için bir clock gerekiyor. Clock SH_CP pinine uygulanır. Her yükselen kenar clock’unda  seri olarak gönderdiğimiz datalar 74HC595 kabul eder. Sonra 8-bit data seri olarak gönderildikten sonra ST_CP lojik 1 durumuna çıkarılır çıkışlar gönderdiğimiz datalara göre aktif olur. Şunu unutmamız gerekir, datalar seri olarak gönderilmeye başladığında ST_CP lojik 0, dataların hepsi gönderildikten sonra lojik 1 yapılır.
 
Bu entegrenin kullanım amaçları şunlar; Kullandığınız mikrodenetliyice pin sıkıntısı sorunu varsa siz bu entegreyi kullanarak o sorunu çözebilirsiniz. Yani, mikrodenetleyicinizin minimum üç pini kullaranak  siz  74HC595 yardımıyla 8 pine çıkarabilirsiniz. Mikrodenetleyicilerde satır LCD ekran sürmek için çok fazla pine ihtiyaç vardır ama bu entegre yardımıyla  satır LCD ekran sürebilirsiniz. Led uygulamalarında kullanılabilir, örneğin dot matrixli uygulamalarda.
Ben bu çalışmamda mikrodenetliyici olarak st firmasının ürettiği STM32F429-DISCOVERY kullanacağım ve yapacağım çalışma mikrodenetleyicinin sadece üç pinini kullanarak 74HC595 ile  8 adet led süreceğim. Bunları yaparken  SPI(Serial Peripheral Interface)   donanımında yararlanacağım. Bu donanımdan stm32f429 altı tane SPI’a sahiptir.
Kısaca devre şeması aşağıdaki gibi oluyor.
 
 
 
 
 
Yazılım Keil uVision5 ile yazılmıştır. SPI modu kullanılarak yazılımıştır.
#include "stm32f4xx.h"
#include "defines.h"
#include "tm_stm32f4_delay.h"
#define KIRMIZI_LED_YAK  GPIO_SetBits(GPIOG,GPIO_Pin_14)
#define YESIL_LED_YAK  GPIO_SetBits(GPIOG,GPIO_Pin_13)
void gpio_config(void);
void spi_config(void);
void send_byte(uint8_t val);
uint8_t say=0;
int main() {    
                        SystemInit();
                   TM_DELAY_Init();
                        gpio_config();
                        spi_config();
                        while(1){         
                                                KIRMIZI_LED_YAK ;
                                                send_byte(say);
                                                YESIL_LED_YAK;
                                                say++;
                                                Delayms(100);
                                                if(say==256) say=0;
                        }
 
}
void gpio_config(void){
                        GPIO_InitTypeDef GPIO_InitStructure;         
                        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
                        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
                        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
 
                        /*PG13 VE PG14 CIKIS YAPILDI*/
                         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
                          GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
                          GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14;
                          GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
                          GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
                          GPIO_Init(GPIOG,&GPIO_InitStructure);
 
                        /*PB0 CIKIS YAPILID*/
                          GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
                          GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
                          GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
                          GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
                          GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
                          GPIO_Init(GPIOB,&GPIO_InitStructure);
                       
                          GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
                          GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
                          GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
                          GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
                          GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
                          GPIO_Init(GPIOA,&GPIO_InitStructure);
                        /*PA5 VE PA7 SCK VE MOSI YAPILDI*/         
                          GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1);
                          GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1);
}
 
 
void spi_config(void){
                          SPI_InitTypeDef SPI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);           SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_4;
                           SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b;
                           SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB;
                           SPI_InitStruct.SPI_Mode=SPI_Mode_Master;
                           SPI_InitStruct.SPI_Direction=SPI_Direction_1Line_Tx;
                          SPI_InitStruct.SPI_CPOL=SPI_CPOL_High;
                           SPI_InitStruct.SPI_CPHA=SPI_CPHA_1Edge;
                           SPI_InitStruct.SPI_NSS=SPI_NSS_Sof;
                           SPI_Init(SPI1,&SPI_InitStruct);
                 SPI_Cmd(SPI1,ENABLE);
}
 
void send_byte(uint8_t val){
    GPIO_ResetBits(GPIOB, GPIO_Pin_0); // ST_CP low
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    SPI_SendData(SPI1, val);
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    GPIO_SetBits(GPIOB, GPIO_Pin_0); // ST_CP high
}
 
 
Bu kod,  say değişkeni 100ms aralıkla 0’dan 255 kadar sayıp onları ledlerle ifade ediyor. Örnegin, eğer say 255 eşit olduğunda bütünledler yanar veya say 1 eşit olduğunda sadece QA’ya bağlı led yanar veya 2’ye eşit olduğunda  QB yanar.   
 
ÇALIŞMA VİDEOSU
 
 
 
HAKAN  AYDIN
 
Kaynaklar
[1].PIC PROGRAMLAMA TEKNIKLERI VE PIC16F877A, ALTAŞ YAYINCILIK
4. https://github.com/devthrash/STM32F4-examples/blob/master/SPI/main.c
 
 

13 Haziran 2015 Cumartesi

STM32F429 RTC BİRİMİ İLE SAAT





    Bu çalışmam da stm32f429 discovery kitini kullanarak analog ve dijital saat tasarımı yapıp bunu lcd ekranda göstermek. Bunun için stm32f429 entegresi içindeki RTC(Real Time Clock) birimini kullanarak yapmak. Bu çalışma da saat için  TM STM32F4 RTC kütüphanesinden yararlanıldı.

   DS1307 saat entegresini kullanarak saat tasarımı yapanlar bilirler ki bu iş için  32768 Hz bir kristal gereklidir. Aynı kristal yine bu çalışmamda kullanıldı. Tek farkı bu kristal stm32f429 entegresi içinde var veya eğer  siz bu kristali dışarıdan bağlamak isterseniz benim yazılım için bunu PC14, PC15 girişlerine bağlayarak yapabilirsiniz. DS1307 entegresi üzerinde Vbat girişi bulunur. Bu aynı girş yine  stm32f429 entegresinde de vardır.

   Benim yazdığım kod sadece basit bir saat tasarımı içindir. Bu kütüphaneyi kullarak daha iyi ve kararlı bir saat tasarımı yapabilirsiniz.

  Yine bu yazılım için Keil programı kullanıldı ve bu yazılım üzerinde oynanarak daha iyisi yapılabilir.

Keli Kod;
#include "stm32f4xx.h"
#include "defines.h"
#include "tm_stm32f4_rtc.h"
#include "tm_stm32f4_delay.h"
#include "tm_stm32f4_disco.h"
#include "tm_stm32f4_emwin.h"
#include "button.h"
#include "DIALOG.h"
#include
#include
#define TWO_PI 6.28318530717958647693
#define HALF_PI 6.28318530717958647693/4.0


int x0 = 120;
int y0 = 120;
float k;
float s ;
float m ;
float map(float x, float in_min, float in_max, float out_min, float out_max);
void gosterge_cizdir(void);
void gun(void);
char buf[50];

TM_RTC_Time_t zaman; 
int main(void) {

 /* Initialize system */
 SystemInit();

 /* Initialize delay functions */
 TM_DELAY_Init();

 /* Initialize LEDs */
 TM_DISCO_LedInit();

 /* Initialize emWin */
 if (TM_EMWIN_Init() != TM_EMWIN_Result_Ok) {
  /* Initialization error */
   while (1) {
      /* Toggle RED led */
      TM_DISCO_LedToggle(LED_RED);
      /* Delay */
      Delayms(100);
    }
 }
 /* Initialize RTC with internal 32768Hz clock */
 /* It's not very accurate */
 if (!TM_RTC_Init(TM_RTC_ClockSource_Internal)) {
  /* RTC was first time initialized */
  /* Do your stuff here */
  /* eg. set default time */
 }

 /*Çalistirilmaya baslamadan once ilk olarak asagidaki yerleri doldurun*/
     zaman.hours = 00;//00 ile 23 aras1nda secilir
   zaman.minutes = 42;//00 ile 59 aras1nda secilir
   zaman.seconds = 00;//00 ile 59 aras1nda secilir
   zaman.year = 15;
   zaman.month = 6;
   zaman.date = 13;
   zaman.day = 6;  // 1 den  7'ye. Sirasiyla  pazartesi,......,pazar

 TM_RTC_SetDateTime(&zaman, TM_RTC_Format_BIN);
 /* Her 125 ms'de bir kesme üreterek TM_RTC_RequestHandler() bu fonksiyona girer ve günclemeden yard1m eder */
 TM_RTC_Interrupts(TM_RTC_Int_125ms);


 GUI_SetBkColor(GUI_GRAY); // arka plan rengi
  GUI_Clear();

 GUI_SetPenSize( 5 ); // Dis cemberin kalinligi
 GUI_SetTextMode(GUI_TM_TRANS);
  GUI_SetFont(&GUI_FontComic18B_ASCII);
  GUI_SetColor( GUI_BLUE );// dis cember rengi
 
  GUI_SetTextMode(GUI_TM_TRANS);
  GUI_SetFont(&GUI_FontComic18B_ASCII);
  GUI_DrawArc( x0,y0,110, 110,0,360); //dis cemberi cizdir
 
 while (1) {
     gosterge_cizdir();// cember icinde olan noktalari ve sayilari çizdir.

      TM_RTC_GetDateTime(&zaman, TM_RTC_Format_BIN); /* STM32F429 ICINDEKI RTC BOLUMUNDEN
      zaman ile ilgili olan saat, dakika, saniye gibi bigileri almak icin kullanilir*/

    GUI_SetColor( GUI_RED );
    sprintf(buf, "TARIH: %02d.%02d.%04d\n", zaman.date, zaman.month,zaman.year + 2000);
    GUI_DispStringAt(buf, 10, 300);
     sprintf(buf, "SAAT: %02d:%02d:%02d\n",zaman.hours,zaman.minutes,zaman.seconds);
    GUI_DispStringAt(buf, 10, 280);
    GUI_SetColor( GUI_GRAY );
       GUI_SetPenSize( 4 );
     GUI_DrawLine( x0,  y0, cos(s)*60+120 , sin(s)*60+120);
    GUI_DrawLine( x0,  y0, cos(k)*40+120 , sin(k)*40+120);
    GUI_SetPenSize( 3);
    GUI_DrawLine( x0,  y0, cos(m)*50+120 , sin(m)*50+120);

       k = map(zaman.hours%12, 0, 12, 0, TWO_PI)-HALF_PI;
     /*Map fonk 0 ile 12 olan sayilar1 0 ile iki pi arasina uygun olarak ayarlar */
      s = map(zaman.seconds, 0, 59, 0, TWO_PI)-HALF_PI;
    m = map(zaman.minutes, 0, 59, 0, TWO_PI)-HALF_PI;
     /*Asag1daki ko parcas1nda cember 1c1ndeki akrep,yelkovan cizildi ve bunun icin
       trigonometriden yararlan1ld1*/
    GUI_SetColor( GUI_BLUE );
       GUI_SetPenSize( 4);
      GUI_DrawLine( x0,  y0, cos(s)*60+120 , sin(s)*60+120);
    GUI_SetPenSize( 3);
    GUI_SetColor( GUI_RED );
    GUI_DrawLine( x0,  y0, cos(m)*50+120 , sin(m)*50+120);
    GUI_SetColor( GUI_BLACK );
       GUI_SetPenSize( 4);
     GUI_DrawLine( x0,  y0, cos(k)*40+120 , sin(k)*40+120);
   
    gun();
 }
}
void gun(void){
   switch (zaman.day){
        case 1: GUI_DispStringAt("PAZARTESI", 10, 250);break;
        case 2: GUI_DispStringAt("SALI", 10, 250)     ;break;
     case 3: GUI_DispStringAt("CARSAMBA", 10, 250) ;break;
     case 4: GUI_DispStringAt("PERSEMBE", 10, 250) ;break;
     case 5: GUI_DispStringAt("CUMA", 10, 250)     ;break;
     case 6: GUI_DispStringAt("CUMARTESI", 10, 250);break;
     case 7: GUI_DispStringAt("PAZAR", 10, 250)    ;break;
       }
}
void gosterge_cizdir(void){
 char ac[4];
 int i;
 for (i=1; i<= 12; i++) {
     float a = (i*30)*3.1415926/180;
     int x = 100*cos(a)+x0;
     int y = 100*sin(a)+y0;
  
      if (i%3 == 0)
    GUI_SetPenSize( 5 );// saat 12,3,6 ve 9 1c1n büyük nokta
      else
      GUI_SetPenSize( 4 );// digerleri 1c1n 1se kucuk nokta koy
  
      GUI_DrawPoint(x,y);
    
     if (i%3 == 0) { //saat 12,3,6 ve 9 say1lar1 yazd1r 
          x = -80*cos(a)+x0;
          y = 80*sin(a)+y0;
          sprintf(ac, "%d", i);
          GUI_SetTextAlign(GUI_TA_VCENTER);
          GUI_DispStringHCenterAt(ac,y,x);
      }   
    } 
}
void TM_RTC_RequestHandler() {
       TM_DISCO_LedToggle(LED_RED | LED_GREEN);
    GUI_ClearRect(0, 250, 240, 300);
}

float map(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
/* User handler for 1ms interrupts */
void TM_DELAY_1msHandler(void) {
 /* Call periodically each 1ms */
 TM_EMWIN_UpdateTouch();
}


Çalışma Videosu

 




24 Mayıs 2015 Pazar

STM32F429-DISCOVERY İLE HC-SR04 MESAFE SENSORU


          


 Bu çalışmamda daha önce radar projemde kullanmış olduğum mesafe sensörünü kullanarak stm32f429 kiti ile bağlantı kurup ve mesafeyi ölçümü yapacağım. Bu kiti üç ay önce almıştım fakat üniversitem o zaman başladığı için vakit bulamadığımdan kullanmaya başlayamamıştım. Bu çalışmamda basit bir mesafe ölçümü uygulaması yapılarak stm32f429 ile ARM'a giriş yaptım ve bu çalışmamada şimdilik kod yazımında hazır kütüphaneler kullanıldı. Kod'u yazarlen derleyici olarak Keil uVision5 programında  faydalanıldı.





      Yukarıdaki resim STM32F429 Discovery kitidir. Bu kit üzerinde kullan mikrodenetliyicimiz STM32F429ZIT6  ve üzerinde L32D20 ST NEMS 3- axis Gyroscope, Led(kırmızı, yeşil), Buton, USB OTG micro-B girişi, 2.4"" TFT LCD  vardır. STM32F429ZIT6  mikro denetleyicisi 2MB flash belleği, 256 KB RAM'i, 3 ADCs, 17TIMs,Uart, ethernet vardır. Bu denetliyici  ARM Cortex-M4 32-bit'tir. Dokunmatik ekranın özelliği TFT LCD (Thin-film-transistor liquid-crystal display) 240x320 dots.  Toplam 157 tane giriş ve çıkış pini vardır.



       Mesafe ölçümünde kullanacağım sensör HC-SR04'dür. Radar projemde genel olarak nasıl çalıştığını anlatmıştım. Şimdi kısaca tekrar yazacağım;


 40Khz frekansında bir ses sinyali verici sensörü ile ortama iletilir sonra bu gönderilen ses sinyali cisme çarparak geridöner ve

 
sensörü bu sinyali algılar. Mikro denetliyicimiz bu gönderilen ve gelen ses sinyalinin arasındaki zaman farkını hesaplayarak mesafe bulunur. Buda matematiksel olarak şöyle bulunur. Mikrodenetliyimiz HC-SR04 sensörü ile cisim arasındaki ses sinyalinin gidiş ve dönüş arasındaki zamanı ölçsün ve biz buna "t" diyelim. Ve daha sonra biz bu "t"'yi ses hızı ile çaparak 2'ye bölersek mesafeyi bulmuş oluruz. MESAFE=(t*Ses_Hızı)/2

Keil'de yazılan kodumuz ;


/* Include core modules */
#include "stm32f4xx.h"
#include
#include
/* Include my libraries here */
#include "defines.h"
#include "tm_stm32f4_delay.h"
#include "tm_stm32f4_disco.h"
#include "tm_stm32f4_emwin.h"
#include "tm_stm32f4_hcsr04.h"
/* GUI modules */
#include "button.h"
#include "DIALOG.h"
char ac[4];
char k[4];
int distance;
int x0 = 120;
int y0 = 120;


int main(void) {
  uint8_t i;

 /* Initialize system */
 SystemInit();
 
 /* Initialize delay functions */
 TM_DELAY_Init();

 /* Initialize LEDs */
 TM_DISCO_LedInit();
 /* Initialize emWin */
 /*This function initialize LCD, SDRAM, STMPE811 touch and GUI  !!!*/
 if (TM_EMWIN_Init() != TM_EMWIN_Result_Ok) {
  /* Initialization error */
  while (1) {
     /* Toggle RED led */
     TM_DISCO_LedToggle(LED_RED); 
     /* Delay */
   Delayms(100);
  }
 }

 if (!TM_HCSR04_Init()) {
  /* Sensor is not ready to use */
  /* Maybe wiring is incorrect */
  while (1) {
      TM_DISCO_LedToggle(LED_GREEN);
      Delayms(100);
  }
 }

   GUI_SetBkColor(GUI_WHITE);
   GUI_Clear();
    
 while (1) {
      GUI_SetPenSize( 5 );
      GUI_SetTextMode(GUI_TM_TRANS);
      GUI_SetFont(&GUI_FontComic18B_ASCII);
      GUI_SetColor( GUI_BLUE );
  
     GUI_SetTextMode(GUI_TM_TRANS);
     GUI_SetFont(&GUI_FontComic18B_ASCII);
     GUI_DrawArc( x0,y0,110, 110,-30, 210 );
 
   for (i=0; i<= 22; i++) {
     
     float a = (-30+i*10)*3.1415926/180;
     int x = -100*cos(a)+x0;
     int y = -100*sin(a)+y0;
   
      if (i%2 == 0)
        GUI_SetPenSize( 5 );
      else
        GUI_SetPenSize( 4 );
   
      GUI_DrawPoint(x,y);
     
      if (i%2 == 0) {
          x = -80*cos(a)+x0;
          y = -80*sin(a)+y0;
          sprintf(ac, "%d", 10*i);
          GUI_SetTextAlign(GUI_TA_VCENTER);
          GUI_DispStringHCenterAt(ac,x,y);
      }     
    }   
   
       distance = TM_HCSR04_Read();
       GUI_ClearRect(0, 200, 320, 240);
       GUI_SetColor( GUI_RED );
       sprintf(k, "%d",distance);
   
       GUI_SetFont(&GUI_Font8x16);
       GUI_DispStringAt("The result is: ",5,210); // Disp text
       GUI_SetColor( GUI_BLACK );
       GUI_SetFont(&GUI_Font24_1);
       GUI_DispStringAt(k,130,210);
       GUI_SetColor( GUI_RED );
       GUI_DispStringAt("cm",170,210); // Disp text
 
       GUI_SetColor( GUI_BLUE );
       GUI_SetPenSize( 4 );
       GUI_DrawLine( x0,  y0, -65*cos((-30+distance)*3.1415926/180)+120 , -65*sin((-30+distance)*3.1415926/180)+120);  
       GUI_Delay(10);
      GUI_SetColor( GUI_WHITE );
      GUI_DrawLine( x0,  y0, -65*cos((-30+distance)*3.1415926/180)+120 , -65*sin((-30+distance)*3.1415926/180)+120);


   }
}

Çalışma Videosu





 

21 Ocak 2015 Çarşamba

Durum Cayrosu(Artificial Horizon)




Durum cayrosu
 1. Bayrak
2. Uçak maketi
3. Ayar düğmesi
4. Kayış (yaw) göstergesi
 
Yan taraftaki resim de durum cayrosu veya diğer adıyla artifical horizon gösterilmiştir. Wikipedia'dan alıntı yaparak, Durum cayrosu veya durum göstergesi, pilota uçağın Dünya'ya göre oryantasyonu konusunda bilgi veren  uçuş göstergesi. Sunî ufuk olarak da bilinir.

Durum cayrosu en basit haliyle; yeri sembolize eden koyu kısım, gökyüzünü sembolize eden açık renk kısım ve bunların birleşimi (suni ufuk) üzerinde bulunan bir uçak maketinden meydana gelir. Pilota uçağın yatışı ve yunuslaması konusunda bilgi verir.

Bu sistem, Uçağın ufkana göre olan pitch(uçağın burunun aşağıya veya yukarıya kalkması) ve roll(uçak sağa veya sola yatması) hareketini gösteren ve jiroskopik sistemle çalışan bir göstergedir.










Bu çalışmada benim amacım geçen yazımda anlattığım MPU6050'yi Ardiuno ile kullanarak ve Processing diliyle tasarlanmış olduğum durum cayrosu göstergesi(Artifical Horizon) arasında serial port ile bağlantı yaparak aynı uçaklarda olduğu gibi bir durum cayrosu tasarlamak.

Benim Tasarlamış Olduğum Durum Cayrosu 

Ben sadece Pitch ve Roll hareketleri kullandım bu çalışmada. Ardiuno ile yapmamın sebebi yine bu proje de kodların herkese açık olmasından.

Bu çalışmada yazdığım kodları ben direk olarak yazdığım gibi yayımlamayacağım fakat şifreli dosya olarak ekleyeceğim. Eğer isteyen olursa benimle irtibata geçebilir bununla ilgili.

indir

Video


Kaynak
  1. http://tr.wikipedia.org/wiki/Durum_cayrosu
  2. http://www.tayyareci.com/akademi/ucusgos1.asp

20 Ocak 2015 Salı

MPU6050 İle Servo Motor Kontrolü

Bu çalışmamda, bir önce ki yazımda anlattığım ivme ölçer ve cayro sensörlerini Ardiuno ile nasıl bağlantı kurullacağını ve bunun ile ilgili bir servo motor kontrol çalışma yapacağım. Servo motor çalışmasına geçmeden önce bu çalışmada kullanılacak olan GY-521 modülünü sonra servo motor kontrolüne geçeceğim.



GY-521 Modülü


Yukarıdaki resim de GY-521 modülü gösterilmiştir. Bu modül için de bir adet MPU-6050 çipi mevcuttur ve o çip içinde birer tane MEMS accelerometer (ivme ölçer) ve bir tane MEMS gyro bulundurmaktadır. Bu yüzden Quadrotor veya  bir denge robot gibi projelerde, bu modül çok güvenli sonuçlar verir. Bu sensör aynı zaman 6 DOF olarak da adlandırabiliriz çünkü 3 ekse cayro ve 3 eksen ivme ölçere sahip.   

Bu modül kartı bir voltaj regülesi devresine sahiptir. Bu nedenle 3.3V yada ile 5V birlikte kullanılabilir. I2C-bus’ında 2k2 pull-up direnci vardır. 2k2 direnci çok düşüktür. Eğer diğer pull-up direnci olan sensörlerle kombine yapılıp kullanılmak istenirse toplam pull-up empedansı düşük olabilir. Bunun şemasını bulmak zordur. O yüzden piyasa böyle çeşitli modüller bulanmaktadır. Ben başlıkta da yazdığım gibi Gy-521 modülünü kullanıyorum.

MEMS(Mikro elektronik mekanik sistem) yapıya sahiptir ve her kanalda 16 bit analoğu dijitale çeviren donanım bulunmaktadır.  Bu modül en güzel yanlarında biri; Kullancı için şu seçimleri yapmamıza imkan sağlıyor, skala aralığı gyro için ±250, ±500, ±1000, ve  ±2000°/sec aynı şekilde ivme ölçer için  ±2g, ±4g, ±8g, ve ±16g. Bunlar istenildiği değer için seçilebilir.
İvme ölçer ve gyro için gerekli ham değerleri okumak kolaydır. Önce uyku modu devre dışı bırakılmalı ve daha sonra ivme ve gyro değerleri okunabilir. Modül, 1024 byte’lık FIFO tampon bulundurmaktadır kullanıcıya düşük güç tüketimi sağlar ve okunan açı ve ivme bilgileri FIFO tampon içerisinde saklanabilmektedir. Tampon, bir mikrodenetleyici tarafından okunarak, FIFO tampon kesme sinyaliyle beraber kullanılabilmektedir. Tamponda veri olduğunda sensörün “int” pininden kesme sinyali gönderilir ve kullanılacak mikrodenetleyici (ben Ardiuno kullanacağım), okunacak bir veri olduğunu anlar.
Biraz daha karışık yöntem ise ikinci bir I2C cihaz ile tespit etmektir. MPU-6050 her zaman I2C-bus a bağlı SDA ve SCL pinleri ile bir mikrodenetletici‘ye slave olur. Ama bunun yanında normal I2C kendi I2C sini kontrol etmek için ikinci bir master I2C-bus’a sahiptir. İkinci I2C-bus için AUX_DA ve AUX_CL pinlerini kullanır. Bir magnetometer ile kontrol edilebilir ve magnetometer değerleri bir mikrodenetletici’ye aktarılabilir.
Bazen hesaplanacak işlemler çok karmaşık olabilir. Fakat sensör bir tane “Digital Motion Processor ” (DMP) (dijital hareket işlemci)’ye sahiptir. Ve bu DMP ile karmaşık hesaplamaları yapmak mümkündür (DMP, firmware ile programlanabilir). DMP nin nasıl programlandığı konusunda fazla bilgi bulunmamakta piyasada fakat yine de tersine mühendislik ile firmeware’yi bulmaya çalışanlar olmuştur ve deneyebilirsiniz. Bu DMP ile çip üzerinde hızlı hesaplamalar da yapabilirsiniz. Bu işlem kullanılan mikrodenetleyicinizin üzerindeki iş gücünü azaltır.
Benim amacım bu çalışmamda bu modül üzerindeki sadece ivme ölçerin x-ekseninden datayı alıp servo motor kontrol edeceğim. Bunu yaparken Ardiuno Uno mikrodenetleyicisinden yararlanacağım çünkü bu modül  için nette çok fazla kaynak vardır ve bu kaynaklar herkese açıktır. Bunlardan biri ise şu linkteki kütüphanedir. Eğer benim yazdığım ardiuno kodu çalıştırmak isterseniz bu linkteki kütüphaneyi sizin ardiuno kütüphanenize eklemeniz gerekir.

Ardiuno Kod:


/*
 http://muhhakanaydin.blogspot.com.tr/
 PROJE: MPU6050 ILE SERVO KONTROL TEK EKSENDE
 TARIH:12/01/2015
 MPU6050 BAGLANTISI;
   MPU6050     ARDIUNO
    GND------- > GND
    VCC--------> +3V3
    SDA--------> A4
    SCL-------- > A5
    INT--------  >PIN 2
   
    NOT: MPU6050 ÜZERİNDEKİ AD0 PINI GND 'ye BAĞLANIR.
*/
//*********** KÜTÜPHANE DOSYALARI EKLENİR********************************
#include   Servo.h

#include   I2Cdev.h
#include   MPU6050.h
#include   Wire.h // MPU6050 I2C ILE ILETISIM KURDUGUNDAN BU KÜTÜPHANE GEREKLİ
//****************************************************************************************
MPU6050 ACC_GYR;
Servo S_K; // nesne yaratılır.
//16-BITLIK DEGISKEN KULLANILIR. ÇÜNKÜ GYRO VE IVME OLÇERDEN ALINAN DATALAR 16-BITLIK.
int16_t accx, accy, accz; 
int16_t gyrx, gyry, gyrz; 
const int servocikis=9; // SERVO CIKIS PALS PINI. SINYAL
int deger, eskideger; 

void setup(){
    Serial.begin(9600);
    Serial.println("MPU6050 HAKAN AYDIN");
    Serial.println("http://muhhakanaydin.blogspot.com.tr/");
    ACC_GYR.initialize(); //
    Serial.println(ACC_GYR.testConnection() ? "BASARILI":"BASARISIZ");
                  // EGER BAGALANTI BASARILI ISE mpu.testConnection()=1 OLUR
                  // VE "BASARILI" AKTIF OLUR. DEGILSE "BASARISIZ" AKTIF OLUR
    S_K.attach(servocikis);
    S_K.write(90); // 90 DERECE KONUMUNA GETIR.
    delay(50);
}

void loop(){
    ACC_GYR.getMotion6(&accx, &accy, &accz, &gyrx, &gyry ,&gyrz); // HER BIRI 16-BIT OLANA DATALARI AL
   
    deger=map(accx,-17000,17000,0,180);// SADECE X EKSENINDEKİ DEGEERİ 0 ILE 180 ARASINDA SINIRLA.   
   
    if(deger!=eskideger){ // EGER ILK DEGER VE BIR ONCEKİ DEGER AYNI ISE BURAYAI GIRME SERVO AYNI KONUMDA KALSIN
                          // FARKLI ISE SERVOYU ONA GORE AYARLA
      S_K.write(deger);  // SERVOY'A X EKSENDEN ALINAN DEGERİ GONDER VE ONA GÖRE KONUMLANSIN.
      eskideger=deger;
      Serial.println(deger);
    }
   
    delay(50);
}

 

Video



Kaynaklar 

http://playground.arduino.cc/Main/MPU-6050#easy



19 Ocak 2015 Pazartesi

Complementray Filtresi, Gyroscope, Accelerometer


         Complementray Filtresi,  Gyroscope,  Accelerometer 

    Bu yazımda uzun zamandır araştırmaya planladığım fakat bir türlü yapamadığım çalışmamı, sömestr tatili sayesinde 7-8 gün içinde nerdeyse tamamlamış bulunmaktayım. Nerdeyse dememin sebebi, araştırdığım konu tam anlamıyla istediğim şeyleri bir türlü kavrayamadıysam bile belirli bir yere kadar getirdim. Bu yer şimdilik beni belli başlı projeleri yapmamda çok yardım etti. Çok uzun bir konuydu,  geçmişi çok olan bir konu.  Aslında bakarsanız kolay konu fakat benim amacım detayları öğrenmek olduğundan biraz karışık geldi. Ben bu yazımda ve çalışmalarımda bu detayı daha anlaşılır ve açık bir biçimde anlatmayı planlıyorum ve bunun yanında bu araştırmayla ilgili hazırladığım 2 veya 3 projeyi yayımlayacağım.
   Şimdi gelelim bu araştırma ne sorusuna.  Aslıdan günlük hayatımız da pek çok kez kullandığımız fakat nasıl çalıştıklarını bilmediğimiz ama onlarsız da olmayacağımız bildiğimiz iki adet elektronik sensörlerdir. Bunlar Gyroscope ve Accelerometer, türkçesi ile sırasıyla jiyroskop(cayro) ve ivmeölçer. Bu sensörler hayatımızın bildiğimiz ve bilmediğimiz her alanında çok sıklıkla kullanılmakta. Kullanıldıkları yerler; Birinci olarak, bilmiyorum farkında mıyız ama bu sensörler cep telefonlarında ve tabletlerde kullanılmakta. Basit olarak ne iş yaptığını gelecek olursak, bu sensörler telefonunuzun yönünü takip etmekle sorumludurlar ve bu günlerde her telefonda bu özellik mevcut. Yani cep telefonundaki bu sensörler, siz cep telefonunuzu sağa, sola, yukarıya ve aşağıya çevirdiğiniz anda cep telefonunuzun ekranı o yönde hareket eder, eğer bu özellik aktif ise telefonunuzda.  Aynı şekilde telefonunuzda eğer bir araba yarışı gibi oyunlar mevcut ise o oyunları telefondaki tuşları kullanmadan sadece telefonunuzun yönünü değiştirerek oynaya bilirsiniz. Bu sensörlerin telefonlardaki uygulaması bunlardır fakat daha fazla uygulama yapılabilir telefonlar ile ilgili. İkinci olarak kullanıma gelirsek, bu sensörler genel olarak uçaklarda ve bunun gibi askeri işlerde çok sıklıkça kullanılır. Kullanılmasının sebebi ise havada uçan helikopter, uçak artık ne olursa bir şeyi dengede tutmak istiyorsanız bunu bu sensörlerle yapabilirsiniz. Veya iki tekerlek üzerinde duran bir platform yapmak istiyorsunuz diyelim, iki tekerlekli üzerinde dengeli olarak sabit kalması için bu sensörleri kullanmanız şart. Ben o yüzden bu sensörlerin tam olarak nasıl çalıştığını anlamadığımdan dolayı böyle bir projeyi yarım olarak bırakmıştım(Balance Robot Hazırlıkları) ama en kısa zamanda ona tekrar dönüş yaparak bu araştırmamda öğrendiklerimi orada deneyeceğim.  Kullanıldıkları başka alanlara gelecek olursak; Hız, konum, çarpma, titreşim ya da yerçekimi ivmesinin de ölçülmesi amaçla da kullanılabilir. Gördüğünüz gibi bu sensörler hayatın bildiğimiz ve bilmediğimi her alanında sıkça tercih edilmekte. İşte bu sensörler bulunmuş olmasaydı, bu yazdığım kullanım alanların da bu sensörler kullanılmayacaktı. Kısacası, bu sensörler hayatın her alanında insanlara fayda sağlamaktadır.
    Sıklıkça, sıklıkla gibi kelimeleri bu yazımda şimdiye dek çok kullanmadım ve bu yüzden bu kelimeleri çok yazma ve düşünme sebebi beni bu araştırmaya çok fazla teşvik etti.  
   
  Bu sensörlerin nasıl çalıştıklarıyla başlamak istiyorum. İlk olarak Accelerometer ile başlayacağım sonra Gyroscopes ile devam edip ve sonra bunların aralarındaki benzerliklerinden ve farklılıklarından bahsedeceğim ve en son ise complementray(tamamlayıcı) filtresiyle bitireceğim.  

 Not: Bu yazımda bazı kaynaklardan alıntılara da yer verilmiştir.  
 

Accelerometer(İvme ölçer)


    Accelerometer  bulunduran sistemin, artık o sensör kaç eksene sahip ise örneğin 3 eksene sahip ve bunlar x,y,z eksenleri olsun, bu durumda o eksenlerden  koordinat bilgisi ve hareketin o anki ivmesini verir bize. Sisteme hangi yönde ivme kazandırırsanız o eksende sensörden bilgi alırsınız. Örneğin; bir sistem veya bir uçak düşünün z-ekseni boyunca hızlandırırsanız sensörün z-ekseninden o ivme ile ilgili veri alırsınız. Buradan da anlaşılacağı üzerine Accelerometer sensörü sahip olduğu eksen sayısı kadar çıkışlarından o sisteme ait ivme bilgisini alıyoruz.

  Accelerometer  sensörleri ile hem sistemden kaynaklanan ivmeyi hem de yerçekimi ivmesini ölçeriz ve bunları trigonometriyi kullanarak o ivmelenen sistemin yerçekimi ile yaptığı açıları sensörün x,y ve z eksenlerinden aldığımız datalar ile bulabiliriz. Örnek olarak bu sistem bir cep telefon olsun ve bu cep telefonda bir tane  Accelerometer bulunsun. Bu Accelerometer x,y ve z eksenden alığımız datalara göre belli başlı matematiksel işlemlerden geçirerek cep telefonunun 3 boyutlu uzayda nasıl durduğunu bilebiliriz.

    Tekrar söylecek olursak, Accelerometer üzerlerine düşen statik(yerçekimi) veya dinamik (aniden hızlanma veya durma) ivmeyi ölçmektedirler. Sensörden okunan değerler derece olarak ölçülmez. Sensörden okunan değer m/s^2 veya yer çekimi (g-Force) türünden belirtilir.



   Şimdi uzayda olduğunuzu düşünün. Herhangi bir çekim etkisi yok ve ağırlığınız 0 dır. Önünüzde de yukarıdaki bir kutu, kutunun ortasında da bir küre olduğunu hayal edin. Herhangi bir çekim veya kuvvet etkisi olmadığından küre herhangi bir yüzeye temas etmeden hareketsiz bir şekilde durmaktadır. Şekildeki kutu da x, y ve z eksenleri de gösterilmiştir. Küre sanki havada asılı halde duruyor, bir kuvvetin etkisi altında olmadığından dolayı. 



Yandaki şekilde göreceğiniz gibi eğer bu kutu dünyada herhangi bir noktada ve kutunu negatif z ekseni zeminle paralel halde ise dünyada ki yerçekimi kuvveti sayesinde küreye bir kuvvet etki ederek küreyi aşağıya yani zemine doğru gider. Yani bir ivmelenme olur zemine karşı ve bu ivme dünya da hep vardır. Bu kuvvet ise herkesin bildiği gibi 1g ve 9.8m/s2 olarak bilinir. Yerçekimi ivmesi dünyada her yerde mevcut olduğundan  ivme ölçerden sürekli olarak data alınabilir. Yandaki küreyi sabit bir hızla x-ekseni boyunca ittiğinizi düşünün çıkışta 0 görmeniz gerekir. Çünkü biz ivmeyi hızın türevini alarak buluruz. Eğer hız sabit ise türevi sıfırdır yani ivme sıfır olur.  Hızda bir değişlik olursa ivmelenme olur. Bu yüzden bu sensör aniden ivmelenmeyi veya durmayı ölçüyor.

Sonuç olarak; İvme ölçerin eksenlerinden verdiği dataya göre cismin açısal konumuna göre yerçekimi ivmesi ile yaptığı açı hesaplanarak oluşturulurlar.  Dolayısıyla yerçekimi her yerde mevcut olduğundan ivmeölçerler hareketsiz iken de açısal konuma göre çıktı üretirler.



Yandaki şekilde ivme ölçerin üzerine etkiyen kuvvetlerin vektörel olarak gösterimi görülmektedir. Buradaki R vektörü toplam kuvveti ifade eder yani ivme sensörünün üzerine etkiyen kuvvet vektörüdür ve bileşenleri Rx , Ry  ve Rz  dir.  Rx , Ry  ve R bilindiği taktirde
Pisagor teoremini kullanarak R toplam vektörünün yeryüzüne göre konumu bulunabilir.
Daha önce de dediğim gibi ivme ölçer çıkış olarak g türünden ifade eder. Rx , Ry  ve Rz    g türünden ifade  edilir. Burada önemli olan ivme sensöründen   Rx , Ry  ve Rz   değerleri elde etmektir. Bu değerleri bildiğimiz taktirde trigonometrik fonksiyonları yardımı ile R vektörünün X,Y ve Z eksenleri ile yaptığı açılar hesaplanıp sensörün yeryüzüne göre konumu bulunabilir.
 




  Rx , Ry  ve Rz    değerleri sensörden direk olarak g türünden alınamaz. Örneğin ADXL335 adlı bir adet 3 eksende ivme ölçen bir sensör satın aldınız ve besleme gerilimimizin 5v olduğunu ve 10 bitlik bir ADC kullandığımızı varsayalım. Bu sensörün x, y ve z eksenlerinden g türünden değer alamazsınız. Bunun yerine bu sensör ADC ile bir mikrodenetleyici ile iletişim kurduğundan binary çıkış alırsın sensörün her bir ekseninden. Bu alınan binary değerleri besleme gerilimi ile çarpıp ve 210=1024 olduğundan  bu değer ile bölersek o çıkışlara ilişkin binary değil de gerilim olarak ifade edersiniz. Sonra bu değerden VzeroG den çıkarılır, bu değer ivmeölçerin 0g de vermiş olduğu bir gerilim değeridir. Bu da genellikle besleme gerilimimin yarısıdır. Son olarak elde edilen değeri sensörün hassasiyet  bölersek g türünden o çıkışları yani Rx , Ry  ve Rz   ifade ederiz ve açıları trigonometri ile bulabiliriz.
 
Not: Birimlere dikkat edin!
Rx = (AdcRx * 5v / 1024 - VzeroG) / Sensitivity =>   Birimi artık g     ------------à Axr = arccos(Rx/R) 
Ry = (AdcRy * 5v / 1024 - VzeroG) / Sensitivity = >  Birimi artık g      ------------
à Ayr = arcos(Ry/R)        
Rz = (AdcRz * 5v / 1024- VzeroG) / Sensitivity = >   Birimi artık g      ------------
à Azr = arccos(Rz/R)   











İvme ölçerin çalışması yapısı ; Konsept olarak, bir akselerometre kütle yay ve sönümden oluşan bir sistemdir. Sisteme ivmelenme uygulandığında yaya bağlı olan kütle ivmenin oluşturduğu kuvvetin etkisi ile yer değiştirir. Bu yer değiştirmenin ölçülmesi ile sistem üzerine uygulanan ivme elde edilir. Bu kuvvet yukarıdaki şekillerde gösterilen toplam R vektörüdür.


 
 
İvmeölçerlerin çalışmasında pek çok farklı yöntem kullanılmaktadır;
 
 
Piezoelektrik olan akselerometreler, içerisinde bulundurduğu mikroskopik kristal yapı üzerinde ivmelenme oluştuğunda bir çıkış voltajı üretirler. Piezoelektik ivmeölçerler içerisindeki mikroskobik kristaller maruz kaldıkları stres sonucunda orantılı olarak gerilim üretir. Üretilen bu gerilim değeri, önceden tanımlanmış olan gerilim değeri ile kıyaslanır ve ivmenin etkisi bulunmuş olur.

 


Bunu yapmanın başka bir yolu da kapasitans ölçmektir. Eğer iki adet mikroyapı birbirine çok yakın bir şekilde duruyorsa, bunların arasında bilinen bir değerde kapasitans vardır. Bu yapılardan birinin üzerinde ivmelenme sonucu oluşan kuvveti uygulanırsa, mikroyapı yer değiştirir ve bu da kapasitansın değişmesine neden olur. Kapasitans voltaj değerine çevrildiğinde bir akselerometre elde edilmiş olur.
 


Modern akselerometreler genellikle mikro elektro-mekanik sistem olarak imal edilirler ve oldukça küçük boyutlardadırlar. Bir MEMS akselerometrenin yapısına ait şekil yanda gösterilmiştir. Gösterilen sistemde sönüm etkisi akselerometre içerisinde saklı tutulan gaz ile yapılmaktadır.

 



MEMS ivmeölçerler genellikle tek bir eksen üzerinde ivmelenme ölçecek şekilde imal edilirler. Birden fazla eksende ölçüm yapılmak istenirse bu ivmeölçerler birbirine dik eksenlerde bağlanılarak ölçüm alınır. 
 
MEMS ivmeölçerler genellikle tek bir eksen üzerinde ivmelenme ölçecek şekilde imal edilirler. Birden fazla eksende ölçüm yapılmak istenirse bu ivmeölçerler birbirine dik eksenlerde bağlanılarak ölçüm alınır.
 
MEMS ivmeölçerlerin bir diğer özelliği çok büyük bir ölçüm aralığına sahip olmalarıdır. Binlerce g ölçebilecek yapıda ivmeölçerler mevcuttur. Bunun karşılığında düşük g durumlarında hassasiyet azalmaktadır. Bu yüzden akselerometre seçiminde hassasiyet maksimum g ölçümü arasında uygulamaya bağlı olarak bir seçim yapılmalıdır.
 

Akselerometre seçiminde dikkat edilmesi gereken noktalar;
 
·         Digital veya analog çıkışlı
·         Eksen sayısı
·         Hassasiyet
·         Bant genişliği
·         Ölçü skalası
 
İvme ölçerler ölçü skalası olarak ± 1g, ± 2g, ± 4g… gibi değerlere sahiptir. Yerçekimi ivmesini ölçme amaçlı eğim sensörü olarak kullanılması halinde çıkış aralığının ±1.5g civarında olması yeterlidir. Çarpma sensörü olarak kullanılması halinde (en yaygın olanı müzikal uygulamalardır) ±5g yeterlidir.
 
İvme ölçer sensörlerin bir, iki ve üç eksende ölçüm yapabilen türevleri de mevcuttur. Örneğin ADXL335 üç eksende ölçüm yapar. 
 
Sensitivity sensörün hassaslık belirtir. Hassasiyetin  yüksek olması, ivmedeki çok küçük değişimleri bile çok büyük tepki verir. Birimi V/g[volt/g]. Yüksek hassasiyete sahip ivme ölçerler genellikle füzelerde, uçaklarda kullanılıyor.
 
Bant genişliği: Yavaş hareket eden bir sistemde ivme değişimlerini algılayabilmek için bant genişliğinin 50 Hz,  yüksek hızda ise 100 Hz olması gerekir.
 
        Bu link deki video izlemenizde yarar vardır ivme ölçerin çalışma yapısını anlamanız için. 

  

Gyroscope(Jiroskop, Cayro)

 



 



Jiroskoplar basitçe bir tekerleğin ekseni etrafında hızlıca döndürülmesi sonucu ortaya çıkarlar. Tekerleğin etrafındaki çembere dik açıyla kenetlenmiş başka bir çember ve bu çemberlere dik açıyla tutturulmuş başka bir çember jiroskopu modeller. Yandaki resimde de bu gösterilmiştir.


Jiroskopun dönmeye başladığı eksenin jiroskopun durduğu yüzey ne açıyla oynatılırsa oynatılsın jiroskopun dönüş ekseni sabit kalır. Bu özelliğinden dolayı uyduların sürekli olarak dünyaya dönük kalması, uçaklarda ve çeşitli araçlarda yapay ufuk oluşturulması ve oto pilot gibi uygulamalarda kullanılmaktadır.
Jiroskoplar basitçe bir tekerleğin ekseni etrafında hızlıca döndürülmesi sonucu ortaya çıkarlar. Tekerleğin etrafındaki çembere dik açıyla kenetlenmiş başka bir çember ve bu çemberlere dik açıyla tutturulmuş başka bir çember jiroskopu modeller. Yandaki resimde de bu gösterilmiştir.
Jiroskopun dönmeye başladığı eksenin jiroskopun durduğu yüzey ne açıyla oynatılırsa oynatılsın jiroskopun dönüş ekseni sabit kalır. Bu özelliğinden dolayı uyduların sürekli olarak dünyaya dönük kalması, uçaklarda ve çeşitli araçlarda yapay ufuk oluşturulması ve oto pilot gibi uygulamalarda kullanılmaktadır.
Jiroskop veya Cayro, yön ölçümü veya ayarlamasında kullanılan, açısal dengenin korunması ilkesiyle çalışan bir sensördür. Jiroskopik hareketin temeli fizik kurallarına ve merkezkaç ilkesine dayalıdır
Jiroskoplar açısal hız hesaplayan sensörlerdir.  Sensörlerin çıkışından alınan değer derece/saniye[deg./s] türünden ifade edilir. Bu demektir ki derecenin zamana göre türevini alırsak biz açısal hızı elde ederiz.
 
 
Biz bu sensörü, bir şeyin bir eksen etrafında ne kadar hızladöndüğünü (RPM)  başka bir deyişle açısal hızını öğrenmek için kullanırız. Yan taraftaki şekilde 3 eksen jiyroskop için gösterilmiştir, iki eksende ölçüm yapabilen modelleri vardır. Wx,Wy ve Wz eksenlerdeki açısal hızları verir bize.

bu eşitliğin her iki taraf için integralini alırsak ;

 
elde ederiz.
 
. Görüldüğü gibi açısal hızdan dereceye geçiş yaptık. Yani eksenlerdeki açısal hızı bildiğimiz taktirde açıya geçiş yapabiliyoruz fakat burada önemli olan şu noktaya dikkat çekmemiz gerekir; Yukarıda yapılan integral işlemidir. Biz sürekli integral alamayız. Bu yüzden sayıların toplamından yararlanırız.
Yani bu 
Ts;örnekleme periyodudur. Bu eşitlik tabi yine bize hata getirecek çünkü jiyroskop’un datası örnekleme frekansından(Fs=1/Ts) daha hızlı değişirse biz bunu yakalamayacağız. Ve bu toplamamın sonucu doğru çıkmayacaktır. İşte bu hataya Drift denir. Bu yüzden bu örnekleme periyodunu doğru seçmeliyiz. Genellikle mekanik sistemlerde bu örnekleme frekansı 100Hz ile 200Hz arasındadır.

 
Gyroscope, anlık açı değişimi hesaplayabilirler fakat hareketsiz bir cisim için açısal hız 0 olacağından üretilen değer hep başlangıç değerine geri dönecektir. Yani sadece anlık o anda o eksende değişen değeri verir bize. Bizde o değeri yani açısal hızı bilirsek, o anlık değişen açıyı bulabiliriz. 

 


İki eksen X,Y cayro kullandığımızı düşünelim; Vektörlerin(Rxz, Ryz),  z ekseni ile yapmış olduğu açılar ise Axz ve Ayz dir. Jiyroskop açısal hız ölçer.  Bu açısal hızı zaman ile çarparsam o açısal hızın açısını elde ederim. Çünkü açısal hızın birimi derece/saniye‘dir.  Eğer ben zaman ile açısal hızı çarparsam dereceyi elde ederim.






t0 anındaki açımızın Axz0 olduğunu ve t1 anındaki açımızın ise Axz1 olduğunu düşünelim. O halde dönüş açımız;∆Q=(Axz1 – Axz0)=OkunanAçısalHız*( t1-t0) verir.

 
Örneğin elinizde bir eksen ölçen cayro var. Örnekleme periyodunuz da 0.01s olarak belirlediniz. Bu sensörün çıkışında okuduğunuz  değer yine derece/saniye olmayacaktır. Yine amacımız derece/saniye elde etmek olacaktır. Bunun için sensörümüzün çıkışında yine binary bir değer okuduğumuz varsayalım bu değeri volt türünden ifade etmek için o sensörü kaç volt(v) ile besliyorsak ve 10 bit ADC yardımıyla okuyarsak, binary değeri besleme gerilimi ile çarparak ve sonra 1024 bölerek gerilimi elde ederiz. Her jiyroskobun bir offset(V) gerilimi vardır sonra elde edilen bu gerilimi offset geriliminden çıkararak ve sonra sensörün hassasiyetine(V/deg/s) bölerek derece/saniyeye çeviririz. Artık elimizde o tek eksene göre istediğimiz değer var. Şimdi ise bu değeri örnekleme zamanı ile çarparak açıyı yani dereceyi elde ederiz. Bu açı sadece iki zaman arasında açıyı verir bize. Tek eksenli jiyroskoptan sürekli açı almak için ise; Bu iki zaman arasında bulanan açıyı, bir önceki bulanan açı ile toplarsak toplam açıyı elde etmiş oluruz. Not: Sensörlerin ofset gerilimi ve hassasiyetini o ilgili sensörün datasheet’in den öğrene bilirsiniz.
GyroToplamAçı    =   ÖncekiAçı    +   ŞimdikiAçı



GyroToplamAçı=ÖncekiAçı+((GyroBinaryDeğer*BeslemeGerilimi/1024)-Offset)*0.01/Hassaslık


Bu işlemlerde idealde iyi sonuç alabilirsiniz fakat  gerçek hayatta pekte bu mümkün sayılmıyor. Bunun çözümü ileride anlatacağım filtre sayesinde biraz daha iyi yapabiliyoruz


 


 

 

  Gyroscope bir sistemi dengede tutmak için kullanılır. Uçakların cayro durum göstergeli vardır. Burada o uçağın hava nasıl konumlandığını pilota gösterir. Yani, hava da düz mü uçuyor yan mı uçuyor gibi bilgileri pilot ondan alır. Aynı zaman da  cep telefonlarında da kullanılıyor uçaklarda olduğu gibi. Amacı yine uçaklarda olduğu gibi aynı dır. Cayroların bir diğer kullanım yeri ise; Quadrotorlardır. Amacı ise üç hareket ekseni olan ROLL,  PITCH ve YAW eksenlerindeki açısal değişimleri ölçmek. Bu ölçülen değerler Quadrotorların mikrodenetleyicilerine gelerek orada değerlendirilir. Eğer sizin talebiniz Quadrotorun veya uçağın havada dengeli şekilde kalmasını isterseniz bu sensör size çok yardımcı olacaktır. Son olarak bu sensörler, uçakların otomatik pilot sistemlerinde ve uyduların sürekli olarak dünyaya bakabilmelerinde kullanılmaktadır.
 
Gyroscope seçiminde dikkat edilmesi gerekenler; 

·         Dijital veya analog çıkışlı
·         Eksen sayısı
·         Hassasiyet
·         Bant genişliği
·         Ölçüm aralığı
·         Çalışma sıcaklığı
Ölçüm aralığı: Bu parametre maksimum ne kadar açısal hızı ölçtüğünü belirtir. Çalışma sıcaklığı: Çoğu elektronik cihaz belir bir sıcaklık arasında lineer olarak çalışır. Bu durum cayrolar içinde geçerlidir. Cayrolar için bu aralık oldukça geniş. Bu aralık genellikle; -40˚C ile 70˚C oldukça lineerliğie yöneliktir.

 

Gyroscope Ve Accelerometer Arasında Farklılıklar Benzerlikler


Aslında cayro ve ivme ölçerler aynı işi yapıyorlar, ikisi de hep bize matematiği kullanarak açı veriyorlar. Fakat bunu yaparken ikisi farklı şekilde yapıyor. Daha öncede bahsettiğim gibi cayrolar bize anlık açısal hızı verir. Burada şuna dikkat edin “anlık” ve sonra eksenlerde değişim yok ise sıfır olur. Bu durum ivme ölçerler için böyle değil çünkü ivme ölçer anlık değer ölçmez, her zaman çıkışlarından değer alabilirsiniz. Nedeni ise; sensör sürekli olarak yerçekimi ivmesi etkisi altında kaldığında her zaman çıkışlarından değer alabilirsiniz. Dolayısıyla yerçekimi her yerde mevcut olduğundan ivmeölçerler hareketsiz iken de çıktı üretirler. Örneğin bir denge robotunuz var ve o robot öne doğru eğilmeye başladı. Bunu iten bir kuvvettir. Kuvvet varsa ivme de vardır. Bu yüzden ivme ölçerden bir açı değişimi alırsınız ve haliyle bir eğilme olduğu için gyrodan da açı değişimi alırsınız çünkü açısal hız var eksenlerde. Fakat eğilme belli bir açıda bitti diyelim sonra kuvvet olmadığından gyroscopedan bilgi alamazsınız çünkü değişim yok fakat ivme ölçerden yine alabilirsiniz çünkü yer çekimi etkisi altında kaldığından sürekli değer alırısınız.


 
Kullanım farklılıkları ise;  Cayrolar gemileri, torpidoları, roketleri, kameraları yönlendirmek ve stabilizasyonlarını yapmak için kullanılır. İvme ölçerler ise yerçekimi ivmesini, sismik sinyalleri tespit etmek ve titreşimleri(vibrasyon) ölçmek için kullanılır.


 

   Gyro ve ivmeölçerler tek başlarına kullanılmaz. Genellikle birlikte kullanılırlar. Nedenleri ise şunlardır;

 


 

1.    İvmeölçerler;  kısa zaman da nesne üzerindeki çok küçük kuvvetler bile istenmeyen gürültüler yaratabiliyor.  Fakat uzun zaman sonra bu istenmeyen gürültüler yok olup gidiyor. Yani ivme ölçerler uzun zamanda daha kararlı bilgi veriyor,  kısa zamanda  ise istenmeyen gürültüler oluşuyor  veri üzerinde.


2.    Gyroscope;  Daha öncede bahsettiğim gibi bunlar açısal hız verir. Yani anlık değişimleri verir bize.  Bu yüzden anlık alınan bilgiler yani kısa zamanda alınan bilgiler daha doğrudur, kararlıdır jiyroskoplar için fakat uzun zaman sonra anlık değişim olmayacağında açısal hız sıfırdır idealde. Gerçekte ise bu böyle değil, çıkış da istenmeyen gürültülere sebep olabiliyor bu durum. Kısacası gyro dataları kısa zamanda daha iyi datalar veriyor uzun zaman göre.

3.    İvme ölçerler kuvvete karşı çok duyarlı olduğundan en ufak titreşimlerde dahi çok yüksek gürültüler oluşturmaktadırlar. Gyroların bu kuvvetlerden etkilenmez

İşte bu yüzden hassas iş yapmak istiyorsanız bu sensörler tek başlarına kullanılmaz. Bu yüzden bu iki sensörden alınan datalar birleştirilerek sanki tek bir tane sensör den alığımız data gibi yaparak daha net bir data alırız. İşte bu birleştirme çeşitli matematiksel formüllerle yapılır. Bunlardan bir tanesi de işte   Complementary(tamamlayıcı) Filtresidir.



Complemantry Filtresi





Bu filtre jiyroskop ve ivme ölçerden gelen dataları bir arada topluyor ve bu filtrelerinin çıkışında iki sensöre göre daha kararlı bilgi alabilirsiniz. İvme ölçer ve gyro bir arada olan ve çeşitli filtreler ile gürültüyü engelleyebilen gelişmiş sensörlere IMU adı veriliyor. Örneğin 3 eksen ivme ölçer ile 2 eksen cayroyu bu filtreye veya buna benzer filtreler ile bir araya getirirsek buna 5DOF(Degrees of Freedom) IMU diyoruz.

 

 
 







Yukarıdaki şekil-1 ve şekil-2 deki mavi sinyal ivme ölçerin datasından alınan datayı gösterir. Dikkat ederseniz şekil 2 de ivme ölçerden dolayı gürültüler oluşmuş fakat kırmızı sinyal ise bir filtre yardımıyla cayro ve ivme ölçer birleştirilerek oluşturulmuş. Bu sinyalde ise mavi sinyale göre daha kararlı bilgi alınmıştır.  




 

Complementray filtresi hem yüksek geçiren bir filtre hem de alçak geçiren bir filtreden oluşur. Bu filtrenin amacı; Kısa zamanda biz Gyroscope datasını kullanırız çünkü o kısa zamanda daha kararlı bilgi veriyor ve dış kuvvetlerden etkilenmiyor, uzun dönemde ise ivme ölçerlerin datasını kullanırız çünkü kısa dönemde ivme ölçerin çıkışında gürültüler oluşuyor. İşte bu filtre bu seçimi yapmamıza yarayarak sensörleri düzenli şekilde kullanmamızı sağlıyor.  


Alçak geçiren filtre kullanılmasının amacı uzun-süreli değişimlere izin verip kısa-süreli dalgalanmaları filtrelemektir. Yüksek geçiren filtrenin görevine değinecek olursak yüksek geçiren filtre alçak geçiren filtrenin tersi olarak çalışır. Kısa süreli sinyallerin geçişine izin verirken durgun sinyalleri filtreleyen bir filtredir. Jiroskoplarda ölçümlerin doğruluğunu etkileyen en önemli faktör kayma oranı (drift rate) idi. Yüksek geçiren filtre kaymaları elimine etmek için kullanılır.



Filtreli Açı = a × (Gyro Açısı) + (1 − a) × (Accelerometer Açısı)



 t=(a*Ts)/(1-a)   ve  (Gyro Açısı) = (Önceki Gyro Açısı) + ω×Ts


Ts: Örnekleme periyodu, her bir program döngüsü arasında geçen zamandır. Eğer örnekleme oranı 100Hz ise örnekleme periyodu 0.01sn dir,  




a: Bu kat sayısı alçak geçiren ile yüksek geçiren filtreyi ayırt etmemize yarar. Genellikle 0.96 veya 0.98 gibi kat sayılar seçilir.



t: Zaman sabiti. Örneğin; t=(a*Ts)/(1-a)=(0.98*0.01)/(1-0.98) =0.49 bu sonuç jiroskoplara ve ivmeölçerlere güvenilecek sınırları ifade etmektedir. Ve şunu ifade etmektir; Yarım saniyeden kısa periyotlar için jiroskop verileri  önceliklidir ve gürültülü ivmeölçer verileri filtre edilmektedir. Yarım saniyeden uzun periyodlar içinse ivmeölçer verileri jiroskop verilerinden daha önceliklidir.


Şimdilik bu sensörler ve bu filtre hakkında yazacaklarım bu kadar. Her insanda olduğu gibi  yanlışlarım olabilir. Eğer yanlış bir şey görürseniz veya aklınıza ters düşen bir şeyler görürseniz bana mesaj atarak bunu sora bilirsiniz. Umarım sizin için yararlı olmuştur…                                                                                                                                                                                                      


                                                                            HAKAN AYDIN
                                                                           ELEKTRONİK VE HAB. MÜH.
                                                                           YILDIZ TEKNİK ÜNİVERSİTESİ


                                                                                           

Kaynaklar


1)    ADXL320 İVME SENSÖRÜ İLE DİJİTAL SU TERAZİSİ TASARIMI/Yavuz EROL, Murat SERHATLIOĞLU/Fırat Üniversitesi






9)    OTONOM ARAÇLAR için ATALETSEL NAVİGASYON SİSTEMİ GELİŞTİRİLMESİ
10) http://recepkaratas.com/2014/04/05/tamamlayici-filtre/