Adından da anlaşılacağı gibi bu proje kapsamında android işletim sistemini kullanan akıllı cihaz ile ARM Cortex M4 çekirdeğine sahip STM32F4 geliştirme kiti arasında haberleşme sağlanacaktır.
Proje tasarım olarak iki temel kısımdan meydana gelmektedir. İlk kısım android işletim sistemini kullanan akıllı telefon için yazılacak uygulamadan oluşmaktadır. Uygulama akıllı tefonda çalışacak ve temel olarak bluetooth birimini kullanarak veri gönderimi gerçekleştirecektir. İkinci kısımda ise ARM işlemci çekirdeğine yazılan kodlar ve kit-motor bağlantıları sunulması amaçlanmıştır. Android
uygulaması Java programlama dili ile Eclipse editöründe ADT eklentisi kullanılarak yazılmıştır. ARM işlemci mimarileri ve STM32F4 Discovery kart hakkındaki inceleme bilgileri internette bol miktarda mevcut olduğundan bu konu üzerinde durmayıp uygulamaya giriş yapmakta fayda görüyorum.
Aşağıda sistemin blok diyagramı görülmektedir.
Akıllı cihazdan gönderilen verileri Stm32f4 kitte bulunan işlemcide yorumlanarak motor yön kontroleri yapılmıştır. Blok diyagramdan da anlaşılacağı gibi sistem temel olarak tek yönlü bir iletişime sahiptir.
Akıllı Cihaz Bloğu
Android işletim sistemine sahip
akıllı cihazda çalıştırılacak uygulama bu blokta yer alır. Eclipse' te yazılan
uygulamanın derlenerek oluşturulan .apk uzantılı dosyanın telefonda çalıştırılmasıyla
bağlantı kurularak veri gönderimi başlatılabilir. Akıllı cihaz üzerinde çalıştırılacak kontrol uygulaması için hazırladığım arayüz aşağıdaki gibidir.
Uygulamada “BLUETOOTH AÇ", "BAĞLAN", "STOP" ve 4 adet yön tuşu bulunmaktadır. "BLUETOOTH AÇ" butonu ile cihaz üzerinde bulunan bluetooth donanımı aktif hale getirilerek iletişime hazır hale getirilir. "BAĞLAN" butonu ile ise Stm32f4 üzerinde bluetooth haberleşmesini sağlayacak olan HC serisi HC-05 bluetooth modülünün mac adresi ile modüle bağlanılır. Eşleşme sonrasında ortam veri iletimine hazırdır ve artık yön tuşlarıyla veri gönderimi başlatılabilir.
Stm32f4 Üzerinde İşlemler
Blok diyagramdan görüldüğü üzere akıllı
cihazdan bluetooth aracılığı ile veri alımı gerçekleşmektedir. Bu haberleşme
için HC-05 bluetooth modülü kullanılmıştır. Modülün temel olarak kullanılan
uçları Tx ve Rx uçlarıdır. Modül hem master hem de slave
modda çalışabilmekte ve geniş iletişim hızına uygun kullanılabilmektedir.
Çalışma modu ve iletişim hızı gibi parametrelerini değiştirmek için AT
komutları kullanılır.
Kullandığım HC-05
bluetooth modülü isim olarak "HC 05" adında ve mac adresi ise
20:13:06:19:33:13' dir. Uygulamadan bağlantı isteği gönderildiğinde girilmesi
istenilen doğru şifre "1234" tür. Şifre ve isim yine AT komutlarıyla
değiştirilebilir.
HC-05
bluetooth modülünün Tx ucu STM32F4' te PB7, Rx ucu ise PB6 pinine bağlanmıştır.
Burada dikkat edilmesi gereken husus çapraz bağlantıdır. Modülün Tx i kitte
USART biriminin Rx ine, yine modülün Rx i kitin USART biriminin Tx ine
bağlanması
HC-05
bluetooth modülden alınan verilere göre yön tayini yapılır. Örneğin gelen veri
'F' ise ileri, 'B' ise geri, 'R' ise sağa, 'L' ise sola dönüş istenmektedir.
İleri yönde komut geldiğinde PD7 pini set edilerek 1 e kurulur ve aynı şekilde
geri hareket için PD1, sağ için PD3, sol için ise PD5 pinleri set edilir.
Burada dikkat edilmesi gereken nokta ise hem ileri hemde geri hareket için
ilgili bitlerin aynı anda lojik 1 olmasını engellemektir. Bunun için bir
hareketi başlatmadan önce diğer hareketin ilgili pini reset edilerek lojik 0 a
çekilmiştir. Örneğin geri yönde bir hareket başalayacağı zaman PD1 biti set
edilmeden önce PD7 lojik 0 a çekilmiştir.
STM32F4
kitin beslemesi için 9 volt pil kullanılmıştır. 9 volt L7805CV entegresi ile 5
volta regüle edilmiştir.L293D İle Motor Sürücü Devresi
L293D motor sürücü entegresi kullanılarak motor hareketleri sağlanmıştır. Entegre 5 volt ile beslenmiştir ancak motor dönüşleri için 9 volt giriş verilmiştir.
L293D entegresi içerisinde iki adet H köprüsü bulundurur ve iki adet motoru ayrı ayrı sürebilir. İleri ve geri yön hareketleri için bir H köprüsü, sağ ve sol için ise diğer H köprüsü kullanılmıştır. Motor girişlerine önceki konuda bahsettiğimiz yön pinleri bağlanmıştır. Ayrıntılı için katalog bilgileri incelenebilir.
Gerekli kod blokları ise aşağıdadır.
Android Uygulaması Kod Bloğu
Bluetooth ControlActivity Sınıfı
public class BluetoothControlActivity extends Activity {
/* Buton Tanımlama*/
public Button ileri, geri, sag, sol, calistir, list;
/*BA Adında Bluetooth Adaptörü Oluşturma */
BluetoothAdapter BA = BluetoothAdapter.getDefaultAdapter();
public boolean connected = false; // Bağlantı Durum Kontrolü
BluetoothSocket sock; // Bağlantı İçin Socket
char DATA;// Gönderilecek Veri Değişkeni
OutputStream mmOutStream;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth_control_layout);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
/*Butonlara İlgili ID lerinin Verilmesi*/
ileri = (Button) findViewById(R.id.ileriButon);
geri = (Button) findViewById(R.id.geriButon);
sag = (Button) findViewById(R.id.sagButon);
sol = (Button) findViewById(R.id.solButon);
calistir = (Button) findViewById(R.id.calistirButon);
}
/*İleri Buton OnClick Metodu */
public void ileri_method(View v) {
try{
new Task().execute('F');
}
catch(Exception e){
Toast.makeText(getApplicationContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
/*Sağ Buton OnClick Metodu */
public void sag_method(View v) {
new Task().execute('R');
}
/*Sol Buton OnClick Metodu */
public void sol_method(View v) {
new Task().execute('L');
}
/*Geri Buton OnClick Metodu */
public void geri_method(View v) {
new Task().execute('B');
}
/*Bluetooth ile Bağlan*/
public void baglanButon(View v) throws Exception {
onConnect();
}
/*Cihazda Bluetooth Açma */
public void calistir_method(View v) {
BluetoothConnect con = new BluetoothConnect();
con.openBT();
}
public void OFF(View v) {
if (BA.isEnabled()) {
BA.disable();
Toast.makeText(getApplicationContext(), "Bluetooth Kapatıldı",
Toast.LENGTH_SHORT).show();
} else
Toast.makeText(getApplicationContext(),
"Bluetooth Zaten Kapalı Durumda", Toast.LENGTH_SHORT)
.show();
}
/*Bluetooth Bağlantısı İçin onConnect Metodu ve Kod Bloğu*/
public void onConnect() {
if (connected) {
return;
}
try {
BluetoothDevice BD = BA.getRemoteDevice("20:13:06:19:33:13");
Method m = BD.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
sock = (BluetoothSocket) m.invoke(BD, Integer.valueOf(1));
sock.connect();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
/*Dış Dünya İle İletişim İçin Gerekli AsenkronTask Metodu*/
public class Task extends AsyncTask{
@Override
protected Void doInBackground(Character... params) {
try {
mmOutStream = sock.getOutputStream();
mmOutStream.write(params[0]);
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();}
return null;
}
}
5.1.2 BluetoothConnect Sınıfı
public class BluetoothConnect extends BluetoothControlActivity {
private BluetoothSocket sock;
private InputStream in;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth_control_layout);
}
/*Cihazın Bluetooth Aktifleştirmek İçin Gerekli Metot */
public boolean openBT(){
if(BA != null){
boolean isEnabled = BA.isEnabled();
if (!isEnabled) {
connected=true;
return BA.enable();
}
else if(isEnabled) {
return BA.disable();
}
}
return false;
}
/*Socketin Kapatılması*/
@Override
public void onDestroy() {
try {
if (in != null) {
in.close();
}
if (sock != null) {
sock.close();
}
} catch (IOException e) {
e.printStackTrace();
}
super.onDestroy();
}
}
Stm32f4 Kod Bloğu
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
void UART_GPIOInitialize(){
GPIO_InitTypeDef GPIO_InitStructure; //GPIO için structure tanımlama
/* B ve D portları için clockları aktif yapma*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* B portunun 6.pini alternatif yaparak USART1_Tx e bağla */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
/* B portunun 7. pinini alternatif fonksiyon ile USART1_Rx e bağla*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
/*GPIOD için ayarlar*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType= GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD,&GPIO_InitStructure);
/*USART1 Tx = PB6
* USART1 Rx = PB7*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*UART Birimi*/
void UART_Initialize(void) {
USART_InitTypeDef USART_InitStructure;
/* USART1 için çevresel clock sinyalini aktif etme*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* USART1 Seri İletişim Konfigrasyonu Bloğu*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
/* USART1 i aktifleştir */
USART_Cmd(USART1, ENABLE);
}
int main(void) {
char ch; // gelen verinin alındığı değişken
UART_GPIOInitialize();
UART_Initialize();
/*Başlangıçta Tüm Motor Uçları Pasif*/
GPIO_ResetBits(GPIOD,GPIO_Pin_3);
GPIO_ResetBits(GPIOD,GPIO_Pin_5);
GPIO_ResetBits(GPIOD,GPIO_Pin_7);
GPIO_ResetBits(GPIOD,GPIO_Pin_1);
USART_SendData(USART1,OK);
while (1) {
/* Veri Gelene Kadar Bekle*/
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) {
}
/*Gelen Veri Değerlendirme Bloğu
*F: İleri Yönde Hareket
*B: Geri Yönde Hareket
*R: Sağa Dönüş
*L: Sola Dönüş*/1
if(ch=='F'){
GPIO_ResetBits(GPIOD,GPIO_Pin_1);
GPIO_SetBits(GPIOD,GPIO_Pin_7);
USART_SendData(USART1, ch);
}
if(ch=='B'){
GPIO_ResetBits(GPIOD,GPIO_Pin_7);
GPIO_SetBits(GPIOD,GPIO_Pin_1);
USART_SendData(USART1, ch);
}
if(ch=='R'){
GPIO_ResetBits(GPIOD,GPIO_Pin_5);
GPIO_SetBits(GPIOD,GPIO_Pin_3);
USART_SendData(USART1, ch);
}
if(ch=='L'){
GPIO_ResetBits(GPIOD,GPIO_Pin_3);
GPIO_SetBits(GPIOD,GPIO_Pin_5);
USART_SendData(USART1, ch);
}
/*Veri Gönderimi Bitene Kadar Bekle*/
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {
}
}
}
Sonuçlar
Bu projede, ARM işlemci mimarisi üzerinde, akıllı cihazdan
bluetooth ile gelen verilere göre motor kontrolü konusu sunulmuştur. İşlemcinin
PB6 ve PB7 uçları kullanılarak veri alma
ve gönderme sağlanmıştır. İşlemcide HC-05 bluetooth modülünden gelen veriler
incelenerek motorlar L293D motor sürücü entegresi üzerinden sürülmüştür.
Android
uygulama akıllı cihazda çalıştırıldığında cihazın bluetooth açılarak bağlantı
gerçekleştirilmek istendiğinde "BAĞLAN" butonuna basıldığında
uygulama direk olarak HC-05 modülüne bağlanacaktır. Eğer daha önce eşleşme
sağlanmamış ise önceki konularda bahsettiğimiz gibi şifre isteyecektir.
Şifrenin girilmesinin ardından eşleşmenin başarılı olduğunu 2Hz aralıklarla
yanıp sönen led ile modül bildirir.
STM32F4 kite
besleme güçü verildiğinde main fonksiyonuna girecek ve seri iletişim ve port
konfigürasyonları otomatik olarak yapılacaktır. İletişim hızı 9600 baudrate
olarak ayarlanmıştır.
Projede
temel amacı herhangi bir ek donanıma gerek kalmaksızın günlük yaşantıda büyük
yer sahibi olan akıllı cihazları kullanarak motor kontrolü sağlamaktır. Aynı
zamanda bu proje geliştirilerek çeşitli otomatik kontrol mekanizmalarında
kullanılabilir.
Proje
geliştirilmeye açık bir yöntem izlenerek tasarlanmıştır. Bir çok özellik daha
eklenerek projenin kullanım alanları ve özellikleri geliştirilebilir. Örneğin
kontrol edilmesi istenen bir vana yada otomatik garaj kapısını, yalnızca son
kullanıcının cep telefonu yada tableti
ile uygulamayı kullanarak kontrol edebilmesi gerçekleştirilebilir. Proje aynı
zamanda robot teknolojisinede entegre edilerek robot kol hareketleri akıllı
cihazlar üzerinden gerçekleştirilebilir.
Android üzerinde çalışırken tasarımda yardımcı olan Davut DURGUN' a ve desteğini esirgemeyen İhsan BAL' a teşekkürlerimi sunuyorum.
Android üzerinde çalışırken tasarımda yardımcı olan Davut DURGUN' a ve desteğini esirgemeyen İhsan BAL' a teşekkürlerimi sunuyorum.