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.

HC-06 Bluetooth Modülü

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.

1 Kanallı 5V Röle Modülü

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://www.arduino.cc/

https://developer.android.com/

https://fritzing.org/projects/bluetoothlight

https://maker.robotistan.com/arduino-dersleri-17-hc-05-bluetooth-modulu-kullanimi/

https://arduinogetstarted.com/tutorials/arduino-relay#:~:text=About%20Relay,Arduino%20and%20high%20voltage%20devices.

https://github.com/appsinthesky/Kotlin-Bluetooth


#arduino #iot #bluetooth #arduinouno #android #mobirobotics #smarthome #sketch #arduinoide

Komünite

Platform

Mobiler.dev Anasayfa
  • Twitter
  • Instagram
  • development_düzenlendi_düzenlendi
  • Youtube
  • slack-icon-black_edited_edited_edited
  • Gri LinkedIn Simge
imageedit_2_9667998092.png
JetBrains Hakkında Detaylı Bilgi Alın

© 2020 by mobiler.dev

Kurumsal Yazar Hesapları

adesso.png
mobilerdevLogo.jpg
Yazarlık Başvurusu Hakkında Bilgi Alın, Başvuru Yapın.
Topluluk Yazarlarını Tanıyın