I2C Haberleşme Protokolü Nedir? Arduino ile Nasıl Çalışır?
Merhaba arkadaşlar, bu makalede I2C iletişim ve haberleşme protokolü nedir? Arduino ile nasıl çalışır? Birlikte öğreneceğiz ve ayrıca Arduino Uno R3 ile i2c kullanarak pratik bir örnek yapacağız
I2C Genel Bakış
I2C iletişim veri yolu çok popülerdir ve birçok elektronik cihaz tarafından yaygın olarak kullanılır, çünkü bir ana ve çoklu bağımlı cihazlar veya hatta çoklu ana cihazlar arasında iletişim gerektiren birçok elektronik tasarımda kolayca uygulanabilir. Kolay uygulamalar, 7 bit adresleme 128 (112) cihaza kadar kullanılırken I²C ile 10 bit adresleme neredeyse 1024 (1008) cihaza kadar Kullanılabilir ve iletişim için sadece iki tel kablo yeterlidir.
I2C BUS İletişim ve Haberleşme Protokolü Nasıl Çalışır?
Bu kadar çok cihaz arasında sadece kablolarla iletişim nasıl mümkün olabilir? Her cihazın önceden ayarlanmış bir kimliği veya benzersiz bir cihaz adresi vardır, böylece master hangi cihazlarla iletişim kuracağını
seçebilir. Bu yönteme Seri Saat (veya SCL) ve Seri Veri (veya SDA) denir. SCL hattı, I2C veriyolundaki cihazlar ile ana cihaz tarafından üretilen veri aktarımı arasında senkronize olan saat sinyalidir.
Diğer verileri taşıyan SDA hattıdır. İki hat sürekli açıktır. Yani çekme dirençleri bağlı olduğu müddetçe hat sinyalleri yüksektir. Çünkü I2C veriyolundaki cihazlar aktif düşüktür. Dirençler için yaygın olarak kullanılan değerler daha yüksek hızlar için 2K ve 400 kbps'dir.
Daha düşük hızlar için 10K ve 100 kbps'dir.
I²C Protokolü
Veri sinyali 8 bitlik diziler halinde aktarılır. Böylece, özel bir başlatma koşulu meydana geldikten sonra, verinin gönderildiği slave'in adresini gösteren ilk 8 bitlik sıra gelir. Her 8 bitlik sekanstan sonra Acknowledge adlı bir bit takip eder. İlk Onay bitinden sonra çoğu durumda başka bir adresleme sırası gelir. Adresleme sekanslarından hemen sonra, veri tamamen gönderilinceye ve özel bir durdurma koşulu ile bitinceye kadar veri sekanslarını takip eder.
Başlangıç çizgisi, saat çizgisi hala yüksekken veri hattı azaldığında ortaya çıkar. Bundan sonra saat başlar ve her saat darbesi sırasında veri biti aktarılır.
İlk ve en önemli biti ile sekans yıldız (MSB) adres aygıtı, en az önemli biti (LSB) ile biter. 7 bitten oluşur çünkü 8inci bit master'ın slave'e (Logic Low) veya (Logic High) yazıp yazmayacağını belirtmek için kullanılır.
Bir sonraki bit AKC / NACK slave cihaz tarafından önceki bit dizisini başarıyla alıp almadığını belirtmek için kullanılır. Bu sırada ana cihaz SDA hattının kontrolünü slave cihaza devreder ve slave cihaz önceki diziyi başarılı bir şekilde aldıysa, SDA hattını Acknowledge adı verilen duruma çekecektir. Slave, SDA hattını aşağı çekmezse, koşul called Not Acknowledge olarak adlandırılır ve birkaç nedenden kaynaklanabilecek önceki diziyi başarıyla almadığı anlamına gelir. Örnek olarak böyle bir durumda slave meşgul olabilir, alınan verileri veya komutu anlamayabilir, daha fazla veri alamayacak gibi bir durumda ana cihaz nasıl ilerleyeceğine karar verir.
Sonra dahili kayıtların adreslenmesi; Dahili kayıtlar, slave'in hafızasında çeşitli bilgi veya veriler içeren konumlardır. Örneğin, ADX345 İvmeölçer benzersiz bir cihaz adresine ve X, Y ve Z ekseni için dahili kayıt adreslerine sahiptir. Bu nedenle, X ekseninin verilerini okumak istiyorsak, önce cihaz adresini ve ardından X ekseni için belirli dahili kayıt adresini göndermemiz gerekir. Bu adresler ADX345 Sensörün veri sayfasından bulunabilir. Adreslemeden sonra, veri aktarım dizileri, R / W bitinde seçilen moda bağlı olarak master veya slave'den başlar. Veri tamamen gönderildikten sonra aktarım, SCL hattı yüksekken, SDA hattı alçaktan yükseğe çıktığında meydana gelen bir durdurma koşulu ile sona erecektir.
Örnek olarak 5 farklı sensörden oluşan GY-80 kartını ve 3 farklı sensörden oluşan GY-521 kartını kullanacağız. Böylece I2C veri yolu kullanarak sadece iki kablo ile 8 farklı sensörden veri alabiliriz.
Bu bileşenleri aşağıdaki sitelerin herhangi birinden alabilirsiniz:
Kartları nasıl bağlayacağımız aşağıda açıklanmıştır. Arduino Kartının Seri Saat pimi, iki panosunun Seri Saat pinlerine bağlanacaktır. Aynı Seri, veri pinleri için de geçerlidir ve Arduino Kartından Gnd ve 5V pin ile panolara güç vereceğiz.
Şimdi bu çipler veya sensörler ile iletişim kurmak için benzersiz adreslerini bilmemiz gerekiyor. Bunları sensörlerin veri sayfalarından bulabiliriz.
GY-521 kart için sadece bir adresimiz var ve bu onaltılık bir 0x68'dır. Ayrıca adresleri Arduino resmi web sitesinde bulunan Arduino I2C Tarayıcı taslağını kullanarak da alabilir veya kontrol edebiliriz. Dolayısıyla, aşağıdaki kodu yükleyip çalıştırırsak, bağlı cihazların adreslerini I2C veriyolunda alırız.
Sensör Parça Numarası I2C Adresi
- 3 Eksenli İvmeölçer Analog Cihazlar ADXL345 0x53 - Datasheet
- Barometre + Termometre Bosch BMP085 0x77 - Datasheet
Cihazların adreslerini bulduktan sonra, onlardan veri okumak için dahili kayıtlarının adreslerini de bulmamız gerekir. Örneğin, X ekseni için verileri GY-80 3 Eksenli İvmeölçer sensöründen okumak istiyorsak, X ekseni verilerinin depolandığı dahili kayıt adresini bulmamız gerekir. Sensörün veri sayfasından, X ekseni için verilerin aslında iki kayıtta saklandığını görebiliriz; onaltılı adres olan DATAx0 ve 0x32, onaltılı adres olan DATAx1 ve 0x33.
Şimdi X ekseni için veri alacak kodu yapalım. Kod için taslağa dahil edilmesi gereken Arduino Tel Kütüphanesini kullanacağız. Burada önce sensör adresini ve daha önce bulduğumuz iki dahili kayıt adresini tanımlamamız gerekir.
Wire.begin () fonksiyonu Tel kütüphaneyi başlatacaktır ve ayrıca biz sensörden gelen verileri göstermek için
16x2 lcd ekran kullanacağız çünkü seri iletişim başlatmak gerekiyor.
Loop () öğesinde, 3 Eksenli İvmeölçere iletime başlayacak olan
Wire.beginTransmission () işleviyle başlayacağız. Daha sonra
Wire.write () fonksiyonu ile X ekseninin iki kaydından belirli verileri isteyeceğiz.
Wire.endTransmission () iletimi sonlandıracak ve verileri kayıtlardan iletecektir. Şimdi
Wire.requestFrom () fonksiyonu ile iletilen verileri veya iki kayıttan iki bayt talep edeceğiz.
Wire.available () işlevi, alınabilecek bayt sayısını döndürür ve bu sayı istenen baytlarımızla eşleşirse (bu proje de 2 bayt),
Wire.read () işlevini kullanarak baytları iki kayıttan okuyacağız. Sonunda verileri seri monitöre aktaracağız. Verilerin ham veri olduğunu ve X ekseninin doğru değerlerini elde etmek için biraz matematik yapılması gerektiğini unutmayın. Bunun için daha fazla ayrıntıyı Arduino ile ivmeölçer kullanmakla ilgili daha fazla ayrıntı içeren makalelerde bulabilirsiniz, çünkü bu makalede asıl amaç Arduino I2C iletişiminin nasıl çalıştığını açıklamaktır.
/*
* How I2C Communication Protocol Works - Arduino I2C Tutorial
*
* by Dejan,
*
*/
#include <Wire.h>
int ADXLAddress = 0x53; // Device address in which is also included the 8th bit for selecting the mode, read in this case.
#define X_Axis_Register_DATAX0 0x32 // Hexadecima address for the DATAX0 internal register.
#define X_Axis_Register_DATAX1 0x33 // Hexadecima address for the DATAX1 internal register.
#define Power_Register 0x2D // Power Control Register
int X0,X1,X_out;
void setup() {
Wire.begin(); // Initiate the Wire library
Serial.begin(9600);
delay(100);
// Enable measurement
Wire.beginTransmission(ADXLAddress);
Wire.write(Power_Register);
// Bit D3 High for measuring enable (0000 1000)
Wire.write(8);
Wire.endTransmission();
}
void loop() {
Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor
//Ask the particular registers for data
Wire.write(X_Axis_Register_DATAX0);
Wire.write(X_Axis_Register_DATAX1);
Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers
Wire.requestFrom(ADXLAddress,2); // Request the transmitted two bytes from the two registers
if(Wire.available()<=2) { //
X0 = Wire.read(); // Reads the data from the register
X1 = Wire.read();
}
Serial.print("X0= ");
Serial.print(X0);
Serial.print(" X1= ");
Serial.println(X1);
}