Professional Documents
Culture Documents
SAKARYA ÜNİVERSİTESİ
BİLGİSAYAR VE BİLİŞİM BİLİMLERİ FAKÜLTESİ
Melih ÇELENK
İnsan, yüzyıllardan beri başta yaşamını sürdürmek, daha sonra yaşam kalitesini
artırmak için birtakım aletlere ihtiyaç duymuş, gereksinimleri doğrultusunda icatlar
ortaya koymuştur. Zamanla, kullanılan eşyanın sayısı artmış; sonunda evlerde,
ofislerde kategorize edilmeye başlanmıştır. Bazı benzer özelliklere sahip olan araç
gereçler, kitaplar bir araya getirilmiş; ancak eşya çoğaldıkça sınıflandırma da bir
problem hâline gelmeye başlamıştır. Kullanım amacına göre sınıflandırma bir yana;
eski/yeni, büyük/küçük, sık kullanılan/az kullanılan gibi ortak üye barındırabilecek
sınıflar türetilmiştir. Bu kadar çok sınıflandırma çeşidi, özellikle belli ilgi alanları
sebebiyle evinde veya ofisinde çok fazla eşya barındıran insanların hafızasını
yormaya başlamış, bir eşyayı farklı yerlerde aramak gibi vakit kayıplarına yol
açmıştır. Bu vakit kaybını ortadan kaldırmak ve sadece yapılmak istenen işe
odaklanılmasını sağlamak amacıyla, arama motorlarında olduğu gibi günlük hayatta
da arama işinin dijital asistanlara devredilmesinde yarar vardır.
iv
İÇİNDEKİLER
ŞEKİLLER LİSTESİ
TABLOLAR LİSTESİ
ÖZET
Kullanıcı, evini veya ofisini bölgelere ayırır. Etiketleyeceği eşyayla ilgili anahtar
kelimeleri, bölge etiketiyle birlikte söyleyerek mobil uygulama yardımıyla kaydeder.
Daha sonra eşyayı bulmak istediği zaman eşyayla ilgili anahtar kelimeleri söyler ve
eşyanın bulunduğu bölgeden sesli ve görüntülü sinyal gelir. Böylece kullanıcı eşyayı
bulmak için hangi bölgeye yönelmesi gerektiğini bilir.
Mobil uygulama geliştirmek için Android Studio, her bir bölgede sinyal üretmek için
NodeMCU kartlar kullanılmıştır.
BÖLÜM 1. GİRİŞ
Eşya çeşidinin artmasıyla birlikte eşyaların aranma süreci hafızayla ilgili sorunları
olan insanlarda ve görme engellilerde daha belirgin olmakla birlikte bir problem
hâline gelmiştir. Bu işlemin yükü insan beyninden alınıp dijital asistanlara
devredilmelidir.
Kullanıcı tarafından eşyayı tanımlayıcı bilgi mobil uygulamaya sesli veya yazılı
olarak bildirilir ve eşyanın bulunduğu bölgeden sinyal alınır.
tespit edilen bölgelere yerleştirilir. Bu bölgeler, kullanıcının tercihine göre oda veya
odanın bölümleri, hatta raflar olarak seçilebilir.
Kullanıcı, bölgenin ismiyle birlikte eşyanın ismini ve aynı isimde olabilecek başka
eşyalara karşılık eşyayı tanımlayacak anahtar kelimeleri mobil uygulamada sesli
komut vererek veya kaydetme ekranı üzerinden eşyayı kaydedebilir.
Ulaşılmak istenen eşya doğrudan sistemde kaydedilen ismi telaffuz edilerek yahut
eşyayı tanımlayacak yeterince anahtar kelime söylenerek mobil uygulama üzerinden
sesli bir şekilde aranır. Eğer eşyayı tanımlayacak yeterli veri alındıysa ve veri
tabanında eşsiz bir eşya bulunduysa, eşyanın kayıtlı olduğu bölgeden sesle (ve
opsiyonel olarak ışıkla) uyarı yapılır ve kişi o bölgeye yönlendirilir. Aynı şekilde bu
işlem doğrudan kullanıcı ara yüzü ile de yapılabilir.
Projenin minimum başarı kriteri, kullanıcının eşyalarını istediği bölgelere ses ile
kaydedebilmesi, daha sonra kaydettiği eşyaları bulmak istediğinde mobil uygulama
üzerinden yönelttiği bir komutla alınacak uyarıya göre eşyanın yerini tespit
edebilmesidir.
BÖLÜM 2. KULLANILAN TEKNOLOJİLER
Temelde bir ağ üzerinde birbirine bağlı NodeMCU kartları ve ses tanıma ve kartlara
yönlendirmeyi yapacak bir Android cihazı kullanılmıştır. Her bir NodeMCU kartına
bağlı sinyal üretecek olan LED’ler ve buzzer’lar eşya bölgelerine yerleştirilmek için
kullanılmıştır. NodeMCU kartları programlamak için Arduino IDE, Android cihazı
programlamak için Android Studio kullanılmıştır.
Arduino IDE açılır, araç çubuğu üzerinde Dosya/Tercihler tıklanarak “Ek Devre
Kartları Yöneticisi URL’leri:” kısmına aşağıdaki URL girilir:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
#include <ESP8266WiFi.h>
5
2.1.1.4. ESP8266WebServer
Retrofit, Java ve Android REST istemcisidir. JSON veya başka yapıdaki verileri
kolayca almaya ve yüklemeye yarar. Retrofit ile GET ve POST gibi HTTP metotları
kullanılabilir [10].
7
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
Kontrol için bir ara yüz (interface) tanımlanarak burada metotlar ve parametreler
belirlenir. Bu ara yüzden retrofit.create() metoduna ara yüzün sınıfı verilerek bir
nesne oluşturulur ve ara yüz içinde tanımlanan çağrılar bu nesne üzerinden kullanılır.
Yazılacak ses girişi alma metodu içerisinde bir intent tanımlanarak parametre olarak
RecognizeIntent.ACTION_RECOGNIZE_SPEECH verilir. Oluşturulan intent’e
putExtra metodu vasıtasıyla dil özellikleri gönderildikten sonra sistem dili veya
isteğe bağlı olarak başka bir dil seçilerek mesaj gönderilir. Sonuçlar String dizisi
olarak get metoduyla alınır ve istenilen şekilde ayrıştırılır.
SQLite, Android cihazlarda gömülü olarak gelen açık kaynak bir ilişkisel veri
tabanıdır [12]. SQL kodları yazılarak kullanılabildiği gibi sınıfa ait hazır metotlar
çağrılarak da kullanılabilir.
Port tarama, subnet cihazlarını bulma, ping gönderme, ağ üzerinde uyandırma gibi
özellikleri olan bir kütüphanedir [13]. Ağdaki cihazları taramak ve IP’lerini bulmak,
lokal ağda çalışan uygulamalar için yeterli değilse de olmazsa olmazdır. Bu
kütüphane ile ağda IP’leri tespit edilen cihazlar projede IP sabit olduğu müddetçe
kayıtlı tutulmuş ve sadece bağlantı sorunu olduğunda tekrar ağ taramaya
başvurulmuştur.
BÖLÜM 3. TASARIM
Her bir bölgeye NodeMCU kartlar ve sinyal verilecek donanım (buzzer ve LED’ler)
yerleştirilmek ve bu kartlar ortadaki web server sağlayıcı görevindeki kartla
haberleşmek suretiyle sistem kurulur. Bölgeler mobil uygulama vasıtasıyla
etiketlenerek Şekil 3.1’deki çalışır vaziyete getirilir. Bu noktadan sonra eklenen
eşyalar kişinin mobil uygulama üzerinden sesli komut vermesiyle aranır.
3.2. Modelleme
Şekil 3.3’te kullanıcının eşyalar ile ilgili yapabileceği işlemler sekans diyagramı
üzerinde gösterilmiş olup “S” yerleştirilen NodeMCU sistemlerini temsil etmektedir.
“A” etiketi mobil uygulamadaki kullanıcı ara yüzünü temsil eder.
Veri tabanı mobil uygulama üzerinde SQLite ile lokal olarak tutulacaktır. Veri
tabanına ilişkin Varlık İlişki Diyagramı (Entity Relationship Diagram) Şekil 3.4’te
gösterilmiştir.
Şekil 3.4 Mobil Uygulama Üzerinde Barındırılan Veri Tabanının Varlık İlişki Diyagramı
13
Şekil 3.5 üzerinde mobil uygulama için UML sınıf diyagramı gösterilmiştir. Mobil
uygulama üzerinde ana aktivite üzerinde Bolge sınıfından bir liste oluşturulacaktır.
Eşyalar bölge nesnelerinde saklanacak ve bir sonraki başlıkta verilen ara yüzde
görüldüğü üzere bölgeler seçildikçe listelenecektir.
Kurulum yapılıp eşyalar sisteme eklendikten sonra kullanıcı mobil uygulamada Şekil
3.6’daki gibi bir ara yüzle karşılaşır. Kolay ulaşılabilir bölgede bulunan mikrofon
simgesiyle doğrudan komut verebilir.
Uygulama üzerinde bölgeler seçilebilir olarak yukarıdaki menüde listelenir. Her bir
bölgeye tıklandığında o bölgede kayıtlı eşyalar sıralanır. Eşyanın üzerine basılı
tutulduğunda Şekil 3.6’daki gibi bir menü açılır. Burada “Yerini Göster”e tıklanarak
doğrudan eşyanın olduğu bölgeden sinyal alınabilir. Eşya bilgileri düzenlenebilir,
eşya silinebilir.
Ana aktivitenin sağ altındaki mikrofon butonu ile Şekil 3.8’deki gibi bir ara yüze
ulaşılır ve kullanıcıdan alınan komut ekrana yazdırılır. Metne dönüştürülen veri
ayrıştırılır ve gerekli işlemin yapıldığı ekrana yönlendirilir.
Şekil 3.8 Mobil Uygulama Sesle Komut Verme (Eşya Ekleme Komutu Durumunda)
17
Kullanıcının verdiği ekleme komutuna göre oluşturulan bilgi teyit amaçlı olarak
Şekil 3.9’daki gibi ekranda gösterilir ve eğer eklenecek eşya bilgileri doğruysa
kullanıcıdan eşyaya dair anahtar kelimelerin sesle söylenmesi istenir.
Kullanıcı eşyayı elle eklemek isterse ana aktivitedeki alt menünün ortasındaki eşya
ekleme butonuyla Şekil 3.11’deki eşya ekleme aktivitesine geçebilir. Kaydetme
işlemi yapıldığında Şekil 3.10’daki ara yüz gösterilecektir.
Kullanıcı alt menünün sağdaki mikrofon simgeli komut verme butonuna dokunarak
Şekil 3.12’deki gibi eşya bulma komutu verebilir.
Şekil 3.12 Mobil Uygulama Sesle Komut Verme (Eşya Bulma Komutu Durumunda)
21
Eşya bulma komutu sonucunda bir eşya tanımlandıysa kullanıcıya Şekil 3.13’teki
gibi bir ekran gösterilir ve bu ekranda eşyanın bulunduğu bölgeye sinyal
gönderildiğine dair mesaj bulunur. Kullanıcı sinyali durdurabilir ya da komutu
yeniden deneyebilir.
Yapılan ilk tasarımda ses girişi almak için Arduino Ses Tanıma Modülü
kullanılmasına karar verilmişti. Bundan bir adet kullanılacak ve her bir eşya
bölgesine de mikrofonlar konularak ses, en yakın eşya bölgesinden alınacaktı. Bu da
en şiddetli sesi alan mikrofonun verisinin işlenmesi suretiyle karar olunacak, bu
sayede o bölgeye ait işlem yapılmış olacaktı. Oysa aktif olması beklenen bölgede bir
insan sesi ile komut verilirken başka bir bölgede insan sesinden daha şiddetli bir ses
bulunabilmektedir. Bu durumda komut işlenemeyecektir. Komut vermede hız önemli
olduğundan ve her yerden gelen seslerin bir tamponda bekletilmesi söz konusu
olamayacağından her bir bölgeye o bölgenin sesini işleyecek bir ses tanıma modülü
üzerinde düşünüldü. Ancak bu, maliyeti önemli ölçüde artıracaktı.
İlk iki sorun için çok daha iyi mikrofonlar kullanılarak belli ölçüde iyileştirme
sağlanabilir, ancak bulunan bu çözümde maliyet zaten gereğinden fazla artmış
olduğu için sistemin daha da maliyetli bir duruma evrimi başka çözüm arayışlarını
23
kaçınılmaz kılmıştır. Hızlı bir şekilde alternatifleri test etmek amacıyla MIT’nin
Android cihazlarda basit yazılımlar oluşturulabilmesi amacıyla geliştirdiği
AppInventor üzerinde SpeechRecognizer aracı kullanılmış ve bu şekilde kullanımın
işlevselliğinin Arduino Ses Tanıma Modülü ile kıyaslanamayacak kadar yüksek
olduğu görüldüğünden projenin ses tanıma kısmının Android uygulaması üzerinde
koşulmasında karar kılınmıştır. Elde edilen bu imkânla birlikte veri tabanı ve karar
verme için yazılacak metotların da Android’e taşınması uygun görülmüştür.
Şekil 3.14 Arduino Ses Tanıma Modülü İle Kurulan İlk Model
NodeMCU’nun ağa bağlanması için başta SSID ve parola statik olarak giriliyordu.
Bunun otomatik olarak yapılması için ara yüz WifiManager kütüphanesi ile
sağlanmıştı. NodeMCU bir web sunucusu oluşturuyor, NodeMCU’nun seri port
ekranı üzerinden alınan IP adresi herhangi bir tarayıcıya girilmek suretiyle HTTP
GET metodu kullanılarak NodeMCU ile haberleşme sağlanıyordu. Buna mukabil bu
IP adresini bulmak son kullanıcının görevi olmadığı için bunun mobil uygulama
tarafından otomatik olarak bulunması gerekiyordu. Bu işlemi yapmak için öncelikle
ağ üzerindeki cihazların IP’lerini bulan bir uygulama yapıldı. Bu uygulamanın
yaptığı işlem ara yüzde çıktı olarak Şekil 3.15’te gösterilmiştir.
24
Her bir bölgede Tablo 3.1’de belirtildiği gibi toplamda ortalama $9,36’lık bir
donanım maliyeti öngörülmüştür. Minimum bölge sayısı 2 olmak üzere eklenecek
bölge sayısı ile bu maliyet çarpılarak toplam kurulum maliyeti hesaplanır. 5 bölge
seçildiği takdirde maliyet $46,8 olacaktır.
Evin veya ofisin büyüklüğüne göre 12V’luk buzzer yerine 24V’luk buzzer
kullanabilir, bu durumda buzzer maliyeti $0,67’ye çıkacaktır.
Bir ev kullanıcısı için ideal olarak oda sayısının üç katı kadar bölge öngörülmüştür.
Bu durumda standart bir ev kullanıcısı için donanım maliyeti (Android cihazının
olduğu varsayılarak) 12 bölge ile $112,32 olarak hesaplanmıştır.
Kullanıcı sağ alttaki mikrofon butonuna tıklayarak ses ile komut verebilir. Şekil
4.11’de bir eşya ekleme komutu örneği görülmektedir.
Sesli komut eğer geçerli bir bölgeye aitse kullanıcı bir aktiviteye yönlendirilir.
Burada zikredilen komut yazılı olarak düzenlenebilir, tekrar sesli komut denenebilir
yahut eşyanın birden fazla bulunması durumu için anahtar kelimelerin yine sesli
olarak eklenmesi gerçekleştirilebilir.
Kullanıcı aynı şekilde diğer eşyalarını ekledikten sonra eşyanın konumunu bulmak
için yine konuşma butonunu kullanarak “Eşya ismi ‘nerede’” formatında bir sesli
komut verebilir. Şekil 4.16’da, bir önceki adımda eklenen “Nutuk” kitabı “Nutuk
nerede” sesli komutu verilerek aranmış ve kullanıcıya eşyanın bulunduğu bölgeye
sinyal gönderildiğini belirten bir Toast mesajı gösterilmiştir. Herhangi bir hata
durumunda kullanıcıya “Sinyal Gönderilemedi.” mesajı gösterilir ve akabinde
cihazların tabloda kayıtlı IP adresleri güncellenir. İstek, “Kitaplık” etiketinin
verildiği karta iletildikten ve bağlantının doğru olduğu kesinleştikten sonra sinyal
verilecektir. Kullanıcı, aradığı eşyanın “Kitaplık” bölgesinde olduğunu şayet sinyal
gönderme başarılıysa Şekil 4.17’deki gibi gelen sinyalle görecek ve bu bölgeye
yönelecektir. Şekil 4.18’de ise haberleşmenin başarılı olduğuna dair geri bildirim
gösterilmiştir.
Kullanıcı sesli komut vermek dışında klavye ile eşya eklemek isterse ortadaki butona
tıklamak suretiyle eşya ekleme aktivitesine yönlendirilir. Burada kullanıcı sesin
alınması ile ilgili olan ‘Tekrar Dene’ ve ‘Anahtar Kelimeleri Söyle’ butonlarını
görmemektedir. Kullanıcı ‘Eşyaları Listele’ butonu ile 4.20’deki gibi bütün eşyaları
görüp el ile sinyal verebilir.
Kullanıcının aynı türde birden fazla eşyası olabilir. Anahtar kelimeler bu eşyaların
ayırt edilmesi için kullanılmaktadır. Şayet birden fazla kayıtlı bir eşya ismi
zikredilirse doğrudan sinyalin gönderilmesi yerine kullanıcıya Şekil 4.22’deki gibi
ilgili eşyalar tanımlayıcılarıyla birlikte gösterilir.
Şekil 4.23 Eşyanın Konumu Sesli Komut ile Arandığında Mobil Uygulamanın Kaynak Kullanımı
Şekil 4.24 Kurulum Ekranında Tarama İşlemi Yapıldığında Mobil Uygulamanın Kaynak Kullanımı
40
4.3.1. NodeMCU
4.3.2. Android
4.3.2.1. RecyclerView
42
Android Studio üzerinde eşyaların listelendiği kayan bir yapı oluşturmak için
RecyclerView kullanılmıştır [27]. Örneklere bakıldığında cardCornerRadius ile ilgili
bir hata alınmıştır. Gerekli sürüm desteği eklenerek çözülmüştür [28].
Uygulama üzerinde PIN kodu gibi tekil verilerin cihaz üzerinde saklanması için veri
tabanı yerine SharedPreferences kullanılmıştır [29].
Veri tabanının sınıfı yazılırken son değiştirilen değerin alınması gerekmiştir. Burada
bu işlem tablodaki son satırla karıştırılmamalıdır [34]. Burada yapılan bir hatanın
fark edilmesi uzun sürebilmektedir.
43
Android üzerinde network işlemlerinin yapılması sürekli olarak hafıza aşımı hatasına
sebep olmuştur. Uzun süre aramalar genel olarak yapıldığı için sorunun kaynağı
bulunamamış, ancak bazı işlemler yapılırken keşfedilmiştir. Varılan sonuca göre
network işlemleri asenkron olarak arka planda yapılmalıdır [36].
Asenkron fonksiyonun çalışması bittikten sonra çağrılan sınıfta işlem yapma ihtiyacı
doğmuştur. Bunun için Stackoverflow’da new RunInBackGround().execute().get()
fonksiyonunun çağrılması önerilmiş, ancak bu ara yüzün kilitlenmesine sebep verdiği
için tercih edilmemiştir [38]. Asenkron fonksiyona gönderilecek pointer mantığında
çalışan bir değişken yapısı aranmış, bu sırada daha kullanışlı bir yapı keşfedilmiştir.
MutableLiveData canlı olarak değişkenlerin durumunu dinleyen bir yapıdır [39].
Asenkron fonksiyona parametre olarak gönderilen bu değişken, onPostExecute
metodunda değiştirilmiş, böylece asenkron fonksiyonun çalışması bittiğinde ara
yüzde de değişim sağlanmıştır.
44
Android Studio üzerinde en düşük desteklenen sürüm 6.0 olarak seçilmiş olmakla
birlikte buna rağmen yeni sürümlerde çalışan uygulama bu sürümde hata
verebilmektedir. Drawable klasörüne atılan görüntü dosyaları farklı sürümler için
tekrar eklendiğinde sorun çözülmektedir.
Aktivite açıldığında imlecin odak noktasının ayarıyla ilgili veya benzeri kodlar
yazıldığında programın çalışmasına karşılık ilgili kod çalışmayabilmektedir. Keza
eski sürümlerde çalışan bazı kodlar yeni sürümlerde çalışmayabilmektedir. Bu
nedenle farklı sürümler için senaryolar test edilmeli, konsola yazılmış bir hata
olmasa dahi her bir bileşenin çalışıp çalışmadığı kontrol edilmelidir.
45
Teze konu olan uygulama, yerel ağda çalıştığı için en önemli problem ağdaki diğer
cihazların bulunması ve bu işlemin maliyetli olması olmuştur. Bu nedenle IP’ler bir
kez bulunduktan sonra veri tabanında saklanmış, değişmediği sürece sinyal
göndermek gerektiğinde buradan alınarak kullanılmıştır. Böylece defalarca tarama
maliyetinden kaçınılmıştır. Burada dikkat edilmesi gereken nokta cihazların
birbirinin IP’lerini alabileceğidir. Bu nedenle sinyal gönderilirken sadece IP’ye
sinyal gönderme yapılmamalı, cihazın kimliği de kontrol edilmelidir.
KAYNAKLAR
[1] https://www.learnrobotics.org/blog/which-controller-should-i-use-wemos-d1-mini-
or-nodemcu. [Erişildi: Aralık 2019].
[2] https://www.arduino.cc/en/guide/environment. [Erişildi: Aralık 2019].
[3] https://create.arduino.cc/projecthub/auggujarat/getting-started-with-
nodemcuesp8266-on-arduino-ide-b7e18e. [Erişildi: Aralık 2019].
[4] C. BAYILMIŞ, BSM313 Nesnelerin İnterneti ve Uygulamaları Dersi Uygulama
Föyü, Sakarya: Sakarya Üniversitesi, Bilgisayar ve Bilişim Bilimleri Fakültesi,
Bilgisayar Mühendisliği Bölümü, 2019.
[5] https://www.esp8266.com/viewtopic.php?t=2153. [Erişildi: Nisan 2020].
[6] https://stackoverflow.com/questions/40062146/send-data-to-esp8266. [Erişildi:
Şubat 2020].
[7] https://github.com/esp8266/Arduino/tree/master/libraries/EEPROM. [Erişildi: Ocak
2020].
[8] https://arduino-esp8266.readthedocs.io/en/latest/libraries.html#eeprom. [Erişildi:
Ocak 2020].
[9] https://developer.android.com/studio/intro. [Erişildi: Aralık 2019].
[10] https://www.vogella.com/tutorials/Retrofit/article.html. [Erişildi: Aralık 2019].
[11] https://developer.android.com/reference/android/speech/RecognizerIntent. [Erişildi:
Aralık 2019].
[12] https://www.javatpoint.com/android-sqlite-tutorial. [Erişildi: Şubat 2020].
[13] https://github.com/stealthcopter/AndroidNetworkTools. [Erişildi: Şubat 2020].
[14] https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266mDNS. [Erişildi:
Kasım 2019].
[15] https://github.com/berndverst/androidssdp/blob/master/app/src/main/java/ly/readon/a
ndroid_ssdp/UPnPDiscovery.java. [Erişildi: Kasım 2019].
[16] https://developer.android.com/training/connect-devices-wirelessly/nsd. [Erişildi:
47
Kasım 2019].
[17] https://forum.arduino.cc/index.php?topic=42080.0. [Erişildi: Ocak 2020].
[18] https://github.com/esp8266/Arduino/blob/74819a763bfb6e9890a57411dcea4aba221
a778d/libraries/DNSServer/examples/CaptivePortalAdvanced/credentials.ino.
[Erişildi: Ocak 2020].
[19] https://support.garmin.com/en-ZA/?faq=aC6mOWyuda1ClsYQ22lgyA. [Erişildi:
Ocak 2020].
[20] https://www.routersecurity.org/wepwpawpa2.php. [Erişildi: Ocak 2020].
[21] https://github.com/tzapu/WiFiManager/issues/165. [Erişildi: Ocak 2020].
[22] https://forum.arduino.cc/index.php?topic=343015.0. [Erişildi: Ocak 2020].
[23] https://stackoverflow.com/questions/9321/how-do-you-create-a-static-class-in-c.
[Erişildi: Ocak 2020].
[24] https://tttapa.github.io/ESP8266/Chap10%20-%20Simple%20Web%20Server.html.
[Erişildi: Şubat 2020].
[25] https://www.arduino.cc/en/tutorial/BlinkWithoutDelay. [Erişildi: Mart 2020].
[26] https://www.arduino.cc/en/Tutorial/StringAdditionOperator. [Erişildi: Mart 2020].
[27] https://youtu.be/Nw9JF55LDzE. [Erişildi: Ocak 2020].
[28] https://stackoverflow.com/questions/31982890/cardcornerradius-shows-error.
[Erişildi: Ocak 2020].
[29] https://www.androidauthority.com/how-to-store-data-locally-in-android-app-
717190/. [Erişildi: Ocak 2020].
[30] https://github.com/square/retrofit/issues/2004. [Erişildi: Ocak 2020].
[31] https://stackoverflow.com/questions/36730086/retrofit-2-url-query-parameter.
[Erişildi: Şubat 2020].
[32] https://www.sqlitetutorial.net/sqlite-unique-constraint/. [Erişildi: Şubat 2020].
[33] https://stackoverflow.com/questions/11024533/sqlite-in-android-unique-constraint-
not-working. [Erişildi: Şubat 2020].
[34] https://stackoverflow.com/questions/11302276/select-last-insert-rowid-returns-
always-0. [Erişildi: Şubat 2020].
[35] http://pages.cs.wisc.edu/~hasti/cs302/examples/Parsing/parseString.html. [Erişildi:
48
Mart 2020].
[36] https://stackoverflow.com/questions/37751907/using-async-for-a-network-activity.
[Erişildi: Mart 2020].
[37] https://stackoverflow.com/questions/39289601/waiting-for-other-asynctasks-finish-
in-asynctask-before-processing-onpostexecut. [Erişildi: Mart 2020].
[38] https://stackoverflow.com/questions/14827532/waiting-till-the-async-task-finish-its-
work/14827618. [Erişildi: Nisan 2020].
[39] https://stackoverflow.com/questions/14457711/android-listening-for-variable-
changes. [Erişildi: Nisan 2020].
49
ÖZGEÇMİŞ
Toplam