- I2C İletişim Protokolü nedir?
- I2C İletişim nasıl çalışır?
- I2C iletişimi nerede kullanılır?
- Arduino'da I2C
- Gerekli Bileşenler
- Devre şeması
- Çalışma Açıklaması
- Arduino'da I2C Programlama
- Master Arduino Programlama Açıklaması
- Slave Arduino Programlama Açıklaması
Önceki eğitimimizde Arduino'daki SPI iletişimi hakkında bilgi edindik. Bugün başka bir Seri İletişim Protokolü hakkında bilgi edineceğiz: I2C (Inter Integrated Circuits). I2C'yi SPI ile karşılaştırdığımızda, I2C yalnızca iki kabloya sahipken, SPI dört kablo kullanır ve I2C Çoklu Master ve Slave'e sahipken, SPI yalnızca bir ana ve birden fazla bağımlıya sahip olabilir. Yani bir projede master olması gereken birden fazla mikrodenetleyici varsa I2C kullanılır. I2C iletişimi genellikle Jiroskop, ivmeölçer, barometrik basınç sensörleri, LED ekranlar vb. İle iletişim kurmak için kullanılır.
Bu Arduino I2C eğitiminde iki arduino kartı arasında I2C iletişimini kullanacağız ve potansiyometre kullanarak birbirlerine (0 ila 127) değerler göndereceğiz. Değerler, Arduino'nun her birine bağlı 16x2 LCD'de görüntülenecektir. Burada bir Arduino Master olarak hareket edecek ve diğeri Slave olarak hareket edecektir. O halde I2C iletişimi ile ilgili girişle başlayalım.
I2C İletişim Protokolü nedir?
IIC terimi, " Inter Integrated Circuits " anlamına gelir. Normalde I2C veya I kare C olarak veya hatta bazı yerlerde 2 telli arayüz protokolü (TWI) olarak belirtilir, ancak hepsi aynı anlama gelir. I2C, senkronize bir iletişim protokolüdür, yani bilgiyi paylaşan her iki cihaz da ortak bir saat sinyalini paylaşmalıdır. Biri horoz sinyali için, diğeri ise veri göndermek ve almak için kullanılan bilgileri paylaşmak için yalnızca iki tele sahiptir.
I2C İletişim nasıl çalışır?
I2C iletişimi ilk olarak Phillips tarafından tanıtıldı. Daha önce de belirtildiği gibi, iki tele sahip, bu iki tel iki cihaza bağlanacak. Burada bir cihaz ana cihaz olarak adlandırılır ve diğer cihaz köle olarak adlandırılır. İletişim her zaman iki Master ve bir Slave arasında olmalıdır ve olacaktır. I2C iletişiminin avantajı, bir Master'a birden fazla slave'in bağlanabilmesidir.
Tam iletişim, Seri Saat (SCL) ve Seri Veri (SDA) olmak üzere bu iki kablo üzerinden gerçekleşir.
Seri Saat (SCL): Master tarafından üretilen saat sinyalini slave ile paylaşır
Seri Veri (SDA): Verileri Master ve slave arasında ve arasında gönderir.
Herhangi bir zamanda yalnızca kaptan iletişimi başlatabilecektir. Veriyolunda birden fazla slave olduğundan, ana birimin her bir slave'e farklı bir adres kullanarak başvurması gerekir. Adreslendiğinde, yalnızca bu belirli adrese sahip olan bağımlı kişi bilgilerle yanıt verirken diğerleri çıkmaya devam eder. Bu şekilde, birden fazla cihazla iletişim kurmak için aynı veri yolunu kullanabiliriz.
I2C gerilim seviyeleri önceden tanımlanmış değildir. I2C iletişimi esnektir, yani 5v volt ile çalışan cihaz I2C için 5v kullanabilir ve 3.3v cihazlar I2C iletişimi için 3v kullanabilir. Peki ya farklı voltajlarda çalışan iki cihazın I2C kullanarak iletişim kurması gerekiyorsa? Bir 5V I2C veri yolu 3.3V cihazla bağlanamaz. Bu durumda voltaj değiştiriciler, iki I2C veri yolu arasındaki voltaj seviyelerini eşleştirmek için kullanılır.
Bir işlemi çerçeveleyen bazı koşullar vardır. İletimin başlatılması, SDA'yı düşük ayarlarken master'ın SCL'yi yüksek bıraktığı aşağıdaki diyagramda 'BAŞLAT' durumu olarak tanımlanan SDA'nın düşen kenarı ile başlar.
Aşağıdaki diyagramda gösterildiği gibi, SDA'nın düşen kenarı, BAŞLAT koşulu için donanım tetikleyicisidir. Bundan sonra aynı veri yolundaki tüm cihazlar dinleme moduna geçer.
Aynı şekilde, SDA'nın yükselen kenarı yukarıdaki diyagramda 'STOP' durumu olarak gösterilen iletimi durdurur, burada master SCL'yi yüksek bırakır ve ayrıca YÜKSEK gitmek için SDA'yı serbest bırakır. Böylece SDA'nın yükselen kenarı iletimi durdurur.
R / W biti takip eden baytların iletim yönünü gösterir, YÜKSEK ise slave'in iletim yapacağı ve düşük olması master'ın iletim yapacağı anlamına gelir.
Her bit, her saat döngüsünde iletilir, bu nedenle bir bayt iletmek için 8 saat döngüsü gerekir. Gönderilen veya alınan her bayttan sonra, ACK / NACK için dokuzuncu saat döngüsü tutulur (onaylandı / onaylanmadı). Bu ACK biti duruma bağlı olarak slave veya master tarafından üretilir. ACK bit için SDA 9'da ana ya da yan tarafından düşük olarak ayarlandığında inci saat çevrimi. Dolayısıyla düşük, ACK, aksi takdirde NACK olarak kabul edilir.
I2C iletişimi nerede kullanılır?
I2C iletişimi yalnızca kısa mesafeli iletişim için kullanılır. Akıllı hale getirmek için senkronize bir saat darbesine sahip olduğu için kesinlikle güvenilirdir. Bu protokol, esas olarak bir ana bilgisayara bilgi göndermesi gereken sensör veya diğer cihazlarla iletişim kurmak için kullanılır. Bir mikrodenetleyicinin diğer birçok slave modülle minimum yalnızca kablo kullanarak iletişim kurması gerektiğinde çok kullanışlıdır. Uzun menzilli bir iletişim arıyorsanız RS232'yi denemelisiniz ve daha güvenilir bir iletişim arıyorsanız SPI protokolünü denemelisiniz.
Arduino'da I2C
Aşağıdaki resim, Arduino UNO'da bulunan I2C pinlerini göstermektedir.
I2C Hattı | Arduino'daki pin |
SDA | A4 |
SCL | A5 |
İki Arduino kullanarak I2C'yi programlamaya başlamadan önce. Arduino IDE'de kullanılan Wire kütüphanesi hakkında bilgi edinmemiz gerekiyor.
kütüphane
1. Wire.begin (adres):
Kullanım: Bu kütüphane, I2C cihazlarıyla iletişim kurmak için kullanılır. Bu, Wire kütüphanesini başlatın ve I2C veriyoluna bir master veya slave olarak katılın.
Adres: 7 bitlik slave adresi isteğe bağlıdır ve adres belirtilmezse, bu şekilde bir master olarak veriyoluna katılır.
2. Wire.read ():
Kullanım: Bu işlev, bir requestFrom () çağrısından sonra bir bağımlı aygıttan bir ana aygıta iletilen veya bir ana birimden bir ikincil aygıta iletilen, ana veya bağımlı aygıttan alınan bir baytı okumak için kullanılır.
3. Wire.write ():
Kullanım: Bu işlev, bir bağımlı veya ana cihaza veri yazmak için kullanılır.
Slave to Master: Slave, Wire.RequestFrom () ana birimde kullanıldığında verileri bir ana yöneticiye yazar.
Master'dan Slave'e: Bir ana cihazdan bağımlı cihaza aktarım için Wire.write () , Wire.beginTransmission () ve Wire.endTransmission () aramaları arasında kullanılır .
Wire.write () şu şekilde yazılabilir:
- Wire.write (değer)
değer: tek bayt olarak gönderilecek değer.
- Wire.write (dize):
string: bir dizi bayt olarak gönderilecek bir dize.
- Wire.write (veri, uzunluk):
veri: bayt olarak gönderilecek bir veri dizisi
uzunluk: iletilecek bayt sayısı.
4. Wire.beginTransmission (adres):
Kullanım: Bu işlev, verilen bağımlı adresle I2C cihazına bir iletimi başlatmak için kullanılır. Daha sonra, write () işleviyle iletim için bayt kuyruğu oluşturun ve sonra bunları endTransmission () işlevini çağırarak iletin . Cihazın 7 bitlik adresi iletilir.
5. Wire.endTransmission ();
Kullanım: Bu işlev, beginTransmission () tarafından başlatılan ve Wire.write () tarafından sıraya alınan baytları ileten bir ikincil aygıta iletimi sonlandırmak için kullanılır .
6. Wire.onRequest ();
Kullanım: Bu işlev, bir ana cihaz yardımcı cihazdan Wire.requestFrom () kullanarak veri istediğinde çağrılır . Burada içerebilir Wire.write () ana veri göndermek için işlevini.
7. Wire.onReceive ();Kullanım: Bu işlev, bir ikincil cihaz bir ana cihazdan bir veri aldığında çağrılır. Burada Wire.read (); ana bilgisayardan gönderilen verileri okuma işlevi.
8. Wire.requestFrom (adres, miktar);
Kullanım: Bu işlev, bir bağımlı cihazdan bayt istemek için ana bilgisayarda kullanılır. Wire.read () işlevi, ikincil cihazdan gönderilen verileri okumak için kullanılır.
adres: bayt istemek için aygıtın 7 bit adresi
miktar: talep edilecek bayt sayısı
Gerekli Bileşenler
- Arduino Uno (2-Nos)
- 16X2 LCD ekran modülü
- 10K Potansiyometre (4-Nos)
- Breadboard
- Kabloların Bağlanması
Devre şeması
Çalışma Açıklaması
Burada, Arduino'da I2C iletişimini göstermek için, birbirine bağlı İki 16X2 LCD ekrana sahip İki Arduino UNO kullanıyoruz ve her iki arduino'da iki potansiyometre kullanarak, master'dan slave'e ve slave'den master'a, değişkenleri değiştirerek gönderme değerlerini (0 ila 127) potansiyometre.
Arduino pini A0'da giriş analog değerini potansiyometre kullanarak (0'dan 5V'a) alıp Analog'dan Sayısal değere (0'dan 1023'e) dönüştürüyoruz. Daha sonra bu ADC değerleri, I2C iletişimi yoluyla yalnızca 7 bitlik veri gönderebildiğimiz için (0'dan 127'ye) dönüştürülür. I2C iletişimi, her iki arduino'nun A4 ve A5 pinlerindeki iki kablo aracılığıyla gerçekleşir.
Slave Arduino'nun LCD ekranındaki değerler, ana taraftaki POT'u değiştirerek değiştirilecektir ve bunun tersi de geçerlidir.
Arduino'da I2C Programlama
Bu eğitimde biri ana Arduino için diğeri bağımlı Arduino için olmak üzere iki program vardır. Her iki taraf için eksiksiz programlar bu projenin sonunda bir tanıtım videosu ile verilmiştir.
Master Arduino Programlama Açıklaması
1. Öncelikle, I2C iletişim işlevlerini kullanmak için Wire kitaplığını ve LCD işlevlerini kullanmak için LCD kitaplığını eklememiz gerekir. Ayrıca 16x2 LCD için LCD pinleri tanımlayın. LCD ile Arduino arasında arayüz oluşturma hakkında daha fazla bilgiyi burada bulabilirsiniz.
#Dahil etmek
2. Geçersiz kurulumda ()
- Baud Rate 9600'de Seri İletişimi Başlatıyoruz.
Serial.begin (9600);
- Daha sonra I2C iletişimini pin (A4, A5) üzerinden başlatıyoruz
Wire.begin (); // Pin (A4, A5) üzerinden I2C iletişimine başlar
- Daha sonra, LCD ekran modülünü 16X2 modunda başlatıyoruz ve karşılama mesajını görüntüleyip beş saniye sonra temizliyoruz.
lcd.begin (16,2); // LCD ekranı başlat lcd.setCursor (0,0); // İmleci Display lcd.print'in ilk satırına ayarlar ("Devre Özeti"); // LCD'de CIRCUIT DIGEST'i yazdırır lcd.setCursor (0,1); // İmleci Display lcd.print'in ikinci satırına ayarlar ("I2C 2 ARDUINO"); // I2C ARDUINO'yu LCD gecikmesinde (5000) yazdırır ; // 5 saniye gecikme lcd.clear (); // LCD ekranı temizler
3. Boş döngüde ()
- Öncelikle Slave'den veri almamız gerekiyor, bu yüzden slave adresi 8 ile requestFrom () kullanıyoruz ve bir bayt istiyoruz
Wire.requestFrom (8,1);
Alınan değer Wire.read () kullanılarak okunur
bayt MasterReceive = Wire.read ();
- Daha sonra, A0 pinine takılı ana arduino POT'tan analog değeri okumamız gerekir.
int potvalue = analogRead (A0);
Bu değeri bir bayt cinsinden 0'dan 127'ye çeviriyoruz.
bayt MasterSend = harita (potvalue, 0,1023,0,127);
- Daha sonra bu dönüştürülmüş değerleri göndermemiz gerekiyor, böylece iletime 8 adresli slave arduino ile başlayalım.
Wire.beginTransmission (8); Wire.write (MasterSend); Wire.endTransmission ();
- Daha sonra slave arduino'dan alınan değerleri 500 mikrosaniye gecikmeyle görüntüleriz ve bu değerleri sürekli olarak alır ve görüntüleriz.
lcd.setCursor (0,0); // Currsor'u LCD lcd.print'in birinci satırına ayarlar (">> Master <<"); // Yazdırır >> Ana << LCD lcd.setCursor (0,1); // İmleci LCD lcd.print'in ikinci satırına ayarlar ("SlaveVal:"); // SlaveVal yazdırır: LCD'de lcd.print (MasterReceive); // Slave Serial.println'den alınan MasterReceive'ı LCD'de yazdırır ("Slave'den Master Alındı"); // Seri Monitörde yazdırır Serial.println (MasterReceive); gecikme (500); lcd.clear ();
Slave Arduino Programlama Açıklaması
1. Master ile aynı, her şeyden önce I2C iletişim fonksiyonlarını kullanmak için Wire kütüphanesini ve LCD fonksiyonlarını kullanmak için LCD kütüphanesini eklememiz gerekir. Ayrıca 16x2 LCD için LCD pinleri tanımlayın.
#Dahil etmek
2. Geçersiz kurulumda ()
- Baud Rate 9600'de Seri İletişimi Başlatıyoruz.
Serial.begin (9600);
- Daha sonra slave adresi 8 olacak şekilde pin (A4, A5) üzerinden I2C iletişimini başlatıyoruz. Burada slave adresini belirtmek önemlidir.
Wire.begin (8);
Daha sonra, Slave master'dan değer aldığında ve Slave'den Master istek değeri aldığında fonksiyonu çağırmamız gerekir.
Wire.onReceive (takeEvent); Wire.onRequest (requestEvent);
- Daha sonra, LCD ekran modülünü 16X2 modunda başlatıyoruz ve karşılama mesajını görüntüleyip beş saniye sonra temizliyoruz.
lcd.begin (16,2); // LCD ekranı başlat lcd.setCursor (0,0); // İmleci Display lcd.print'in ilk satırına ayarlar ("Devre Özeti"); // LCD'de CIRCUIT DIGEST'i yazdırır lcd.setCursor (0,1); // İmleci Display lcd.print'in ikinci satırına ayarlar ("I2C 2 ARDUINO"); // I2C ARDUINO'yu LCD gecikmesinde (5000) yazdırır ; // 5 saniye gecikme lcd.clear (); // LCD ekranı temizler
3. Daha sonra, biri istek olayı ve diğeri olay alma için iki işlevimiz var
Olay talebi için
Slave'den Master talep değeri olduğunda, bu fonksiyon çalıştırılacaktır. Bu fonksiyon Slave POT'dan girdi değerini alır ve 7-bit cinsinden dönüştürür ve bu değeri master'a gönderir.
void requestEvent () { int potvalue = analogRead (A0); bayt SlaveSend = eşleme (potvalue, 0,1023,0,127); Wire.write (SlaveSend); }
Olay Almak İçin
Master, slave adresli (8) slave'e veri gönderdiğinde bu fonksiyon çalıştırılacaktır. Bu işlev, ana birimden alınan değeri okur ve bayt tipi bir değişken içinde depolar.
void ReceEvent (int howMany { SlaveReceived = Wire.read (); }
4. Boşluk döngüsünde ():
Master'dan aldığımız değeri sürekli olarak LCD ekran modülünde gösteriyoruz.
geçersiz döngü (void) { lcd.setCursor (0,0); // Currsor'u LCD lcd.print'in birinci satırına ayarlar (">> Slave <<"); // LCD lcd.setCursor (0,1) ' de >> Slave << yazdırır ; // İmleci LCD lcd.print'in ikinci satırına ayarlar ("MasterVal:"); // MasterVal'i yazdırır: LCD'de lcd.print (SlaveReceived); // Master Serial.println'den alınan LCD'de Slave Alınan değerini yazdırır ("Slave , Master'dan Alındı:"); // Seri Monitörde yazdırır Serial.println (SlaveReceived); gecikme (500); lcd.clear (); }
By bir tarafında Potansiyometre dönen, başka tarafta LCD'de değişen değerlerini görebilirsiniz:
Dolayısıyla, Arduino'da I2C iletişimi bu şekilde gerçekleşir, burada yalnızca veri gönderimini değil, aynı zamanda I2C iletişimini kullanarak verileri almayı da göstermek için iki Arduino kullandık. Yani artık herhangi bir I2C sensörünü Arduino'ya bağlayabilirsiniz.
Master ve Slave Arduino için tam kodlama aşağıda bir tanıtım videosu ile verilmiştir.