Şeker Hastalığı: Tanımı, Nedenleri ve Türleri

Şeker Hastalığı: Tanımı, Nedenleri ve Türleri

Günümüzde giderek artan bir sağlık sorunu olan şeker hastalığı (diyabet), vücudun kan şekeri seviyelerinin düzenlenmesinde sorun yaşandığında ortaya çıkan bir durumdur. İnsülin hormonunun yetersizliği veya etkinliğinin azalması sonucu kan şekerinin kontrol edilemez hale gelmesi, diyabetin temel belirtilerinden biridir. Pek çok insanın hayatını etkileyen bu hastalığın farklı türleri bulunmaktadır.  Tip 1, Tip 2 ve gestasyonel diyabet olmak üzere farklı türleri vardır.

1. Tip 1 Diyabet:

Tip 1 diyabet, genellikle çocukluk veya adolesan dönemlerinde başlayan otoimmün bir hastalıktır. Bağışıklık sistemi, pankreastaki beta hücrelerini hedef alır ve onları tahrip eder. Bu hücreler, vücutta insülin üretiminden sorumludur. İnsülinin eksikliği, kan şekerinin hücrelere taşınmasını engeller ve sonuç olarak kan şekerinin yükselmesine neden olur. Tip 1 diyabet hastaları, yaşamları boyunca günlük insülin enjeksiyonlarına veya insülin pompalarına ihtiyaç duyarlar.

2. Tip 2 Diyabet:

Tip 2 diyabet, genellikle ilerleyen yaşlarda ortaya çıkan ve en yaygın şeker hastalığı türüdür. Bu durumda, vücut hâlâ insülin üretir, ancak üretilen insülinin etkinliği azalır veya vücut hücreleri insüline karşı direnç geliştirir. Tip 2 diyabet genellikle obezite, hareketsiz yaşam tarzı, genetik yatkınlık ve yaşam tarzı faktörlerinin bir kombinasyonuyla ilişkilidir. İlk aşamalarda diyabetin kontrol altına alınması, sağlıklı bir diyet, egzersiz ve kilo kaybı gibi yaşam tarzı değişiklikleriyle mümkün olabilir. İlerleyen durumlarda, oral antidiyabetik ilaçlar veya insülin enjeksiyonları gerekebilir.

3. Gestasyonel Diyabet:

Gestasyonel diyabet, hamilelik sırasında beliren geçici bir diyabet türüdür. Hamilelik döneminde hormon seviyelerindeki değişiklikler, bazı kadınlarda insülin direncine neden olabilir. Bu durum, normalden daha yüksek kan şekeri seviyelerine yol açar. Gestasyonel diyabet genellikle gebelik sonrasında kendiliğinden düzelir, ancak hem anne hem de çocuk için sağlık risklerini artırabilir. Gestasyonel diyabet olan kadınlar, doğum sonrası diyabet riski altında olabilirler ve düzenli takip gerektirebilirler.

Sonuç:

Her tür şeker hastalığı, uygun tedavi ve yaşam tarzı değişiklikleriylekontrol altına alınabilir. Diyabetin erken teşhisi ve sürekli takibi önemlidir. Sağlıklı bir beslenme planı, düzenli egzersiz, ilaç tedavisi ve insülin enjeksiyonları, şeker hastalarının sağlıklı bir yaşam sürdürebilmelerine yardımcı olabilir. Ayrıca, diyabet riskini azaltmak için obeziteyle mücadele etmek, sağlıklı kiloyu korumak ve stresi yönetmek gibi önlemler almak da önemlidir.

Mehmed Talat Paşa

Mehmed Talat Paşa: Modernleşmenin Öncülerinden Bir Lider

Osmanlı İmparatorluğu’nun son dönemlerinde etkili olan İttihat ve Terakki Cemiyeti‘nin kurucularından ve önde gelen liderlerinden biri olan Mehmed Talat Paşa, tarih sahnesinde önemli bir rol oynamış bir devlet adamıdır. Cesareti, vizyonu ve liderlik becerileriyle tanınan Talat Paşa, modernleşme ve reform sürecinde öncü bir figür olarak hatırlanır.

Talat Paşa’nın hayatı, çağının zorlu siyasi ve sosyal koşullarında büyük bir başarı hikayesini yansıtmaktadır. İttihat ve Terakki Cemiyeti’nin kurucularından biri olarak, Osmanlı İmparatorluğu’ndaki siyasi ortamı değiştirmeyi hedefleyen bir grup idealistin arasında yer aldı. Bu cemiyet, çağdaşlaşma ve reformları hayata geçirme amacı güden bir hareket olarak ön plana çıktı.

Talat Paşa, İkinci Meşrutiyet hareketinin gerçekleştiği dönemde aktif bir şekilde çalıştı. Meşrutiyetin ilanıyla birlikte, Osmanlı İmparatorluğu’nda demokratikleşme sürecinin başlamasında önemli bir rol oynadı. Meclis-i Mebusan’da (Osmanlı Parlamentosu) görev alarak, halkın temsilcisi olma sorumluluğunu üstlendi ve ülkenin yönetiminde etkin bir rol oynadı.

Talat Paşa’nın sadrazam olmasıyla birlikte, Osmanlı hükümetinin başına geçti ve ülkenin modernleşme çabalarını yönetti. Ekonomik, siyasi ve sosyal alanda reformlar gerçekleştirerek Osmanlı İmparatorluğu’nu daha güçlü bir devlet haline getirmeye çalıştı. Eğitim, adalet ve altyapı gibi alanlarda önemli adımlar attı. Modern eğitim kurumları kuruldu, yasalar yenilendi ve kamu hizmetlerinin etkinliği artırıldı.

Ancak, Talat Paşa’nın liderlik dönemi, Birinci Dünya Savaşı’nın gölgesinde kaldı. Osmanlı İmparatorluğu’nun savaşa girişi, Talat Paşa’nın liderliğinde hayata geçirildi. Bu politika, o dönemde yaşanan karmaşık siyasi ve askeri koşulların bir sonucu olarak ortaya çıktı. Ancak, Talat Paşa’nın liderlik tarzı ve politikaları, eleştirilere ve tartışmalara yol açtı. Bu konuda farklı görüşler bulunsa da, tarihçilerin üzerinde anlaştığı nokta, Talat Paşa’nın savaş sırasında zor bir dönemde kararlar almak zorunda kaldığıdır.

Birinci Dünya Savaşı’nın Osmanlı Devleti ve müttefikleri açısından sona ermesinin ardından Sadrazam Talât Paşa, 1918 yılı Ekim ayı başlarında görevinden istifa etti. Mehmed Talat Paşa, 1 Kasım 1918’de İttihat ve Terakki Fırkası’nın son kongresini yaparak partiyle ilişkisini sonlandırma kararı aldı. Aynı gün Berlin’e giden Talat Paşa, burada çeşitli maceralar yaşadı ve birkaç ev değiştirdi. Berlin’de siyasetten uzak durmadı ve Şark Kulübü’nü kurarak yurt dışında bulunan İttihat ve Terakki üyeleri ve diğer Müslüman ülkelerden burada yaşayan gençlerin bir araya gelmesine önemli katkılarda bulundu. Ancak, 1921 yılında Berlin’de Ermeni bir suikastçı tarafından kalleşçe suikasta kurban gitti. Talat Paşa, Birinci Dünya Savaşı sırasında Ermenilerin tehcir edilmesi kararında etkili olduğu düşünülen İttihat ve Terakki liderlerinden biriydi. Bu nedenle Ermeni Taşnaksutyun örgütü, intikamlarını almak amacıyla Talat Paşa ve diğer İttihat ve Terakki liderlerine suikastlar düzenlemeye karar verdi. Bu suikastlerin arkasında İngiltere’nin çıkarları olduğu ve İngiliz istihbaratının Talat Paşa’yı hedef aldığı belirtilmektedir. İngiltere, Talat Paşa’nın Türkiye ile adil bir antlaşma yapmaması durumunda İngiliz sömürgelerinde Pan-Turanist ve Pan-İslamist bir hareket başlatabileceği tehdidiyle karşı karşıya olduğunu düşünmekteydi. Talat Paşa’nın ölümü, o dönemdeki siyasi gerilimleri ve travmaları yansıtan bir olaydır. Mehmed Talat Paşa, Osmanlı İmparatorluğu’nun modernizasyon sürecinde önemli bir lider olarak hatırlanır. Özellikle İttihat ve Terakki Cemiyeti’nin ideallerini ve reform çabalarını destekleyerek ülkenin çağdaşlaşmasına katkıda bulundu. Ancak, liderliği sırasında yaşanan olaylar ve uygulanan politikalar hala tartışma konusu olup farklı bakış açılarına sahiptir.

Talat Paşa’nın Meşhur sözleri, tarihteki yerini almıştır.

  1. Beni bir gün sokakta vuracaklar. Alnımdan kan akarak yere serileceğim, Yatakta ölmek nasip olmayacak. Ziyanı yok, varsın vursunlar. Vatan benim ölümümle bir şey kaybedecek değildir. Bir Talat gider, bin Talat yetişir!
  2. Millî mücadele muvaffak olacaktır, çünkü millî sınırlar dışında, Türk milletinin hakikaten sahip olduğu topraklar dışında emel beslemiyor. Bu toprağın sınırları millî misakla çizilmiştir.
  3. Bu harbin bize telkin ettiği en büyük ders asri bir milletin bilhassa ilim ve ahlakla yükselebileceği kanaatidir. Milletlerin tecrübeleri açık bir suretle gösteriyor ki, bir memlekette kanunun hakimiyetinin temin edilebilmesi için, evvelemirde ilmin ve ahlakın hakimiyetinin temin edilmesi gerekir. Gerçi bir devletin esas vazifesi kanuni bir adalet ve hürriyet vücuda getirmektir.
  4. Vatanın bütün çıkarlarından istifade eden bu halk onun (Türklerin) kaderlerine ve yüklerine asla katılmıyordu. Memleketin gerek saadetinden ve gerekli ızdıraplarından daima menfaatlar temin ediyorlardı. Vatan için hiçbir harbe iştirak etmediler ve bu uğurda bir damla kan bile dökmediler. Bilakis harp zamanlarında ticaretlerini devam ettiriyor ve taahhüt işlerine girişiyorlar, çok para kazanıyor ve iyi ve kötü günlerde rahat ve huzur içinde yaşıyorlardı. Bu lütuflara teşekkür olarak şimdi çoğunluğu teşkil eden (Türk) nüfusu kovmak ve istiklallerini temin üzere Osmanlı vatanının bir parçasını koparmak istiyorlar.

Kaynakça:

  1. https://turksandarmenians.marmara.edu.tr/tr/talat-pasanin-oldurulmesi-ve-katilin-yargilama-sureci/
  2. Avcı, Halil Ersin (2012), “Dış Destekli Uluslararası Terör Örgütü Örneği: Daşnaksutyun ve Faaliyetleri (1890-1922), Uluslararası Güvenlik ve Terörizm Dergisi, Cilt 3 (1), s. 89-101.
  3. Şakir, Ziya (2011), Yakın Tarihimizin Üç Büyük Adamı, Talât-Enver-Cemal Paşalar, İstanbul.

What are current transformers and what do they do?

Current transformers, often abbreviated as CTs, are vital components in electrical systems designed to measure and monitor electric current. They play a crucial role in ensuring the safety and efficiency of power distribution.

One of the main functions of current transformers is to step down high currents to levels that can be safely measured by instruments and protective devices. By reducing the current to a manageable level, CTs allow for accurate measurements and facilitate the operation of protective devices, such as circuit breakers.

In addition to measurement and protection, current transformers also serve as isolation devices. They create a galvanic separation between the high-voltage primary circuit and the low-voltage secondary circuit, providing a safe means of monitoring current without exposing instruments or personnel to high voltages.

Current transformers come in various types and designs, including wound primary, bar-type, and bushing-mounted CTs. Each type is suitable for specific applications, depending on factors such as the current rating, voltage level, and physical constraints of the electrical system.

Overall, current transformers are indispensable in electrical systems, enabling accurate current measurement, protection, and isolation. Their proper selection, installation, and maintenance are essential for ensuring the reliable and efficient operation of power distribution systems.

Definition and Purpose of Current Transformers

1. Measure and Transform Current

CTs accurately scale down high currents to a level that can be safely handled by measuring instruments.

2. Protect Equipment

They safeguard equipment from damage by detecting and responding to abnormal currents and short circuits.

3. Precise Monitoring

Current transformers enable accurate monitoring and control of current flow in electrical systems.

Basic Principle

CTs work on the principle of magnetic induction to measure electric current. When an electric current flows through a conductor, it generates a magnetic field around it. This magnetic field can be harnessed by a current transformer to accurately measure the current passing through the conductor. The core of a current transformer is made of a highly permeable material, such as iron or ferrite, which enhances the magnetic properties. The primary winding is connected in series with the conductor carrying the current to be measured. As the current flows through the primary winding, it creates a magnetic field in the core. According to Faraday’s law of electromagnetic induction, any change in the magnetic field through a coil will induce a voltage across the coil. In the case of a current transformer, the secondary winding is wound around the core, and the induced voltage in the secondary winding is proportional to the primary current. This induced voltage in the secondary winding can then be measured and scaled down to represent the actual current passing through the primary conductor. By carefully selecting the turns ratio between the primary and secondary windings, current transformers can accurately step down the primary current to a lower, more manageable level for measurement purposes. Overall, current transformers provide a reliable and non-intrusive method of measuring electric current. Their use in various applications, from power distribution to industrial processes, helps ensure the safety, efficiency, and proper functioning of electrical systems.

Secondary Current

The primary current induces a secondary current in the CT’s winding, which is proportional to the primary current. This principle of electromagnetic induction forms the foundation of how current transformers (CTs) operate. CTs are vital components in electrical systems, designed to accurately measure and monitor electric current. When an electric current flows through the primary winding of a CT, it creates a magnetic field around the core. This magnetic field, in turn, induces a secondary current in the secondary winding of the CT. The secondary current is proportional to the primary current, allowing for accurate measurement and monitoring of the electrical current. By stepping down the primary current to a lower, more manageable level, CTs enable the use of instruments and protective devices that are designed to operate within specific current ranges. This ensures the safety and efficiency of power distribution systems by preventing overloads and facilitating proper circuit protection. CTs are available in various types and designs, including wound primary, bar-type, and bushing-mounted CTs. Each type has its own advantages and is suitable for specific applications based on factors like current rating, voltage level, and physical constraints of the electrical system. In summary, current transformers play a critical role in accurately measuring and monitoring electric currents in electrical systems. By utilizing the principle of electromagnetic induction, CTs enable safe and efficient operation of power distribution systems, contributing to the overall reliability and performance of electrical installations.

Types of Current Transformers

  1. Split-Core
    • Allows for easy installation without disconnecting the primary conductor.
  2. Wound
    • Features a circular magnetic core with a primary winding and a secondary winding.
  3. Toroidal
    • Consists of a donut-shaped core with the primary conductor passing through the center.

Applications of Current Transformers

  1. 5K -Industrial Systems
  2. 2K+ Power Plants

Advantages of Using Current Transformers

Accurate Monitoring : Enables precise measurement and control of current flow.

Equipment Protection: Ensures the safety and reliability of electrical devices and machinery.

Common Challenges and Limitations of Current Transformers

Accuracy Issues: May experience accuracy limitations based on load and environmental conditions.

Saturation: Can saturate under fault conditions, affecting accuracy and performance.

Temperature Effects: Performance may be impacted by extreme temperatures.

Conclusion and Key Takeaways

Essential Component

CTs are indispensable in ensuring safe and reliable electrical operations.

Continuous Advancements

Ongoing developments are enhancing the accuracy and efficiency of current transformers.

Flutter ile Bluetooth Cihazları Tarama ve Bağlantı Kurup/Kaldırma Uygulaması – 3 (Izınler ve Kontroller)

Flutter ile Bluetooth Cihazları Tarama ve Bağlantı Kurup/Kaldırma Uygulaması – 1 başlığı altında verilen kodda, import kısmında flutter_blue kutuphanesine prefix verilerek tanımlanmasının sebebi flutter_reactive_ble kutuphanesinin de BluetoothDevice sınıfına sahip olmasıdır. Hangi kutuphanenin BluetoothDevice sınıfını kullanacağımızı belirtmek için kütüphanelerin birine prefix vermemiz gerekti.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_blue/flutter_blue.dart' as flutter_blue;
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:open_settings/open_settings.dart';
import 'package:permission_handler/permission_handler.dart';

flutter_blue kutuphanesine ait bir sınıf, metod veya özellik kullanıldığı zaman artık bunu belirtmemiz gerekmektedir. flutter_blue.FlutterBlue.instance veya flutter_blue.BluetoothDevice gibi kullanımlarının sebebi budur.

Uygulamanın amacı çevredeki bağlanabilecek cihazları taramak ve bu cihazlara bağlanıp, bağlı cihazlarla da bağlantıyı koparmak olduğundan iki tane boş liste tanımladık.

Bulunan cihazları listelemek için:

List<DiscoveredDevice> _discoveredDeviceList = [];

Bağlı olduğumuz cihazları listelemek için:

List<DiscoveredDevice> _connectedBluetoothDeviceList = [];

Konum ve bluetooth izinlerini uygulama başlatıldığında almak için _getBluetoothPermission(), _getLocationPermission(), _getPermissions() methodları initState içerisinde çağrıldılar.

@override
void initState() {
super.initState();

// setting devices orientation on landscape
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);

_getBluetoothPermission();
_getLocationPermission();
_getPermissions();
}

Uygulamaya ilk defa giriş yapıldığında konum ve bluetooth izinleri verilmemiş olacağından if bloğuna ilk olarak bluetoothPermission.isDenied ve locationPermission.isDenied koşullarıyla başladık böylece izin verildikten sonra bu koşullar false döndüreceğinden if bloğu tekrar koşmayacaktır.

İzinler verildikten sonra if bloğu bluetoothPermission.isDenied koşulunu sağlamayıp false’a düştüğü için sonraki koşmalarda else bloğu içerisindeki print komutu koşacak ve konsola Not Granted yazılacak, bu print komutunu Granted olarak değiştirmeniz daha doğru olur.

Future<bool> _getBluetoothPermission() async {
var bluetoothPermission = await Permission.bluetoothScan.status;

if (bluetoothPermission.isDenied) {
if (await Permission.bluetoothScan.request().isGranted) {
if (await Permission.bluetoothConnect.request().isGranted) {
print("Blueooth Permission: Granted");
return true; // Permission granted
}
}
} else {
print("Blueooth Permission: Granted");
}
return false;
}

Future<bool> _getLocationPermission() async {
var locationPermission = await Permission.location.status;

if (locationPermission.isDenied) {
if (await Permission.location.request().isGranted) {
if (await Permission.accessMediaLocation.request().isGranted) {
print("Location Permission: Granted");
return true; // Permission granted
}
}
} else {
print("Location Permission: Granted");
}
return false;
}

Alttaki _getPermissions metodunun tanımlanmasının sebebi ise yukarıdaki gibi izinleri teker teker çağırmak yerine tüm izinleri tek seferde çağırmayı denemek içindir. if bloğu içerisindeki koşulda tüm izinler izin verilmediği sürece true döndürmesi istenmiştir ama şuanki durumda izinlerden sadece birine bile izin verildiği taktirde await Permission.location.status.isDenied && await Permission.bluetoothScan.status.isDenied ifadesi false döndürür.

Bunun için && (AND) ifadesi yerine || (OR) ifadesi kullanmamız gerekmektedir veya her iki ifadenin de başına ! işareti koyabilirsiniz. Böylece sadece tüm izinler verildiği takdirde koşulumuz false döndürür ve if bloğu koşmaz.

Future<void> _getPermissions() async {
// Requesting multiple permissions at once.
if (!await Permission.location.status.isDenied &&
!await Permission.bluetoothScan.status.isDenied) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetoothScan,
].request();
print(statuses[Permission.location]);
print(“\n”);
print(statuses[Permission.bluetoothScan]);
}
}

Çevredeki cihazları taramamız için gereken şartlar sadece izinler değil, aynı zamanda taramaya çalıştığımız zamanda hem bluetooth hem de konum özelliklerinin o anda açık olması gerekmektedir. Bunu kontrol etmek için de _chechkIfBluetoothIsOn ve _chechkIfLocationIsOn methodlarını tanımladık.

Future<bool> _chechkIfBluetoothIsOn() async {
// Check bluetooth service status
var isBluetoothOn = await Permission.bluetooth.serviceStatus.isEnabled;

if (!isBluetoothOn) {
// propmpt user to enable the bluetooth if the bluetooth is off
showDialog(
context: context,
builder: (_) => AlertDialog(
title:
Text("Bluetooth Özelliği ${isBluetoothOn ? "Açık" : "Kapalı"}"),
content: const Text(
"Bu özelliği kullanmak için bluetooth özelliğinin açık olması gerekir."),
actions: [
ElevatedButton(
onPressed: () =>
Navigator.of(context, rootNavigator: true).pop(false),
child: Text(isBluetoothOn ? "Kapat" : "Vazgeç")),
ElevatedButton(
// make the button not intractable when the location is on
onPressed: () async => isBluetoothOn
? null
: {
Navigator.of(context, rootNavigator: true).pop(),
await OpenSettings.openBluetoothSetting(),
},
child: Text(isBluetoothOn ? "" : "Aç")),
],
elevation: 12.0,
backgroundColor: Colors.white,
),
barrierDismissible: true,
);
} else {
//dismiss dialog box
}
return isBluetoothOn;
}

Burada bluetooth servisi açık değilse kullanıcıyı AlertDialog ile uyarıyoruz ve bluetooth servisini açması için yönlendiriyoruz.

await OpenSettings.openBluetoothSetting() satırının amacı Aç tuşuna tıklandığında kullanıcıyı bluetooth ayarlarına yönlendirmek, bu methodu ‘open_settings‘ kutuphanesini import ederek kullanabiliyoruz.


Navigator.of(context, rootNavigator: true).pop(), satırı ise kullanıcıyı yönlendirdiğimizde AlertDialog’u kapatmak içindir, böylece kullanıcı izin verip uygulamaya döndüğünde AlertBox ile karşılaşmayacak.

İlk başlıkta verilen kodda Scan Devices ve List Connected Devices tuşlarında hem if koşulunda hem de ek olarak onPressed metodu altında bluetooth ve konum izinleri istendiğinden iki tane AlertDialog üst üste oluşturulmaktadır. Bu durumu çözmek için _chechkIfBluetoothIsOn ve _checkIfLocationIsOn satırları “Scan Devices” ve “List Connected Devices” tuşlarının onPressed metodundan silinebilir.

TextButton(
onPressed: () async {
_getPermissions();
/* _chechkIfBluetoothIsOn();
_checkIfLocationIsOn(); */

if (await _chechkIfBluetoothIsOn() &&
await _checkIfLocationIsOn()) {
_scanForAvaileableBluetoothDevices();
} else {
print(
"Blueooth veya Location özellikleri açık olmadığından tarama yapılamadı.");
}
},
child: const Text('Scan Devices'),

Yukarıda gösterildiği gibi bu iki satırı yorum satırı da yapabilirsiniz, aynı durum “List Connected Devices” tuşu için de geçerlidir ve aynı işlemi o tuş için de uygulayabilirsiniz.

Flutter ile Bluetooth Cihazları Tarama ve Bağlantı Kurup/Kaldırma Uygulaması – 2

Flutter reactive BLE ve FlutterBlue kütüphaneleri bluetooth cihazlarını bulmak, bağlanmak ve bu cihazlar üzerinden bilgi çekmek için kullanılanılan kütüphanelerdir.

Bu uygulamada Flutter reactive Ble kütüphanesini çevredeki bluetooth cihazlarını bulmak, listelemek ve bağlanmak için, FlutterBlue kütüphanesini de bağlı olduğumuz cihazları listelemek için kullanıyoruz.

Kodların işlevlerini açıklamadan önce kısaca bluetooth cihazlarının çalışma mantığına göz atalım. Uygulamalarımız bluetooth donanımlarıyla iletişim kurarken alttaki katmanlı yapıda Generic Access Profile (GAP) ve Generic Attribute Profile (GATT) katmanları üzerinden bluetooth cihaza bağlanma ve bağlandıktan sonraki iletişim için bu katmanları kullanırlar.

GAP: Cihazların keşfedilmesi ve birbirleri arasındaki bağlantı ile ilgili prosedürlerin çoğunu GAP katmanı üstlenir.

GATT: Uygulamalarımız, GATT katmanını bağlı olan iki cihaz arasındaki veri iletimini sağlamak için kullanır.

GATT iki cihaz arasında bağlantı sağlandıktan sonra devreye girer yani ilk önce GAP ile cihazlar birbirine bağlanıyor sonra GATT ile birbirleri arasında veri alışverişini gerçekleştiriyorlar.

ATT (Attribute Proctocol): Service ve Characteristic ve ilişkili verilerin, herbiri benzersiz 16-bitlik ID’lerle basit tablolar şeklinde tutulması için kullanılır.

GATT server: GATT Client tarafından yazılan veya okunan “characterictic veritabanını” bulunduran cihazlardır.

GATT client: GATT server’dan verileri okuyan veya server’a yazan cihazlardır.

Peripheral: bağlanacağımız bluetooth cihazlar (saat, kulaklık, fare, klavye, sensörler gibi)

Center: bağlantıyı yapacak olduğumuz cihazlar (telefon, tablet, bilgisayar gibi)

Bu durumda her iki cihazda GATT server ve GATT client olabilir, her iki cihazda birbiri üzerinde okuma ve yazma işlemi gerçekleştiriyor.

Peripheral ile center arasındaki ilişki tekli şekildedir yani peripheral bir center ile bağlantı halindeyken, diğer cihazlar bu peripheral’ı göremezler veya bu peripheral’a bağlanamazlar. Bu durum peripheral ve center arasındaki bağlantı sonlanıncaya kadar böyle devam eder.

Center ile peripheral arasındaki ilişki ise çoklu olabilir yani bir center birden fazla peripheral ile aynı anda bağlı olabilir.

Profile: Service kümesi, (Fitness profili; kalp atış hızı servisi, kan basıncı servisi gibi servisleri içerir)

Service: Characteristic kümesi, (Kalp atış hızı servisi; kalp atış hızı değeri, kalp atış hızlarının zamanı gibi karakteristikleri içerir)

Characteristic: Değer ve Başlıktan (Value ve Label) oluşan veri (kalp atış hızı değeri: 10 gibi)

Profile: Neyin sunulduğunu,

Service: Nasıl sunulduğunu,

Characteristic ise Ne sunulduğunu tanımlar.

Veriler cihazların belleğinde “characteristic” şeklinde tutulurlar.

Peripheralların birbiri arasında veri alışverişi yapmaları gerektiği durumlarda bu işlem center üzerinden gerçekleştirilir.

Bizim yaptığımız uygulamanın çalışma şeklini ve yaptığımız listelemeler ve listeler arasındaki ilişkilerin anlam kazanması için buraya kadar olan kısım yeterlidir.

Daha fazla bilgiye sahip olmak isterseniz alttaki linklere göz atabilirsiniz:
https://www.bluetooth.com/bluetooth-resources/bluetooth-5-go-faster-go-further/

https://docs.silabs.com/bluetooth/6.1.0/bluetooth-gatt

https://learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt

https://software-dl.ti.com/lprf/simplelink_cc2640r2_latest/docs/blestack/ble_user_guide/html/ble-stack-3.x/gatt.html

Flutter ile Bluetooth Cihazları Tarama ve Bağlantı Kurup/Kaldırma Uygulaması – 1

Uygulamada hem taranan cihazlar listeleneceği hem de telefonumuzun bağlantıda olduğu cihazların listeleneceği bir arayüz kullanılacak. Iki liste yan yana sergileneceği için uygulamanın yönü landscapeRight ve landscapeLeft olarak ayarlanmıştır.

Ekranı yan döndürme işlemi alttaki kod bloğu ile gerçekleştirebilir.

@override
void initState() {
super.initState();

// setting devices orientation on landscape
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
}

Aynı zamanda DeviceOrientation.portraitDown ve DeviceOrientation.portraitUp satırları ile de uygulamanın sadece dikey eksenlerde çalışması sağlanabilir.

Uygulamanın şu anki görüntüsü aşağıdaki gibidir.

Uygulamamızın çalışma mantığı alttaki akış şemasında verilmiştir.

Çevredeki bağlanılabilecek cihazları bulup listelemek için Appbar’da yer alan “Scan Devices” TextButton’a tıklıyoruz. “List Connected Devices” TextButton’a tıklandığında ise bize o anlık bağlı olunan cihazlar listelenecek.

Ekranın sol kısmında bağlanmaya hazır cihazlar, sağ kısmında ise bağlı olduğumuz cihazlar listelenmektedir. Soldaki listeden seçilen bir cihaza bağlanılması durumunda listeler güncellenecektir, yani seçtiğimiz cihaza başarılı bir şekilde bağlanabilirsek artık cihaz sağda listelenecektir. Ayni mantikla sağ listede yer alan bir cihaz ile olan bağlantının kalkması durumunda bu cihaz da listeler güncellendiğinde sol listede yer alacaktır.

Uygulamanın kodu altta verilmiştir, main.dart dosyası:

import 'dart:async';
import 'dart:core';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_blue/flutter_blue.dart' as flutter_blue;
import 'package:flutter_blue/gen/flutterblue.pb.dart';
import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:open_settings/open_settings.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Android Studio',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});

final String title;

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
final _reactive_Ble = FlutterReactiveBle();
final _flutter_Blue = flutter_blue.FlutterBlue.instance;
// Discovered Device List
List<DiscoveredDevice> _discoveredDeviceList = [];
// To get Device Connection States
Stream<ConnectionStateUpdate> get state => _deviceConnectionController.stream;
// Connection Update Control Stream
final _deviceConnectionController = StreamController<ConnectionStateUpdate>();
//Bluetooth Low Energy Connection State Update
late StreamSubscription<ConnectionStateUpdate> _ble_Connection;
String connectionMessage = "";
// Connected Bluetooth Device List
List<flutter_blue.BluetoothDevice> _connectedBluetoothDeviceList = [];

// defined to be used for defining UI behavior
var _isConnecting = false;

@override
void initState() {
super.initState();

// setting devices orientation on landscape
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);

_getBluetoothPermission();
_getLocationPermission();
_getPermissions();
}

// Listen to stateStream for updates
/*FlutterBlue.instance.state.listen((BluetoothState state) {});*/

Future<bool> _getBluetoothPermission() async {
var bluetoothPermission = await Permission.bluetoothScan.status;

if (bluetoothPermission.isDenied) {
if (await Permission.bluetoothScan.request().isGranted) {
if (await Permission.bluetoothConnect.request().isGranted) {
print("Blueooth Permission: Granted");
return true; // Permission granted
}
}
} else {
print("Blueooth Permission: Not Granted");
}
return false;
}

Future<bool> _getLocationPermission() async {
var locationPermission = await Permission.location.status;

if (locationPermission.isDenied) {
if (await Permission.location.request().isGranted) {
if (await Permission.accessMediaLocation.request().isGranted) {
print("Location Permission: Granted");
return true; // Permission granted
}
}
} else {
print("Location Permission: Not Granted");
}
return false;
}

Future<void> _getPermissions() async {
// Requesting multiple permissions at once.
if (await Permission.location.status.isDenied &&
await Permission.bluetoothScan.status.isDenied) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.bluetoothScan,
].request();
print(statuses[Permission.location]);
print("\n");
print(statuses[Permission.bluetoothScan]);
}
}

Future<bool> _chechkIfBluetoothIsOn() async {
// Check bluetooth service status
var isBluetoothOn = await Permission.bluetooth.serviceStatus.isEnabled;

if (!isBluetoothOn) {
// propmpt user to enable the bluetooth if the bluetooth is off
showDialog(
context: context,
builder: (_) => AlertDialog(
title:
Text("Bluetooth Özelliği ${isBluetoothOn ? "Açık" : "Kapalı"}"),
content: const Text(
"Bu özelliği kullanmak için bluetooth özelliğinin açık olması gerekir."),
actions: [
ElevatedButton(
onPressed: () =>
Navigator.of(context, rootNavigator: true).pop(false),
child: Text(isBluetoothOn ? "Kapat" : "Vazgeç")),
ElevatedButton(
// make the button not intractable when the location is on
onPressed: () async => isBluetoothOn
? null
: {
Navigator.of(context, rootNavigator: true).pop(),
await OpenSettings.openBluetoothSetting(),
},
child: Text(isBluetoothOn ? "" : "Aç")),
],
elevation: 12.0,
backgroundColor: Colors.white,
),
barrierDismissible: true,
);
} else {
//dismiss dialog box
}
return isBluetoothOn;
}

Future<bool> _checkIfLocationIsOn() async {
// Check location service status
var isLocationOn =
await Permission.locationWhenInUse.serviceStatus.isEnabled;

if (!isLocationOn) {
// Request location permission
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text("Konum Özelliği ${isLocationOn ? "Açık" : "Kapalı"}"),
content: const Text(
"Bu özelliği kullanmak için konum özelliğinin açık olması gerekir."),
actions: [
ElevatedButton(
onPressed: () =>
Navigator.of(context, rootNavigator: true).pop(false),
child: Text(isLocationOn ? "Kapat" : "Vazgeç")),
ElevatedButton(
// make the button not intractable when th location is on
onPressed: () async => isLocationOn
? null
: {
Navigator.of(context, rootNavigator: true).pop(),
await OpenSettings.openLocationSourceSetting(),
},
child: Text(isLocationOn ? "" : "Aç")),
],
elevation: 12.0,
backgroundColor: Colors.white,
),
barrierDismissible: true,
);
} else {}
return isLocationOn;
}

void _scanForAvaileableBluetoothDevices() {
setState(() {
_discoveredDeviceList = [];
});

StreamSubscription<DiscoveredDevice> scanSubscription =
_reactive_Ble.scanForDevices(
withServices: [],
scanMode: ScanMode.lowLatency,
).listen((device) {
setState(() {
// if device has a name and not on the list, add device to the list
if (!_discoveredDeviceList
.any((element) => element.id == device.id) &&
device.name != "") {
_discoveredDeviceList.add(device);
}
});
}, onError: (error) {
print("Error occured while scanning: $error");
});

Future.delayed(const Duration(seconds: 10)).then((_) {
scanSubscription.cancel();
print("Scan completed");
});

print("Available Bluetooth Devices is Dsplayed:");
}

Future<void> _listConnectedBluetoothDevices() async {
var connectedDevices = await _flutter_Blue.connectedDevices;

setState(() => _connectedBluetoothDeviceList = connectedDevices );
print("_connectedBluetoothDeviceList.lenght: ${_connectedBluetoothDeviceList.length}");
print("connectedDevices count: ${connectedDevices.length}");
print("Connected Device List is Displayed:");
}

Future<void> _connectToTheSelectedDevice(
BuildContext context,
DiscoveredDevice discoveredDevice
) async {

setState(() {
_isConnecting = true;
});

_ble_Connection = _reactive_Ble.connectToDevice(
id: discoveredDevice.id,
connectionTimeout: const Duration (seconds: 30)).listen((update) async {
// connection update handler (async)
print('ConnectionState for device : ${update.connectionState}');

setState(() {
if (update.connectionState == DeviceConnectionState.connecting) {
connectionMessage = "Connecting...";
}

if (update.connectionState == DeviceConnectionState.connected) {
connectionMessage =
"Connected";
}

if (update.connectionState == DeviceConnectionState.disconnected) {
connectionMessage = "Disconnected";
}
});
_deviceConnectionController.add(update);

if (update.connectionState == DeviceConnectionState.connecting) {}
if (update.connectionState == DeviceConnectionState.connected) {
_isConnecting = false;
print("Recalling the updated lists after connecting a device");
_scanForAvaileableBluetoothDevices();
_listConnectedBluetoothDevices();
}
if (update.connectionState == DeviceConnectionState.disconnected) {
_isConnecting = false;
print("DeviceConnectionState.disconnected");
print("Recalling the updated lists after disconnecting a device");
_scanForAvaileableBluetoothDevices();
_listConnectedBluetoothDevices();
}
},
onError: (Object error) => print("Connecting to device resulted in error $error"),
);
}

@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xfff5f5f5),
appBar: AppBar(
elevation: 0,
centerTitle: false,
automaticallyImplyLeading: false,
backgroundColor: const Color(0xffffffff),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.zero,
),
title: const Text(
"AppBar",
style: TextStyle(
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
fontSize: 14,
color: Color(0xff000000),
),
),
actions: [
TextButton(
onPressed: () async {
_getPermissions();
_chechkIfBluetoothIsOn();
_checkIfLocationIsOn();

if (await _chechkIfBluetoothIsOn() &&
await _checkIfLocationIsOn()) {
_scanForAvaileableBluetoothDevices();
} else {
print(
"Blueooth ve Location özellikleri açık olmadığından tarama yapılamadı.");
}
},
child: const Text('Scan Devices'),
),
TextButton(
onPressed: () async {
_getPermissions();
_chechkIfBluetoothIsOn();
_checkIfLocationIsOn();

print("Connected Device Count: ${_connectedBluetoothDeviceList.length}");

if (await _chechkIfBluetoothIsOn() &&
await _checkIfLocationIsOn()) {
_listConnectedBluetoothDevices();
} else {
print(
"Blueooth ve Location özellikleri açık olmadığından liste yenilenemedi.");
}
},
child: const Text('List Connected Devices'),
)
],
),
body: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: ListView.builder(
itemCount: _discoveredDeviceList.length,
itemBuilder: (BuildContext context, int index) {
final scanned_Device = _discoveredDeviceList[index];
return Column(
children: [
ListTile(
title: Text(scanned_Device.name),
subtitle: Text(scanned_Device.id),
trailing: ElevatedButton(
onPressed: _isConnecting
? null
: () {
_connectToTheSelectedDevice(context, scanned_Device);
print(_connectedBluetoothDeviceList.length);
},
child: const Text("Bağlan"),
style: ElevatedButton.styleFrom(
backgroundColor: _isConnecting
? Colors.red
: Colors.green,
foregroundColor: Colors.white,
),
),
tileColor: Colors.lightBlue,
textColor: Colors.white,
),
],
);
},
),
),
Expanded(
child: ListView.builder(
itemCount: _connectedBluetoothDeviceList.length,
itemBuilder: (BuildContext context, int index) {
final connected_Device = _connectedBluetoothDeviceList[index];
return Column(
children: [
ListTile(
title: Text(connected_Device.name),
subtitle: Text("${connected_Device.id}"),
trailing: ElevatedButton (
onPressed: () async {
_ble_Connection.cancel();
//connected_Device.disconnect();
print("connected_Device.disconnect() Ran");
await Future.delayed(const Duration(milliseconds: 100));
_listConnectedBluetoothDevices();
print("_listConnectedBluetoothDevices() Ran");
},
child: const Text("Unut"),
),
),
],
);
},
),
)
],
),
);
}

@override
void dispose() {
super.dispose();
}
}

pubspec.yaml dosyası:

name: ...
description: "..."

publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
sdk: '>=3.3.0 <4.0.0'

dependencies:
flutter:
sdk: flutter

open_settings:

cupertino_icons: ^1.0.6
flutter_svg: ^2.0.10+1
flutter_reactive_ble: ^5.3.1
permission_handler: ^11.2.0
flutter_joystick: ^0.0.4
flutter_blue: ^0.8.0
get:

dev_dependencies:
flutter_test:
sdk: flutter

flutter_lints: ^3.0.0

flutter:

uses-material-design: true

android/app/src/main/AndroidManifest.xml dosyasında <manifest> ve <application> başlıkları arasına altta verilen şekilde <usus-permission …> satırlarını ekleyin:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
tools:remove="android:usesPermissionFlags"/>

<application ...>

android/app/src/build.gradle dosyasında android { … defaultConfig { … bloğunun içinde minSdkVersion’u 21 olarak değiştirin:

android {
namespace "com.beyhude.flutterandroidstudio"
compileSdk flutter.compileSdkVersion
ndkVersion flutter.ndkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.beyhude.flutterandroidstudio"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

Bir sonraki yazıda Bluetooth cihazlarının çalışma mantığına, kod anlatımlarına ve rastlanılan hatalara değinilecektir, eğer yukarıdaki kodlar direkt olarak çalışmazsa:
https://pub.dev/packages/flutter_blue,
https://pub.dev/packages/flutter_reactive_ble,
https://pub.dev/packages/permission_handler/install ve
https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration
sayfalarından yararlanabilirsiniz. İyi günler.