Popüler I2C protokolü, iki veya daha fazla Arduino kartının iletişim kurmasını sağlar. Bunları nasıl bağlayacağınızı ve kodlayacağınızı keşfedin.

Tek bir Arduino birçok görevi yerine getirebilirken, bazı projeler farklı işlevleri yerine getirmek için birden fazla kartın kullanılmasını gerektirebilir. Bu nedenle, iki mikrodenetleyici arasında veri aktarımını sağlamak için CAN, SPI, I2C veya UART gibi bir iletişim protokolü kurulmalıdır.

Bu kılavuzda, I2C'nin nasıl çalıştığının temellerini, donanım bağlantılarını ve iki Arduino kartını I2C master ve slave cihazları olarak ayarlamak için gereken yazılım uygulamasını ele alacağız.

I2C Nedir?

Inter-Integrated Circuit (I2C), elektronik cihazlar arasında veri aktarımını sağlamak için gömülü sistemlerde ve mikrodenetleyicilerde yaygın olarak kullanılan bir iletişim protokolüdür. SPI'den (Serial Peripheral Interface) farklı olarak I2C, birden fazla ana cihazı tek veya birden fazla bağımlı cihazla bir veri yoluna bağlamanıza izin verir. İlk olarak Philips tarafından kullanılmıştır ve İki Telli Arayüz (TWI) iletişim protokolü olarak da bilinir.

I2C İletişimi Nasıl Çalışır?

I2C iki yönlü hat kullanır: Seri Veri (SDA) ve Seri Saat (SCL), verileri aktarmak ve cihazlar arasındaki iletişimi senkronize etmek için. I2C veriyoluna bağlı her cihazın, iletişim sırasında onu tanımlayan benzersiz bir adresi vardır. I2C protokolü, birden fazla cihazın aynı veri yolunu paylaşmasına izin verir ve her cihaz bir ana veya bağımlı olarak hareket edebilir.

Haberleşme ana cihaz tarafından başlatılır ve bağımlı cihazların yanlış adreslenmesi aktarımda hatalara neden olabilir. Şu konudaki ayrıntılı kılavuzumuza göz atın: UART, SPI ve I2C seri iletişimleri nasıl çalışır? size biraz bağlam vermek için.

I2C iletişiminin önemli bir avantajı, güç yönetimi söz konusu olduğunda sunduğu esnekliktir. Farklı voltaj seviyelerinde çalışan cihazlar, voltaj kaydırıcılar yardımıyla etkili bir şekilde iletişim kurabilir. Bu, 3,3 V'ta çalışan cihazların 5 V I2C veriyoluna bağlanmak için voltaj kaydırıcılara ihtiyaç duyduğu anlamına gelir.

Tel Kitaplığı

Wire kitaplığı, I2C üzerinden iletişim kurmak için işlevler sağlayan yerleşik bir Arduino kitaplığıdır. I2C iletişimi için Arduino kartında iki pin (SDA ve SCL) kullanır.

Arduino Uno'daki I2C pinleri:

Arduino Nano I2C pinleri:

Kütüphaneyi kullanmak için, Wire.h Arduino taslağınızın başındaki başlık dosyası.

#katmak

Wire kitaplığı, bir I2C cihazıyla iletişim başlatmak, veri göndermek ve veri almak için işlevler sağlar. Bilmeniz gereken bazı önemli işlevler şunları içerir:

  • Wire.begin(): I2C veriyoluna katılmak ve iletişimi başlatmak için kullanılır.
  • Wire.beginTransmission(): bağımlı adresi belirlemek ve bir iletimi başlatmak için kullanılır.
  • Wire.write(): I2C cihazına veri göndermek için kullanılır.
  • Wire.endTransmission(): iletimi sonlandırmak ve hataları kontrol etmek için kullanılır.
  • Wire.requestFrom(): I2C cihazından veri talep etmek için kullanılır.
  • Wire.available(): verilerin I2C cihazından okunabilir olup olmadığını kontrol etmek için kullanılır.
  • Wire.read(): I2C cihazından veri okumak için kullanılır.

Kullan Wire.beginTransmission() argüman olarak eklenen sensörün adresini ayarlamak için işlev. Örneğin, sensörün adresi ise 0x68, şunları kullanırsınız:

Tel.iletim başla(0x68);

Arduino I2C Donanım Kurulumu

I2C kullanarak iki Arduino kartını bağlamak için aşağıdaki donanım bileşenlerine ihtiyacınız olacak:

  • İki Arduino kartı (ana ve bağımlı)
  • Breadboard
  • jumper telleri
  • İki adet 4,7kΩ çekme direnci

Bağlan SDA Ve SCL her iki Arduino kartının pimlerini bir devre tahtasına. Çekme dirençlerini aralarına bağlayın. SDA Ve SCL pimler ve 5V Breadboard üzerindeki güç rayı. Son olarak, iki devre tahtasını atlama kablolarını kullanarak birbirine bağlayın.

Arduino Uno devresi

Arduino Nano Devre

Resim Kredisi: Arduino I2C belgeleri

Arduino Kartlarını I2C Master ve Slave Cihazları Olarak Ayarlama

Kullan Wire.requestFrom() iletişim kurmak istediğimiz bağımlı cihazın adresini belirtmek için işlev. Daha sonra Wire.read() bağımlı cihazdan veri alma işlevi.

Ana cihaz kodu:

#katmak
geçersizkurmak(){
Tel.başlamak(); // i2c veriyoluna katıl
Seri.başlamak(9600); // çıktı için seriyi başlat
}
geçersizveri almak(){
int adres = 8;
int bytesToRead = 6;
Tel.istekKimden(adres, bytesToRead);
sırasında (Tel.mevcut()) {
karakter veri = Tel.Okumak();
Seri.Yazdır(veri);
}
gecikme(500);
}
geçersizdöngü(){
veri almak();
}

bu Wire.onReceive() işlevi, köle ana cihazdan veri aldığında ne yapılacağını belirtmek için kullanılır. Yukarıdaki kodda, Wire.available() işlev, verilerin mevcut olup olmadığını kontrol eder ve Wire.read() işlevi, ana cihaz tarafından gönderilen verileri okur.

Bağımlı cihaz kodu:

#katmak
geçersizkurmak(){
Tel.başlamak(8); // I2C veriyoluna 8 adresi ile katılın
Tel.alındığında(alma Olayı); // veri alındığında acceptEvent'i çağır
}
geçersizdöngü(){
gecikme(100);
}
geçersizalmaEtkinliği(int bayt){
Tel.yazmak("Merhaba "); // yönetici tarafından beklendiği gibi 6 baytlık mesajla yanıt verin
}

I2C Kullanarak Veri Gönderme ve Alma

Bu örnekte, bağımlı Arduino ile arayüzlenen bir DHT11 sıcaklık sensöründen sıcaklığı okuyalım ve ana Arduino'nun seri monitörüne yazdıralım.

Daha önce yazdığımız kodu, daha sonra I2C bus üzerinden ana karta göndereceğimiz sıcaklık ölçümünü içerecek şekilde değiştirelim. Ana kart daha sonra gönderdiğimiz değeri okuyabilir ve seri monitörde görüntüleyebilir.

Ana cihaz kodu:

#katmak
geçersizkurmak(){
Tel.başlamak();
Seri.başlamak(9600);
Seri.yazdır("Ana Başlatıldı!");
}
geçersizdöngü(){
Tel.istekKimden(8, 1); // Slave'den sıcaklık verisi iste
eğer (Tel.mevcut()) {
bayt sıcaklık = Tel.Okumak(); // Slave'den sıcaklık verilerini oku
Seri.Yazdır("Sıcaklık: ");
Seri.Yazdır(sıcaklık);
Seri.yazdır("°C");
}
gecikme(2000); // Tekrar sıcaklık istemeden önce 2 saniye bekleyin
}

Bağımlı cihaz kodu:

#katmak
#katmak

#tanımlamak DHTPIN 4 // DHT sensörüne bağlı pin
#tanımlamak DHTTİPİ DHT11 // DHT sensör tipi
DHT dht(DHTPIN, DHTTİPİ);
bayt sıcaklık;

geçersizkurmak(){
Tel.başlamak(8); // Köle adresi 8'dir
Tel.istek üzerine(istekEtkinliği);
dht.başlamak();
}

geçersizdöngü(){
gecikme(2000); // DHT'nin sabitlenmesi için 2 saniye bekleyin
sıcaklık = dht.Okuma sıcaklığı(); // DHT sensöründen sıcaklığı oku
}

geçersizistekEtkinliği(){
Tel.yazmak(sıcaklık); // Sıcaklık verilerini master'a gönder
}

Bu kodu, projenizde sahip olabileceğiniz sensörlere uyacak şekilde özelleştirebilir veya hatta sensör değerlerini bir ekran modülünde görüntüleyebilirsiniz. kendi oda termometrenizi ve nem ölçerinizi yapın.

Arduino'da I2C ile Slave Adresleme

Böyle bir projede I2C veriyoluna eklenen bileşenlerden değerleri okumak için, kodlama sırasında doğru bağımlı adresi eklemeniz önemlidir. Şans eseri, Arduino, köle tanımlama sürecini basitleştiren bir tarayıcı kitaplığı sunar. adresler, uzun sensör veri sayfalarını gözden geçirme ihtiyacını ortadan kaldırır ve çevrimiçi kafa karıştırıcı belgeler.

I2C veriyolunda bulunan herhangi bir bağımlı aygıtın adresini belirlemek için aşağıdaki kodu kullanın.

#katmak // I2C iletişimi için Wire kitaplığını dahil edin

geçersizkurmak(){
Tel.başlamak(); // I2C iletişimini başlat
Seri.başlamak(9600); // 9600 baud hızı ile seri iletişimi başlat
sırasında (!Seri); // Seri bağlantının kurulmasını bekleyin
Seri.yazdır("\nI2C Tarayıcı"); // I2C taramasının başladığını belirten bir mesaj yazdırın
}

geçersizdöngü(){
bayt hata, adres; // Hataları ve cihaz adreslerini saklamak için değişkenler bildirin
int nCihazlar; // Bulunan cihaz sayısını saklamak için bir değişken tanımlayın

Seri.yazdır("Tarama..."); // I2C taramasının başladığını belirten bir mesaj yazdırın

nCihazlar = 0; // Bulunan cihaz sayısını 0 olarak ayarla
için (adres = 1; adres < 127; adres++) { // Tüm olası I2C adreslerini yineleyin
Tel.iletim başla(adres); // Geçerli adrese bir iletim başlat
hata = Tel.bitiş İletimi(); // İletimi sonlandırın ve hataları saklayın

eğer (hata == 0) { // Herhangi bir hata bulunmadıysa
Seri.Yazdır("0x adresinde I2C cihazı bulundu"); // Bir aygıtın bulunduğunu belirten bir mesaj yazdır
eğer (adres < 16) Seri.Yazdır("0"); // Adres 16'dan küçükse biçimlendirme amacıyla başa 0 ekleyin
Seri.Yazdır(adres, HEX); // Adresi onaltılık biçimde yazdır
Seri.yazdır(" !"); // Bir aygıtın bulunduğunu belirten bir mesaj yazdır

nCihazlar++; // Bulunan cihaz sayısını artırın
}
başkaeğer (hata == 4) { // Bir hata bulunursa
Seri.Yazdır("0x adresinde bilinmeyen hata"); // Bir hatanın bulunduğunu belirten bir mesaj yazdır
eğer (adres < 16) Seri.Yazdır("0"); // Adres 16'dan küçükse biçimlendirme amacıyla başa 0 ekleyin
Seri.yazdır(adres, HEX); // Adresi onaltılık biçimde yazdır
}
}
eğer (nCihazlar == 0) { // Hiçbir cihaz bulunamadıysa
Seri.yazdır("I2C cihazı bulunamadı\n"); // Hiçbir aygıtın bulunamadığını belirten bir mesaj yazdırın
}
başka { // Aygıtlar bulunursa
Seri.yazdır("bitti\n"); // I2C taramasının bittiğini gösteren bir mesaj yazdırın
}
gecikme(5000); // Bir sonraki taramaya başlamadan önce 5 saniye gecikme
}

Projenizi Bugün Genişletin

I2C iletişim protokolünü kullanarak iki Arduino kartını birbirine bağlamak, tek bir kart tarafından gerçekleştirilemeyen karmaşık görevleri gerçekleştirmenin esnek ve verimli bir yolunu sunar. Wire kitaplığının yardımıyla, I2C kullanan iki pano arasındaki iletişim kolaylaştırılarak projenize daha fazla bileşen eklemenize olanak sağlanır.