Cara Kerja I2C Protocol
Cara kerja I2C (Inter-Integrated Circuit) Komunikasi Serial – I2C adalah salah satu protokol komunikasi serial yang dapat melakukan komunikasi terhadap banyak peangkat I2C lainnya dengan dua kabel saja. I2C dikembangkan oleh Philips untuk berbagai chip Philips pada tahun 1982.
Pada sistem I2C, terdapat istilah Master dan Slave. Master merupakan kontroller dan Slave merupakan periperal seperti sensor, IC, aktuator dan lainnya
Setiap perangkat I2C (Master atau Slave) memiliki alamat ID misalnya:
- TMP102 i2c address 0x48 atau 0x49
- ADS1115 i2c address 0x48, 0x49, 0x4a, atau 0x4b
- ADS1015 i2c address 0x48, 0x49, 0x4a, atau 0x4B
- MCP23017 i2c address 0x20 to 0x27
- 24lC256 i2c address 0x50
- GLDC i2c SSD1306 i2c address 0x3C
- LCD I2C
- dan sebagainya
Perangkat I2C, ada yang menggunakan alamat ID 7-bit dan ada juga dengan alamat ID 10-bit.
Jika alamat slave nya adalah 7-bit, maka Master akan dapat menghandle 112 Slave.
Jika alamat slave nya adalah 10-bit, maka master dapat menghandle 1008 perangkat dalam jalur yang sama.
Jalur yang digunakan pada I2C ada dua yaitu SDA dan SCL.
- SDA (Serial Data) untuk mengirim/menerima data
- SCL (Serial Clock) untuk untuk menyingkronkan data transfer
Kedua jalur bersifat Open Drain, dibutuhkan resistor Pull-Up pada masing-masing jalur, karena perangkat berupa Aktif -LOW
Untuk nilai resistor Pull-Up nya adalah:
- 2K untuk kecepatan 400 kbps
- 10K untuk kecepatan 100 kbps
Bagaimana Protokol I2C Bekerja?
Untuk bisa memahami bagaimana Protokol I2C bekerja, maka pemahaman akan kita bagi atas dua bagian yaitu Cara Menulis ke Slave dan Cara Membaca dari Slave.
A. Protokol Menulis ke Slave Pada Bus I2C
Mari kita lihat contoh komunikasi pada kehidupan sehari-hari.
Misalnya si Budi ingin meminta informasi kepada si Andi.
Saat meminta informasi, tentu ada kalimat tertentu yang harus diucapkan Budi agar Andi memahami informasi apa yang diminta oleh Budi.
Misalnya, Budi meminta informasi ke Andi tentang Pukul berapa saat . Maka Budi mengucapkan kata “Hey Andi, pukul berapa saat ?”, maka andi akan menjawab “sekarang pukul 08.00 PM”.
Didalam protokol I2C, Budi dapat dikatakan sebagai Master dan Andi dikatakan sebagai Slave.
Andi menyadari bahwa Budi memanggilnya, karena Budi berkata “Hey Andi”. “Hey” adalah kata sapaan, namun jika tidak disertai dengan nama, maka tidak ada yang akan menjawab.
Ketika kata “Hey” ditambahkan dengan “Andi” menjadi “Hey Andi”, maka yang bernama Andi akan merespon pangggilan tersebut.
Begitu juga dengan protokol I2C menulis ke Slave.
Adapun format protokol menulis I2C secara garis besar, dapat dilihat pada gambar berikut (Sumber gambar Texas Instrument):
Semua data yang dikirimkan pada dasarnya adalah 1 bit berupa logika LOW atau HIGH.
Pada komunikasi I2C, Ini akan dibagi atas 8 bagian.
- Bit Start
- Bit Alamat + Read/Write mode
- Bit Ack
- Bit Register
- Bit Ack
- Bit Data Byte to Register
- Bit Ack
- Bit Stop
Penjelasan dari format I2C diatas, akan kita ilustrasikan dalam satu rangkaian Master terhubung ke banyak perangkat I2C.
Master kita ilustrasikan sebagai Arduino Uno dan Perangkat I2C kita ilustrasikan kedalam sensor-sensor yang berbeda.
1. Bit Start
Bit Start adalah bit yang membuat perangkat I2C (Slave) memahami akan segera dimulai komunikasi dari Master.
Jika kembali kita melihat percakapan antara Budi dan Andi, bit Start dapat disamakan dengan panggilan “Hey”.
Bit start akan terjadi ketika bit ber logika LOW. Jika dilihat pada pin SDA dan SCL, maka kondisinya adalah:
- SDA adalah HIGH to LOW
- SCL adalah HIGH.
Maka dengan kondisi , perangkat I2C slave akan mengetahui akan dimulai sebuah percakapan.
2. Bit Alamat
Ketika perangkat I2C telah mengetahui akan dimulainya sebuah percakapan, maka perangkat I2C menunggu siapa yang ingin dipanggil oleh Master (Arduino Uno) berdasarkan alamat ID dari masing-masing perangkat.
Jika kita kembai pada percakapan Budi dan Andi, bit alamat bisa disamakan dengan “Andi”.
Data yang digunakan pada blok alamat tergantung dari berapa bit alamat yang digunakan.
Jika alamat slave 7 bit, maka total bit alamat adalah 8 bit, 1 bit digunakan untuk mode baca atau tulis.
Misalnya alamat suatu peangkat adalah 0x53. Artinya jika kita konversi kedalam biner, maka alamat tersebut adalah 1010011.
Kemudian ditambah dengan mode tulis atau baca.
Jika mode Tulis maka bit adalah 0 (LOW) dan bit baca adalah 1 (HIGH).
Jadi, misalnya kita ingin menulis ke perangkat slave pada alamat 0x53, maka data addres adalah 10100110
3. Bit Ack
Ack (Acknowledge) atau Nack (Not Acknowledge) adalah bit yang dihandle oleh slave yang akan dibaca oleh master.
Jika master mengirimkan bit data alamat ID ke slave dan slave yang dituju membaca bit dengan benar, maka slave akan memberikan kondisi “Ack”, namun jika slave tidak merespon maka kondisi bit adalah Nack.
Ini digunakan oleh perangkat Slave untuk indikasi apakah data yang dikirimkan oleh master diterima dengan baik oleh Slave atau tidak.
4. Bit Register
Bit register digunakan untuk mendapatkan informasi tertentu dari Slave berdasakan alamat register yang diminta.
Misalnya, slave berupa sensor suhu, memiliki alamat ID 0x53 dan data suhu disimpan pada register 0x32.
ketika master ingin mengambil data suhu tersebut, maka setelah master menulis alamat perangkat 0x53 setelahnya dikirimkan alamat 0x32 untuk memberitahukan kepada sensor bahwa master menginginkan data dari register tersebut.
Nilai register dapat dilihat pada lembar data / datasheet dari masing-masing perangkat.
5. Bit Act
Kembali slave memberikan kondisi kepada master, apakah data yang dikirimkan dapat diterima dengan baik atau tidak.
6. Bit Data
Ini adalah data opsional jika masih ada data yang ingin diminta oleh master.
7. Bit Act
Kembali slave memberikan kondisi kepada master, apakah bit data yang dikirimkan dapat diterima dengan baik atau tidak.
8. Bit Stop
Bit stop akan mengakhiri komunikasi antar master dan slave ketika ketika bit ber logika HIGH. Jika dilihat pada pin SDA dan SCL, maka kondisinya adalah:
- SDA adalah LOW to HIGH
- SCL adalah HIGH.
B. Cara Membaca Data Dari Slave Pada Bus I2C
Untuk membaca data dari Slave, langkah awal adalah bit start, kemudian kirimkan alamat perangkat yang ingin dibaca dan mode tulis.
Setelah alamat yang dituju merespon dan membaca data mode tulis, maka slave akan menyatakan bit adalah Ack.
Maka master akan mengirimkan kembali alamat register dari suatu perangkat untuk mengambil data tertentu pada alamat register tersebut.
Setelah slave menerima alamat register yang dikirimkan oleh master, maka slave kembali menyatakan ke master bahwa bit adalah Ack. (Sumber gambar
Texas Instrument).
Si master akan kembali memanggil alamat slave tersebut dengan mode baca. Maka dengan mode baca , slave akan mengirimkan data 8 bit dari register yang diminta oleh master.
Karena kondisi slave mengirimkan data register, maka secara otomatis kondisi bit yang akan diberikan adalah Nack.
Setelah itu, jika tidak ada lagi data yang dikirimkan oleh slave ke master, maka bit akan stop.
Program Dasar I2C Menggunakan Arduino
Sekarang mari kita praktek kan komunikasi I2C menggunakan Arduino. Library default untuk I2C adalah Wire.h.
Perangkat I2C yang akan kita gunakan adalah RTC DS3231. Kita akan ambil data detik dari dalam register.
RTC DS3231 memiliki alamat perangkat 0x68. Data detik disimpan pada alamat register 0x00 yang ada didalam RTC DS3231.
Adapun alamat register dapat dilihat didatahseet, berikut adalah data alamat register dari DS3231:
Untuk perintah meminta data, kita gunakan program:
Wire.beginTransmission(alamatPerangkat);
Wire.write(alamatRegister);
Wire.endTransmission();
Untuk perintah mengambil/baca data, kita gunakan program:
Wire.requestFrom(alamatPerangkat, 1);
int data = bcdToDec(Wire.read());
Serial.println(data);
Untuk merubah data BCD to Decimal kita gunakan program:
byte bcdToDec(byte val) {
//Ubah desimal berkode biner menjadi angka desimal normal
return ( (val / 16 * 10) + (val % 16) );
}
Untuk program lengkapnya dapat dilihat sebagai berikut:
#include <Wire.h>
#define alamatPerangkat 0x68
#define alamatRegister 0x00
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
//Kirim permintaan data ke perangkat I2C (Slave)
Wire.beginTransmission(alamatPerangkat);
Wire.write(alamatRegister);
Wire.endTransmission();
//Mengambil data dari perangkat I2C (Slave)
Wire.requestFrom(alamatPerangkat, 1);
int data = bcdToDec(Wire.read());
Serial.println(data);
}
byte bcdToDec(byte val) {
//Ubah desimal berkode biner menjadi angka desimal normal
return ( (val / 16 * 10) + (val % 16) );
}
Dan hasilnya adalah:
Sekian.