Merhabalar… Bu yazımda sizlere android işletim sistemli telefonum üzerinde gerçekleştirdiğim bluetooth kontrol uygulamasından bahsedeceğim.

Uygulamayı anlatmadan önce biraz android dünyası hakkında bilgi vereyim. Özellikle akıllı telefonlar üzerinde android işletim sistemi yaygınlaşmış durumda. Aynı şekilde android üzerinde program geliştirmek içinde bir sürü kaynak bulunmakta. Benimde bir süredir aklımdaydı. Fakat sanal cihaz üzerinde uğraşmak çekici gelmiyordu. Bir süre önce emektar telefonumun yerine anrdroid sistemli bir telefon alınca başladım uğraşmaya.

Biraz inceleyince gördüm ki android üzerinde yazılım geliştirmek için google tarafından sunulan bir sürü geliştirme aracı ve uygulama mevcut. Bunlardan incelediğim ikisinden birisi eclipse üzerinde java ile program geliştirme diğeri de app inventor isimli uygulama. App inventor, internet üzerinde program geliştirilen ve nerdeyse hiç programlama bilgisi gerektirmeyen, bir satır bile kod yazmadan program geliştirebileceğiniz bir araç. Bir nevi yap boz gibi blokları yan yana koyup program yapabiliyorsunuz. Diğeri ise eclipse üzerinde java ile program geliştirme aracı. Tahmin ediyorum en çok eclipse üzerinde program geliştiriliyor. Bu araçlar hakkında daha detaylı bilgiyi, eğitimi videolarını v.s. internette rahatlıkla bulabilirsiniz. Ben java bilgim olmamasına rağmen eclipse üzerinde geliştirmeye karar verdim. İlk önce temel düzeyde java bilgisi edinerek sonrasında android üzerinde program yazma ile ilgi bir kaç video inceleyip google’nın notlarını kurcalayarak biraz bişeyler kavradım.

Android ile uğraşma amacım android’li akıllı telefonlar gibi sistemler üzerinde kontrol uygulamaları yapmak. Örneğin telefon ile evde bir lamba yakıp söndürmek. Yoksa android üzerinde çok büyük oyunlar yazıp, çok gelişmiş uygulamalar geliştirme gibi bir niyetim yok. 🙂  Bu doğrultuda kolları sıvadım. İşe dış Dünya ile kablosuz bağlantı kurmak ile başladım. (sonuçta mobil telefonlar) Kablosuz aklıma gelen iki seçenek wifi ve bluetooth idi. Wifi’nin daha karışık olduğunu ve modüllerinin daha pahalı olduğunu düşünerek dış Dünya ile haberşlemek için bluetooth kullanmaya karar verdim.

Sonrasında bluetooth modül arayışına girdim. Biraz araştırınca HC-06 isimli modülü almaya karar verdim. Modülü yaklaşık 20 liraya temin ettim. Modülü başlıca özellikleri; 3.3v ile çalışması, uart ile haberleşmesi ve 1200-115200 baud arasında çeşitli çalışması ve slave olarak çalışması.

slave olarak çalışması modülün başka cihazlara bağlanamaması başka cihazlardan tarafından modüle bağlanması ve bağlantının yönetilmesi demek. Ben de uygulama da telefondan modüle bağlanacağım için modülün slave olması sorun değil. AT komutları ile modülün baud hızını, ismini ve şifresini değiştirebilirsiniz.

Slave modül olduğu için çok geniş komut seti yok. Modüle hiç bir komut göndermeden varsayılan olarak 9600 baud hızında, linvor ismi ile “1234” şifresi ile kullanabilirsiniz.

Modülü bir nevi kablosuz uart olarak düşünebilirsiniz. Cihaza bağlandıktan sonra telefondan gönderilen veri direk olarak uarttan okunur. Aynı şekilde uart üzerinden master telefona veri gönderilir. Mikrodenetleyici kısmında uart üzerinden modüle bağlanıp veri gönderip, almak yeterli fakat android kısmında işler biraz daha karışık.

Android tarafında bluetooth kullanabilmek için google tarafından geliştirilen kütüphaneler ve örnek kodlardan faydalandım. Java için google tarafından geliştirilmiş akıllı telefoların donanımlarını (wifi, bluetooth, ivme ve hız sensörleri v.s.) kullanmayı sağlayan bir sürü kütüphane ve örnek kod mevcut. Bende bu uygulamada google’nin bluetooth için hazırlanmış olduğu BluetootChat örneğinden faydalandım.

Yeni baştan uygulama yazabilmek için android üzerinde ileri seviyede programlama bilgisi gerekli. Bende sınırlı seviyede bilgim ile örnek kodları kendi amacıma yönelik değiştirerek uygulamayı yaptım. Uygulamanın çalışma görüntülerini aşağına görebilirsiniz.

Uygulamanın çalışması basittir. Uygulama çalışınca bluetooth açma izni ister. Bluetooth açıldıktan sonra menü tuşuna basarak cihaza bağlan tuşuna basılır. Sonrasında taranıp bulunan veya önceden eşleşilmiş cihazlara bağlanılır. Düzgün bi şekilde cihaza bağlandığında resimde görüldüğü gibi hangi cihaza bağlanıldığı ekranın sağ üst kısmında görülür.Ben aldığım modüle ErhanBT ismini verdim resimde görülebilir.  Uygulamada msp430 launch pad üstünde ki 2 ledin kontrol işlemi yapılır, kit üzerinde bulunan butonun durumu okunur ve denetleyicinin dahili sensörü ile sıcaklık bilgisi ölçülür. Bu bilgiler ekranda görüntülenir ve kontrol işlemi uygulama ekranında ki butonlar ile yapılır.

Uygulamada temel olarak 1 byte veri gönderir ve alınır. Gönderilen veri ile kit üzerinde ki ledler kontrol edilir. Alınan 1 byte veri ile de ledlerin ve butonun durumu ve sıcaklık bilgisi okunur. Alınan veriye göre ekran güncellenir. Uyguluma bu şekilde çalışmaktadır. Kod kısmında ise önemli olan veri alma ve gönderme yapılan kısımlardır.

Bluetooth modül ile 1024 byte paket veriler gönderilip alınabilir. Uygulamanın kodlarında değiştirdiğim kısımları inceleyerek uygulamayı kendinize göre değiştirebilirsiniz. Bluetooth modül ile 1024 byte veri alınıp gönderilebilir demiştim. Ben bu uygulamada sadece 1 byte veri alıp gönderdim. Sebebi ise denetleyici tarafında msp430g2231’in donanımsal uart modülünün olmaması. Uart donanımı zamanlayıcı kullanılarak yazılımsal olarak yapıldığından paket veri alma ve gönderme işlemlerinde veri kaçırma sorunu oluyordu. Bu yüzden sadece 1 byte veri alıp göndererek işlemlerimi yaptım. Bilgisayar ile yaptığım denemelerde bir sıkıntı olmadı paket halinde veri gönderip alabiliyordum.

Mikrodenetleyici tarafında ise basit bir örnek kod yazdım. Yaklaşık 100ms aralıklarla 1 byte veri gönderiliyor. Gönderilen verinin 8. biti ‘1’ ise veri android kısmında Led ve buton bilgisi olarak ‘0’ ise sıcaklık bilgisi olarak değerlendiriliyor. Dediğim gibi denetleyicinin uart donanımı olmadığından paket olarak veri alışverişinde sorun çıkardığı için bu şekilde bir gönderme işlemi yaptım. Ayrıca uygulamada gelen bir byte veriye göre kit üzerinde bulunan 2 Led’in durumu düzenleniyor. Modülü denetleyiciye bağlamak için rx ve tx pinlerini bağlamak ve 3.3 v gerilim ile toprak bağlantısını yapmak yeterli.

/****************************************************************
*  İsim    : BluetoothDemo deneme uygulaması	                *
*  Yazar   : Erhan YILMAZ                                       *
*  E-posta : erhanyilmaz.ytu@gmail.com                          *
*  Tarih   : 08-07-2012                          	        *
*  Sürüm   : 1.0                                                *
****************************************************************/
#include <io430g2231.h>
#include "stdbool.h"
 
#define LED1      0x01
#define LED2      0x40
#define BUTON     0x08
#define TXD 0x02 // TXD pini P1.1
#define RXD 0x04 // RXD pini P1.2
#define Bit_time 104 // 9600 Baud, SMCLK=1MHz (1MHz/9600)=104
#define Bit_time_5 52 // yarım bit zamanı
 
unsigned char BitCnt; // Bit sayaç değişkeni
unsigned int alinan;  // Alınan karakter
unsigned int gonderilen;  // Gönderilen karakter
unsigned char CharCnt; // Karakter sayaç
unsigned int RXByte; // veri alım değişkeni
unsigned int TXByte; // veri gönderim değişkeni
bool isReceiving; // veri alma durum biti
bool hasReceived; // veri alındı durum biti
void Transmit(void);
long ham,derece;
 
//gecikme fonksiyonu
void delay(unsigned long int d)
{
  d*=100;
  for(;d>0;d--);
}
 
void main (void)
{   WDTCTL = WDTPW + WDTHOLD; // Watchdog timeri durdur
 	BCSCTL1 = CALBC1_1MHZ; // 1mhz dahili osilatör
	DCOCTL = CALDCO_1MHZ; // SMCLK = DCO = 1MHz
    // AD çevirici sıcaklık ölçmek için ayarlanır.
    ADC10CTL1 = INCH_10 + ADC10DIV_3;
    ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON ;
	P1SEL |= TXD; // gönderme pini ayarları
	P1IES |= RXD; // Alma pini ayarları
	P1IFG &= ~RXD; // Clear RXD (flag) before enabling interrupt
	P1IE |= RXD; // Enable RXD interrupt
    P1DIR=0;	//Port1 tamam giriş
  	P1DIR |= TXD+LED1+LED2; // Gerekli pinler çıkış olarak ayarlanır.
	isReceiving = false; // Set initial values
	hasReceived = false;
    gonderilen=0;
    P1OUT=0;			//Port1 çıkışı temizle.
	__bis_SR_register(GIE); // interrupts enabled
 
// Ana döngü
  while(1){
	delay(100);
	//LED1'in durumuna göre gönderilen verinin 1. biti düzenlenir.
   if(P1OUT & LED1)
     gonderilen |= 0x01;
   else
     gonderilen &= ~0x01;
   //LED2'nin durumuna göre gönderilen verinin 2. biti düzenlenir.
   if(P1OUT & LED2)
     gonderilen |= 0x02;
   else
     gonderilen &= ~0x02;
   //Butonun durumuna göre gönderilen verinin 3. biti düzenlenir.
   if(!(P1IN & BUTON))
     gonderilen |= 0x04;
   else
     gonderilen &= ~0x04;
	//Gönderilen verinin 8. biti set edilerek buton ve LEd durum bilgileri gönderilir.
   TXByte = (gonderilen | 0x80); Transmit();
 
   ADC10CTL0 |= ENC + ADC10SC;            // AD çevrimi başlat
     if(ADC10CTL0 & ADC10IFG)		        // AD çevrim bitti mi?
      {
        ADC10CTL0 &= !ADC10IFG;		        // çevrim bayarğını temizle
        ham = ADC10MEM;		                // sıcaklığı oku
        derece = ((ham - 673) * 423) / 1024;	//Sıcaklığı dereceye çevir.
	//Gönderilen verinin 8.biti sıfırlanarak sıcaklık bilgisi gönderilir.
     TXByte = (int)derece & 0x7f; Transmit();
      }
 
   //Alınan veri değerlendirilir.
   if(hasReceived){
   alinan=RXByte;
   hasReceived = false;
   //Gelen verinin 1. bitine göre LED1 durumu düzenlenir.
      if(alinan & 0x01)
        P1OUT |= LED1;
      else
        P1OUT &= ~LED1;
	//Gelen verinin 2. bitine göre LED2 durumu düzenlenir.
      if(alinan & 0x02)
        P1OUT |= LED2;
        else
        P1OUT &= ~LED2;
    }
     }
      }     
 
//Bu fonksiyon TXByte degişkenindeki veriyi TXD pininden gönderir.
void Transmit(void)
{
	while(isReceiving); // Wait for RX completion
	TXByte |= 0x100; // Add stop bit to TXByte (which is logical 1)
	TXByte = TXByte << 1; // Add start bit (which is logical 0)
	BitCnt = 0xA; // Load Bit counter, 8 bits + ST/SP
	CCTL0 = OUT; // TXD Idle as Mark
	TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
	CCR0 = TAR; // Initialize compare register
	CCR0 += Bit_time; // Set time till first bit
	CCTL0 = CCIS0 + OUTMOD0 + CCIE; // Set signal, intial value, enable interrupts
	while ( CCTL0 & CCIE ); // Wait for previous TX completion
}
 
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
	isReceiving = true;
	P1IE &= ~RXD; // Disable RXD interrupt
	P1IFG &= ~RXD; // Clear RXD IFG (interrupt flag)
	TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
	CCR0 = TAR; // Initialize compare register
	CCR0 += Bit_time_5; // Set time till first bit
	CCTL0 = OUTMOD1 + CCIE; // Dissable TX and enable interrupts
	RXByte = 0; // Initialize RXByte
	BitCnt = 0x9; // Load Bit counter, 8 bits + ST
}
// Timer interrupt routine. This handles transmiting and receiving bytes.
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
if(!isReceiving)
{
	CCR0 += Bit_time; // Add Offset to CCR0
if ( BitCnt == 0) // If all bits TXed
{
	TACTL = TASSEL_2; // SMCLK, timer off (for power consumption)
	CCTL0 &= ~ CCIE ; // Disable interrupt
}
	else
{
	CCTL0 |= OUTMOD2; // Set TX bit to 0
if (TXByte & 0x01)
	CCTL0 &= ~ OUTMOD2; // If it should be 1, set it to 1
	TXByte = TXByte >> 1;
	BitCnt --;
 }}
	else
{
	CCR0 += Bit_time; // Add Offset to CCR0
if ( BitCnt == 0)
{
	TACTL = TASSEL_2; // SMCLK, timer off (for power consumption)
	CCTL0 &= ~ CCIE ; // Disable interrupt
	isReceiving = false;
	P1IFG &= ~RXD; // clear RXD IFG (interrupt flag)
	P1IE |= RXD; // enabled RXD interrupt
if ( (RXByte & 0x201) == 0x200) // Validate the start and stop bits are correct
{
	RXByte = RXByte >> 1; // Remove start bit
	RXByte &= 0xFF; // Remove stop bit
	hasReceived = true;
}
__bic_SR_register_on_exit(CPUOFF); // Enable CPU so the main while loop continues
}
else
{
	if ( (P1IN & RXD) == RXD) // If bit is set?
	RXByte |= 0x400; // Set the value in the RXByte
	RXByte = RXByte >> 1; // Shift the bits down
	BitCnt --;
	}}}

Uygulamaya ait proje kodlarını buradan indirebilirsiniz. Yazıda direk uygulamadan bahsetmek yerine birazda android hakkında bilgi vermeyi uygun gördüm. Örnek olması açısından basit bir uygulama yaptım. Uygulamayı geliştirerek daha farklı amaca yönelik gelişmiş kontrol uygulamaları yapabilirsiniz.Uygulama ile ilgili söyleyeceklerim bu kadar. Anlaşılmayan veya sormak istediğiniz kısımları sorabilirsiniz, elimden geldiğince cevaplamaya çalışırım. Faydalı olması dileğiyle, bir sonraki yazıda görüşmek üzere…