Arduino & Android ile Bluetooth Tabanlı Ev Otomasyonu
Merhaba, bugünkü yazımda sizlere Arduino ve bir Android cihaz kullanarak nasıl Bluetooth tabanlı bir ev otomasyon sistemi yapabileceğinizi anlatacağım.
Gerekli Donanım
Arduino Uno (başka bir model de işinizi görür)
HC-06 / HC-05 Blutooth modülü
1 Kanal 5V Röle kartı (Birden fazla cihaz kontrol etmek istiyorsanız çoklu kanallı ürünleri de kullanabilirsiniz)
A'dan B'ye USB Kablosu
Jumper kablolar
Breadboard
100 Ohm - 1K Ohm arasında bir direnç
Android bir cep telefonu / tablet
Arduino
Bu malzemeleri toparladıktan sonra projemizi yapmaya başlayabiliriz. Öncelikle kullandığınız bilgisayara Ardunio IDE'sini kurmanız gerekiyor. Detaylı bilgi için: https://www.arduino.cc/en/software
Bilgisayarınıza bu programı kurduktan sonra yapacağınız ilk iş Arduino'nuzu bilgisayarınıza "A'dan B'ye USB kablosu" yardımıyla bağlamak. Ardından File -> Examples -> Basics kısmından Blink sketchini açmak. Bu sketch'i ilk olarak çalıştırmamızın temel sebebi kullandığımız Arduino'ya bilgisayar üzerinden kontrol edebildiğimizi görebilmek böylece kendi kodlarımızı sonrasında rahatlıkla yükleyebileceğiz.
Bu sketchi yükledikten sonra sol köşedeki Çalıştır (Sağ ok) tuşuna tıklıyoruz ve bilgisayarımızın kodları Arduino'da çalıştırmasını bekliyoruz. En altta "Done Uploading" dediği zaman Arduino'nuzun 13.pinindeki küçük ledin yanıp sönüyor olması gerekiyor.
Ardından Ardunio'nuzda şu şekilde saniyede bir yanıp sönen bir led görmelisiniz.
Buraya kadar sorunsuz geldiyseniz, artık Ev Otomasyon sistemimizi yapmaya başlayabiliriz!
Devre Şeması
İlk iş olarak devremizi hazırlamamız gerekiyor. Genel devre şemasına geçmeden önce bazı modüller hakkında bilgi vermek istiyorum.

Bluetooth modülü için ben 4 pinli (HC-06) kullandım. Aşağıdaki devre şemasında da yine 4 pinli bu modülün bağlantılarını görebilirsiniz. Başka modeller kullandıysanız internetten bağlantı şemalarına bakmayı unutmayın.

Kullandığınız rölelere göre değişmekle birlikte, rölelerin düşük voltajlı ve yüksek voltajlı olmak üzere iki tarafı bulunuyor. Arduino ile düşük voltajlı bölgeden röleyi açıp kapatabiliyoruz.
Rölenin yüksek voltajlı pinlerinden de NC, C ve NO olarak geçen kısımda iki farklı bağlantı şekli mevcut: NO & C ve NC & C bağlantıları. Aradaki fark ise rölenin açıldığında voltajı bağlı olduğu cihaza vermesine veya kesmesinden geliyor. Eğer, NO (Normally open) pinini kullanırsak, röleye voltaj geldiği zaman lambamız da aynı anda yanacak. Eğer, NC (Normally closed) pinini kullanırsak bu zaman da röleye voltaj gelmediği zaman lambamız yanacak ya da diğer bir deyişle röleye elektrik gelmediği zaman, lambamız yanacak. Ben burada NO & C bağlantısını kullandım. Eğer kodları yükledikten sonra istediğiniz gibi çalışmazsa bu iki pini kontrol etmeyi unutmayın.
Burada bağladığımız led yanmasın diye 470 Ohmluk bir direnç kullandım ancak bu direnç yerine 100 Ohm ile 1K Ohm arasında bir direnç de kullanabilirsiniz. Her zaman kullandığınız cihazların üzerindeki işaretlere bakarak devrelerinizi hazırlamayı unutmayın.
Aşağıdaki resimde bulunan bağlantıları yaparak devrenizi kurabilirsiniz.

Donanım Kodlama: Arduino Sketch
Bu devreyi kurduktan sonra, Arduino IDE'mizi açıp "File" -> "New" yolunu izleyip yeni bir sketch oluşturuyoruz. Koda geçmeden önce biraz Arduino sketchleri ile ilgili genel bilgi vermek istiyorum. Bir Arduino sketch'inde varsayılan olarak iki fonksiyon bulunur. Bunlar setup ve loop fonksiyonlarıdır. Setup fonksiyonu yalnızca bir kez çalışır, loop fonksiyonu ise adı üstünde sürekli baştan sona çalışır. Bunu da öğrendiğimize göre çalışacak kod parçacığını inceleyebiliriz. Yorumları okuyarak ne yaptığımı daha iyi anlayabilirsiniz.
const int ROLE_PIN = 5; // Röleyi kontrol etmek için kullandığımız pin
// Arduino çalıştığında bir defaya mahsus çalışacak kodlar
void setup() {
// Röleyi kontrol edebilmek için pinimizi OUTPUT moduna alıyoruz
pinMode(ROLE_PIN, OUTPUT);
// Serial Monitor üzerinden veri göndereceğimiz için baundrate'i 9600 olan Serial iletişimi başlatıyoruz
Serial.begin(9600);
}
// Arduino içerisinde döngü şeklinde çalışan fonksiyonumuz
void loop() {
while (Serial.available() > 0 ) {
char data = Serial.read();
switch (data) {
// Eğer Serial iletişimden 0 karakterini alırsak Rölemizi kapatıp oradan geçen elektriği kesecek, böylece lambamız sönecek.
case '0':
// Röle pinini dijital olarak kapatıyoruz yani o pin artık bir gerilim vermiyor.
digitalWrite(ROLE_PIN, LOW);
break;
// Eğer Serial iletişimden 1 karakterini alırsak Rölemizi açıp oradan elektrik geçmesini sağlayacak böylece lambamız yanacak.
case '1':
// Röle pinini dijital olarak açıyoruz yani o pin 5V gerilim veriyor.
digitalWrite(ROLE_PIN, HIGH);
break;
default:
break;
}
}
}
Mobil Kodlama: Android
Bu aşamayı tamamladıktan sonra Android uygulamamızı geliştirmeye geçebiliriz. Yeni bir Android projesi açıp kullanacağımız dili Kotlin seçiyoruz. İlk iş olarak res/layout içerisindeki activity_main.xml dosyasını açmamız gerekiyor. Açtıktan sonra kodları aşağıdakiyle güncelliyoruz. Bunu yaparak ilk ekranda karşımıza gelecek listeyi ve yenileme butonunu eklemiş oluyoruz.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.dkarakay.relaycontroller.MainActivity">
<ListView
android:id="@+id/deviceListView"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/refreshButton"
android:layout_marginBottom="10dp"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/refreshButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginStart="20dp"
android:text="@string/refresh"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="20dp"
android:layout_marginEnd="20dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Buradaki tools:context kısmında kendi aktivitenizin ismi olması önemli, diğer türlü Android Studio hata verecektir. Bu aşamanın ardından /res/values/strings.xml içerisine girip dosyayı aşağıdaki gibi güncelliyoruz.
<resources>
<string name="app_name">Ev Otomasyon Sistemi</string>
<string name="refresh">Yenile</string>
<string name="on">Açık</string>
<string name="off">Kapalı</string>
<string name="disconnect">Bağlantıyı kes</string>
<string name="does_not_support_bluetooth">Bu cihaz Bluetooth\'u desteklemiyor</string>
<string name="could_not_find_paired_device">Eşleşmiş Bluetooth cihazı bulunamadı</string>
<string name="bluetooth_opened">Bluetooth açıldı</string>
<string name="bluetooth_closed">Bluetooth kapatıldı</string>
<string name="bluetooth_cancelled">Bluetooth açma işlemi iptal edildi</string>
<string name="connecting">Bağlanıyor…</string>
<string name="please_wait">Lütfen bekleyin</string>
</resources>
Şimdi MainActivity.kt içerisine girip onCreate fonksiyonun üzerine aşağıdaki değişkenleri ekliyoruz.
private var mBluetoothAdapter: BluetoothAdapter? = null
private lateinit var mPairedDevices: Set<BluetoothDevice>
private val REQUEST_ENABLE_BLUETOOTH = 1
companion object {
val EXTRA_ADDRESS: String = "Device_address"
}
İlgili kütüphaneleri dahil ettikten sonra onCreate fonksiyonumuzun içerisine gerekli kodları ekliyoruz. Burada uygulamamız açıldığında eğer Bluetooth kapalıysa, Bluetooth'u açmamızı söyleyen bir uyarı çıkarttırıyoruz.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if (mBluetoothAdapter == null) {
Toast.makeText(applicationContext,R.string.does_not_support_bluetooth,Toast.LENGTH_SHORT).show()
return
}
if (!mBluetoothAdapter!!.isEnabled) {
val enableBluetoothIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBluetoothIntent, REQUEST_ENABLE_BLUETOOTH)
}
val refreshButton: Button = findViewById(R.id.refreshButton)
refreshButton.setOnClickListener { pairedDeviceList() }
}
Hemen altına pairedDeviceList adında bir fonksiyon oluşturup aşağıdaki kodları ekliyoruz. Burada cihazımızda daha önceden eşleştirilmiş olan bluetooth cihazlarına erişiyoruz. Ardından bu eriştiğimiz cihazların isimlerini listeye ekliyoruz. Böylece uygulamayı çalıştırdığımızda eşleştirdiğimiz Bluetooth cihazlarını bir listede görebiliyoruz. İstediğimiz cihaza bağlanmak için tek yapmamız gereken o cihazı seçmek.
private fun pairedDeviceList() {
mPairedDevices = mBluetoothAdapter!!.bondedDevices
val list: ArrayList<BluetoothDevice> = ArrayList()
if (!mPairedDevices.isEmpty()) {
for (device: BluetoothDevice in mPairedDevices) {
list.add(device)
Log.i("device", "" + device)
}
} else {
Toast.makeText(applicationContext,R.string.could_not_find_paired_device,Toast.LENGTH_SHORT).show()
}
val nameList: ArrayList<String> = ArrayList()
for (item in list){
nameList.add(item.name)
}
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, nameList)
val deviceListView: ListView = findViewById(R.id.deviceListView)
deviceListView.adapter = adapter
deviceListView.onItemClickListener = AdapterView.OnItemClickListener { _, _, position, _ ->
val device: BluetoothDevice = list[position]
val address: String = device.address
val intent = Intent(this, ControlActivity::class.java)
intent.putExtra(EXTRA_ADDRESS, address)
startActivity(intent)
}
}
Ardından altına ekleyeceğimiz onActivityResult fonksiyonuyla farklı durumlara göre Toast yardımıyla kullanıcıya mesajlar gösterebiliyoruz.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_ENABLE_BLUETOOTH) {
if (resultCode == Activity.RESULT_OK) {
if (mBluetoothAdapter!!.isEnabled) {
Toast.makeText(applicationContext,R.string.bluetooth_opened,Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(applicationContext,R.string.bluetooth_closed,Toast.LENGTH_SHORT).show()
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Toast.makeText(applicationContext,R.string.bluetooth_cancelled,Toast.LENGTH_SHORT).show()
}
}
}
Control Activity & Control Layout
Şimdi /res/layout içerisine gidip "activity_control" adında bir xml dosyası oluşturuyoruz. Bu layout dosyasında alt alta 3 tane buton tanımlıyoruz. Buradaki butonlar LED açma, LED kapatma ve bağlantıyı kesme fonksiyonlarını çalıştıracak.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/ledOnButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/on"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/ledOffButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/off"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ledOnButton"/>
<Button
android:id="@+id/disconnectDeviceButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/disconnect"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ledOffButton"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Bundan sonra MainActivity.kt yanına "ControlActivity" adında bir Kotlin dosyası oluşturuyoruz. Burada Arduino'ya Bluetooth üzerinden bağlantıyı sağlama ve komut gönderme işlemlerini gerçekleştireceğiz. Yine bir companion nesnesi kullanıyoruz bu şekilde statik verilerimizi tutabiliyoruz. UUID ile tanımladığımız String dosyasını HC-06/HC-05 için aşağıdaki gibi ekliyoruz. Modül ile bağlantıyı sağlayabilmek ve komut gönderebilmemiz için bu kısım gerekli.
companion object {
var mUUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
var mBluetoothSocket: BluetoothSocket? = null
lateinit var mProgress: ProgressDialog
lateinit var mBluetoothAdapter: BluetoothAdapter
var mIsConnected: Boolean = false
lateinit var mAddress: String
}
Burada layout dosyasından erişeceğimiz butonlara erişiyoruz ve üzerlerine tıkladığımızda çalışacak kodu ekliyoruz.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_control)
mAddress = intent.getStringExtra(MainActivity.EXTRA_ADDRESS).toString()
ConnectToDevice(this).execute()
val ledOnButton: Button = findViewById(R.id.ledOnButton)
val ledOffButton: Button = findViewById(R.id.ledOffButton)
val disconnectDeviceButton: Button = findViewById(R.id.disconnectDeviceButton)
ledOnButton.setOnClickListener { sendCommand("1") }
ledOffButton.setOnClickListener { sendCommand("0") }
disconnectDeviceButton.setOnClickListener { disconnect() }
}
Şimdi komut gönderme fonksiyonumuzu yazmaya başlayabiliriz. Eğer BluetoothSocket nesnemiz null değilse outputStream.write() fonksiyonuyla input olarak verdiğimiz stringi bluetooth modulümüze gönderebiliriz.
private fun sendCommand(input: String) {
if (mBluetoothSocket != null) {
try {
mBluetoothSocket!!.outputStream.write(input.toByteArray())
} catch (e: IOException) {
e.printStackTrace()
}
}
}
Halihazırda bağlı olduğumuz cihazdan bağlantıyı sağlıklı bir biçimde koparabilmek için disconnect adında bir fonksiyon oluşturuyoruz.
private fun disconnect() {
if (mBluetoothSocket != null) {
try {
mBluetoothSocket!!.close()
mBluetoothSocket = null
mIsConnected = false
} catch (e: IOException) {
e.printStackTrace()
}
}
finish()
}
Son olarak ConnectToDevice sınıfını en alta ekleyerek bu dosyadaki kodlarımızı tamamlıyoruz.
private class ConnectToDevice(c: Context) : AsyncTask<Void, Void, String>() {
private var connectSuccess: Boolean = true
private val context: Context = c
override fun onPreExecute() {
super.onPreExecute()
mProgress = ProgressDialog.show(
context,
context.getString(R.string.connecting),
context.getString(R.string.connecting)
)
}
override fun doInBackground(vararg p0: Void?): String? {
try {
if (mBluetoothSocket == null || !mIsConnected) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
val device: BluetoothDevice = mBluetoothAdapter.getRemoteDevice(mAddress)
mBluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(mUUID)
BluetoothAdapter.getDefaultAdapter().cancelDiscovery()
mBluetoothSocket!!.connect()
}
} catch (e: IOException) {
connectSuccess = false
e.printStackTrace()
}
return null
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
if (!connectSuccess) {
Log.i("data", "couldn't connect")
} else {
mIsConnected = true
}
mProgress.dismiss()
}
}
Manifest dosyası
Bluetooth kullanımı için gerekli izinleri almamız gerekiyor. Bunun için AndroidManifest.xml dosyasını açıp manifest tagi altına aşağıdaki izinleri eklememiz gerekiyor.
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Bunun ardından da ControlActivity'i activity olarak manifeste eklememiz gerekiyor. Bunun için MainActivity'nin hemen altına aşağıdaki satırı ekleyebilirsiniz.
<activity android:name=".ControlActivity" />
Test
Uygulamız da hazır olduğuna göre, uygulamamızı telefonumuza yükleyip, Arduino'yu bir güç kaynağına bağlayabiliriz. Bunun ardından ilk iş telefonumuz ile bluetooth modülüne bağlanmalıyız. Ayarlardan Bluetooth'u açtıktan sonra yeni cihazlarda HC-06 yazısını görüp onu seçiyoruz. Şifre olarak (0000 ya da 1234) girmeniz gerekiyor biri olmazsa diğerini deneyebilirsiniz. Şimdi uygulamamızı açıyoruz:

Bluetooth'umuz kapalıysa onu açmamızı söylüyor. Bluetooth'u açtıktan sonra da daha önce eşleşmiş cihazlarımızı gördüğümüz menü geliyor.

Bu menüde kullandığımız modülü yani HC-06'yı seçiyoruz. Ardından kısa bir bağlanma sürecinden sonra kontrol ekranımıza ulaşıyoruz.

Butonlar yardımıyla rölemizi dolayısıyla da LED'imizi kontrol edebiliriz!
Bu projede röleyi kontrol eden ve röle içerisinden geçen akım aslında Arduino'nun kendisinden sağlandı. Ancak siz rölenize 5V yerine 220V bağlayarak evinizdeki lamba, televizyon, buzdolabı gibi elektrikle çalışan aletleri Bluetooth ile Android telefonunuzdan kontrol edebilirsiniz. Hatta çok kanallı röle modülü veya birden fazla röle modülleri kullanarak da daha fazla cihazı aynı anda telefonunuzdan rahatlıkla kontrol edebilirsiniz.
Çalışma videosu:
GitHub: https://github.com/dkarakay/android-arduino-home-automation Teşekkürler!
Kaynaklar:
https://developer.android.com/
https://fritzing.org/projects/bluetoothlight
https://maker.robotistan.com/arduino-dersleri-17-hc-05-bluetooth-modulu-kullanimi/
https://github.com/appsinthesky/Kotlin-Bluetooth
#arduino #iot #bluetooth #arduinouno #android #mobirobotics #smarthome #sketch #arduinoide