Arduino I2C Kullanımı

Bu içerikte Arduino I2C kullanımına göz atıyoruz. Her Arduino geliştirme kartı, en az bir I2C portunu destekler. Benzer şekilde Arduino Uno da bir adet I2C portuna sahiptir. Arduino’yu bir I2C master ve bir I2C slave cihazı olarak yapılandırmayı öğreneceğiz. Sonunda, örnek amaçlı iki Arduino kartı arasında I2C iletişimi gerçekleştireceğiz.

I2C Nedir?

I2C, Inter-integrated devre iletişim protokolü anlamına gelir. Kısa menzilli veri aktarım uygulamaları için sadece 2 kablo gerektiren seri iletişim protokolüdür. I2C tabanlı sensörler, LCD/OLED ekranlar ve iletişim modülleri için arayüz oluşturmak için projelerde kullanılan çok popüler bir iletişim protokolüdür.

İletişim kurmak isteyen cihazlar, I2C veri yolu üzerine bağlanır. I2C veri yolu, birden çok bağımlı aygıtı ve birden çok ana aygıtı destekler.

Birçok sensör, verilerini mikrodenetleyicilere aktarmak için bu seri iletişim protokolünü kullanır veya bu protokol aracılığıyla farklı bağımlı devreler ana devrelerle iletişim kurabilir. Yalnızca kısa mesafeli veri iletimi için kullanılabilir.

I2C Pinleri

SPI ve I2C’nin ayırt edici özelliği, I2C’nin iletişimi yürütmek için sadece iki kablo kullanmasıdır. Bir kablo, cihazlar arasında veri iletimini senkronize eden SCL’dir (seri saat hattı), diğer kablo ise iletilecek gerçek verileri taşıyan SDA’dır (seri veri). Bu hatlar open-drain hatlarıdır, yani cihazlar aktif düşükse dirençleri yukarı çekmek için bağlanmaları gerekir. Veri yoluna bağlı olan her bağımlı cihaz benzersiz bir 8 bitlik adrese sahip olacaktır.

İki kablo kullanan belirli cihazlar arasındaki iletişim, her cihazın kendi benzersiz cihaz kimliğine veya adresine sahip olması ve bu adresin kullanılmasıyla sağlanır; master, iletişim kurmak için herhangi bir belirli cihazı seçebilir.

I2C BUS

Alttaki görselde, I2C veriyoluna bağlı ana ve bağımlı cihazları göstermektedir. Bu resimde Raspberry Pi master, 16×2 LCD ekran, ivme sensörü, Arduino slave olarak görev yapmaktadır.

I2C veri yolu, bağımlı ve ana bağımlı aygıtlar gibi birden çok aygıttan oluşur.

Master(Ana) Cihaz

Ana cihazlar bilgi gönderip alabilir. Slave cihazlar, masterın gönderdiği her şeye tepki verir. Bus hattında bilgi gönderirken, bir seferde yalnızca tek bir cihaz bilgi gönderebilir.

Özetle, veri aktarmak veya farklı sayıda cihazla iletişim kurmak için sadece iki kabloya ihtiyacımız var. Kısıtlı pin durumları söz konusu olduğu zaman I2C aynı anda birden fazla cihaza bağlanmaya izin verir. Tek dezavantajı, bu protokolü uzun mesafeli veri aktarımı için kullanamamanızdır.

Slave(Bağımlı) Cihaz

Her slave cihazın, veri yolundaki aygıtı tanımak için kullanılan benzersiz bir adresi vardır. Başka bir deyişle, bağımlı adres, ana aygıtın veri yolu üzerindeki belirli bir bağımlı aygıta bilgi göndermesine yardımcı olur.

Arduino I2C Kullanımı arduino i2c kullanımı,iki arduino arası haberleşme,iki arduino arası seri haberleşme,iki arduino arası i2c haberleşme,i2c nedir

SDA hattı boyunca veriler bit bit aktarılır. Aynı SPI gibi, I2C eşzamanlıdır, bitlerin çıkışı, master ve slave arasında paylaşılan bir saat sinyali tarafından bitlerin test edilmesiyle senkronize edilir.

Arduino I2C İletişim Pinleri

I2C iletişimi için, Arduino’nun farklı geliştirme kartlarında SDA ve SCL pinleri olarak ayrılmış farklı pinler bulunur:

  • Arduino UNO’da Pin A4 = SDA ve Pin A5 = SCL
  • Arduino Mega2560’da Pin 20 = SDA ve Pin 21 = SCL
  • Arduino Leonardo’da Pin 2 = SDA ve Pin 3 = SCL
  • Arduino Due’da Pin 20 = SDA ve Pin 21 = SCL, SDA1, SCL1

Aşağıdaki Arduino UNO’da, bu makalede kullanılacak olan SDA ve SCL pinlerini göstermektedir:

Arduino I2C Kullanımı arduino i2c kullanımı,iki arduino arası haberleşme,iki arduino arası seri haberleşme,iki arduino arası i2c haberleşme,i2c nedir

Arduino I2C İletişim Kütüphanesi

Arduino’da I2C iletişimi için “Wire” kütüphanesi kullanılır. Aşağıdaki tanımlar bu kütüphanenin önemli işlevleridir. Ayrıca bu kütüphane Arduino IDE’ye kurulu olarak hazır bir şekilde gelir.

Wire.begin(adres)

Wire kütüphanesi bu komut kullanılarak başlatılır ve I2C veriyoluna master veya slave olarak katılır. Adres isteğe bağlıdır. Bu adres, bağımlı cihazlar için yedi bitten oluşur. Belirtilmemiş ise; cihaz bus’a master olarak katılır.

Wire.requestFrom(adres, miktar) 

Bu komut, ana cihaz tarafından bir bağımlı cihazdan bayt istemek için kullanılır. Daha sonra bu baytları toplamak için “Available()” ve “read()” işlevleri kullanılabilir. “adres”, talepte bulunulacak belirli bir bağımlı aygıtın adresidir ve “miktar”, talep edilecek bayt sayısını belirtir.

Wire.beginTransmission(adres)

Bu komut, verilen adresin slave aygıtı ile bayt iletimini başlatır. Daha sonra iletilecek baytlar write() işlevi kullanılarak sıraya alınır ve bu baytlar endTransmission() işlevi kullanılarak iletilir.

Wire.endTransmission()

Wire.beginTransmission() işlevi kullanılarak başlatılan baytların iletimi, bu komut kullanılarak sonlandırılır.

Bu fonksiyon bir argüman olarak kabul eder. Argüman TRUE ise, bayt iletiminden sonra stop komutu gönderilir ve I2C bus korunur.

Argüman FALSE ise, iletim baytlarından sonra yeniden başlatma komutu gönderir ve bus korunmaz ve mesajlar arasında başka bir ana cihazın iletimini engeller.

Wire.Write()

Bu komut aynı anda 2 işlevden birini gerçekleştirir.

  • Master tarafından bir istek yapıldığında, bu fonksiyon bağımlı cihazdan veri yazar.
  • startTransmission() işlevi ve endTransmission() işlevi çağrıları arasında, bu komut iletim için baytları sıraya koymak için kullanılır.

Wire.read()

requestFrom() komutundan sonra slave cihazdan master cihaza veya master cihazdan slave cihaza aktarılan baytlar; bu komut kullanılarak okunur.

Wire.available()

Bu komut, read() işlevi çağrıldıktan sonra alınabilecek bayt sayısını döndürür. Ana cihazda requestFrom() işlevinden sonra çağrılır ve bağımlı cihazda onReceive() işlevi içinde çağrılır.

Wire.onReceive(handler)

Bu, master cihazdan iletilen veri slave cihaz tarafından alındığında çağrılan bir işlevi kaydeder. Çağrılan işlev, işleyici tarafından temsil edilir.

İki Arduino Arası I2C Haberleşme

Bu bölümde, I2C veri yolunu kullanarak iki Arduino kartı arasında veri aktarmak için örnek bir kod göreceğiz. Bir Arduino kartını I2C master cihazı ve başka bir Arduino kartını I2C slave cihazı olarak yapılandıracağız. Master, 0 – 6 arasındaki sayıları sırayla bağımlı cihaza aktaracaktır. Slave cihaz tarafından alınan sayı 3’ten küçükse, slave Arduino’nun D13 pinine bağlı LED yanacaktır, aksi takdirde LED yanmayacaktır

Gerekli Malzemeler

  • İki Arduino Geliştirme Kartı
  • Jumper/Bağlantı kabloları
  • LED

Bağlantı Şeması

Aşağıdaki bağlantı şeması, iki Arduino kartı arasındaki I2C bağlantılarını göstermektedir.

İlk olarak master Arduino üzerindeki A4 ve A5 pinlerini slave Arduino üzerindeki benzer pinlere bağlayacağız.
Daha sonra jumper kablolar kullanarak her ikisinin de topraklamalarını(GND) ortak yapacağız.
Bağlantıları yaptıktan sonra hem slave hem de master kodlarını Arduino kartlarına yükleyin.

Arduino I2C Kullanımı arduino i2c kullanımı,iki arduino arası haberleşme,iki arduino arası seri haberleşme,iki arduino arası i2c haberleşme,i2c nedir
Solda Master Cihaz, Sağda Slave Cihaz

Master Cihaz Kodu

Burada Wire kütüphanesi dahil edilmiş ve değişken x başlatılmıştır. Bu değişkenin değeri slave cihaza iletilecektir.

#include <Wire.h>
int x = 0;

Burada wire.begin() fonksiyonu çağrılmıştır. Ayrıca dahili arabellek başlatılmış oldu.

void setup() 
{
  Wire.begin(); 
  Serial.begin(9600);
}

Burada slave adresi 9 ile iletim başlatılmıştır. Bundan sonra x değeri I2C bus üzerinden iletim için kuyruğa alınmıştır. Wire.write() işlevi, I2C veriyolundaki mevcut ‘x’ değerini iletir. Son olarak, x’in değeri iletilmiş ve bus, endTransmission() komutu kullanılarak korunmuştur.

Wire.beginTransmission(9);
Wire.write(x);              
Wire.endTransmission();

x değeri döngüde 200 mili saniyelik bir gecikmeyle birer birer artırılır, x değeri 6’dan büyükse bu değer 0’a sıfırlanır ve tekrar 0’dan artırılır.

x++;
if (x > 6) 
  {
    x = 0;
  }
delay(200);

Kodun Tamamı

#include <Wire.h>
int x = 0;

void setup() 
{
  Wire.begin(); 
  Serial.begin(9600);
}

void loop() 
{
  Wire.beginTransmission(9);
  Wire.write(x);              
  Wire.endTransmission();
 
  x++;
  if (x > 6) 
  {
    x = 0;
  }
  delay(200);
}

Slave Cihaz Kodu

İlk olarak Arduino’nun D13 pininin sembolik adını tanımlıyoruz. Pin D13 yani LED, master cihazdan alınan değere bağlı olarak açılır ve kapanır. Ayrıca, x değişkenini sıfır ile bildirir ve başlatırız. Bu değişken x, master Arduino’dan alınan değeri depolamak için kullanılacaktır.

#include <Wire.h>
int LED = 13;
int x = 0;

Kurulum işlevinin içinde, pinMode() işlevini kullanarak LED pinini çıkış pini olarak ayarladık. Ayrıca Arduino’nun slave adresini 9 olarak ayarladık.

 pinMode(LED, OUTPUT);
 Wire.begin(9); 
 Wire.onReceive(receiveEvent);
 Serial.begin(9600);

Tanımlar ve fonksiyon çağırma işlemleri yukarıdaki bölümde tanımlandığı gibi yapılmıştır. Burada ReceiveEvent() fonksiyonu onReceive(handler) fonksiyonu çağrılarak kaydedilmiştir.

void receiveEvent(int bytes) 
{
  x = Wire.read();
}

Bu reciveEvent() işlevi burada tanımlanmıştır. Ana cihaz tarafından gönderilecek olan 1’den 6’ya kadar olan değeri okur; ve daha sonra bu değeri, programın kurulum işlevinde bildirilen x değişkeninde saklar.

void loop() 
{
  if (x <= 3) 
  {
    digitalWrite(LED, HIGH);
  }
  else 
  {
    digitalWrite(LED, LOW);
  }
}

Master cihazdan alınan x değeri 3’ten küçük veya eşit ise 13. pindeki LED AÇIK, x değeri 3’ten büyükse 13. pindeki LED KAPALI konuma getirilir.

Kodun Tamamı

#include <Wire.h>
int LED = 13;
int x = 0;

void setup() 
{
  pinMode (LED, OUTPUT);
  Wire.begin(9); 
  Wire.onReceive(receiveEvent);
  Serial.begin(9600);
}

void receiveEvent(int bytes) 
{
  x = Wire.read();
}

void loop() 
{
  if (x <= 3) 
  {
    digitalWrite(LED, HIGH);
  }
  else 
  {
    digitalWrite(LED, LOW);
  }
}

I2C Kullanım Alanları

  • I2C, monitörlerde renk dengesi, değişen kontrast ve renk tonu için kullanılır.
  • Akıllı hoparlörde ses I2C iletişim yöntemi kullanılarak değiştirilir.
  • Bilgisayarlarda fan hızı gibi tanı sensörlerinin okunmasında kullanılır.
  • Sistem bileşenlerinde güç kaynağının açılması ve kapatılmasında kullanılır.
  • Kullanıcı ayarlarını tutan gerçek zamanlı saatlere ve NVRAM yongalarına erişimde kullanılır.

I2C Avantajları ve Dezavantajları

Avantajları

  • Çoklu master ve çoklu slave’i desteklediği için çoğu proje uyarlanabilir bir iletişim yöntemidir.
  • Yalnızca iki kablo kullanır ve çok yönlüdür, farklı bağımlı cihazların gereksinimlerine kolayca uyum sağlayabilir.

Dezavantajları

  • Uzun mesafeli iletişim için geçerli değildir. Yalnızca iki kablo kullanıldığı için yavaş hıza sahiptir.
  • Direnç kullanımı nedeniyle daha fazla alan gerektirir
  • Cihaz sayısı arttıkça karmaşıklaşır.