Menguasai Komunikasi I2C dengan Arduino: Tutorial Praktis
Dalam tutorial ini kita akan mempelajari cara kerja protokol komunikasi I2C dan juga kita akan membuat contoh praktis dengan Papan Arduino dan sensor yang menggunakan protokol ini. Anda dapat menonton video berikut atau membaca tutorial tertulis di bawah ini.
Ringkasan
Bus komunikasi I2C sangat populer dan digunakan luas oleh banyak perangkat elektronik karena dapat dengan mudah diimplementasikan dalam banyak desain elektronik yang membutuhkan komunikasi antara master dan beberapa perangkat slave atau bahkan beberapa perangkat master. Implementasi yang mudah datang dengan fakta bahwa hanya dua kabel yang diperlukan untuk komunikasi antara hampir 128 (112) perangkat saat menggunakan pengalamatan 7 bit dan hampir 1024 (1008) perangkat saat menggunakan pengalamatan 10 bit.
Bagaimana I2C Bekerja
Bagaimana mungkin komunikasi antara begitu banyak perangkat dengan hanya dua kabel? Nah, setiap perangkat memiliki ID yang telah ditetapkan atau alamat perangkat unik sehingga master dapat memilih dengan perangkat mana akan berkomunikasi.
Dua kabel, atau garis, disebut Serial Clock (atau SCL) dan Serial Data (atau SDA). Garis SCL adalah sinyal clock yang menyinkronkan transfer data antara perangkat pada bus I2C dan dihasilkan oleh perangkat master. Garis lainnya adalah garis SDA yang membawa data.
Kedua garis ini adalah "open-drain" yang berarti resistor pull-up perlu dipasang padanya sehingga garisnya tetap tinggi karena perangkat pada bus I2C aktif rendah. Nilai yang umum digunakan untuk resistor adalah dari 2K untuk kecepatan lebih tinggi sekitar 400 kbps, hingga 10K untuk kecepatan lebih rendah sekitar 100 kbps.
Protokol I2C
Sinyal data ditransfer dalam urutan 8 bit. Jadi setelah kondisi start khusus terjadi, urutan 8 bit pertama datang yang menunjukkan alamat slave yang dikirimkan datanya. Setelah setiap urutan 8 bit diikuti sebuah bit yang disebut Acknowledge. Setelah bit Acknowledge pertama, dalam banyak kasus datang urutan pengalamatan lagi tetapi kali ini untuk register internal perangkat slave. Segera setelah urutan pengalamatan, diikuti urutan data sebanyak hingga data selesai dikirim dan diakhiri dengan kondisi stop khusus.
Mari kita lihat lebih dekat peristiwa ini. Kondisi start terjadi ketika garis data turun rendah sementara garis clock masih tinggi. Setelah ini clock dimulai dan setiap bit data ditransfer selama setiap pulsa clock.
Urutan pengalamatan perangkat dimulai dengan bit paling signifikan (MSB) dan diakhiri dengan bit paling tidak signifikan (LSB) dan sebenarnya terdiri dari 7 bit karena bit ke-8 digunakan untuk menunjukkan apakah master akan menulis ke slave (logika rendah) atau membaca darinya (logika tinggi).
Bit berikutnya AKC/ NACK digunakan oleh perangkat slave untuk menunjukkan apakah telah berhasil menerima urutan bit sebelumnya. Sehingga pada saat ini perangkat master menyerahkan kontrol garis SDA ke perangkat slave dan jika perangkat slave berhasil menerima urutan sebelumnya, akan menarik garis SDA ke bawah ke kondisi yang disebut Acknowledge. Jika perangkat slave tidak menarik garis SDA ke bawah, kondisi disebut Not Acknowledge, dan berarti tidak berhasil menerima urutan sebelumnya yang dapat disebabkan oleh beberapa alasan. Misalnya, slave mungkin sibuk, mungkin tidak memahami data atau perintah yang diterima, tidak dapat menerima data lagi dan seterusnya. Dalam hal ini perangkat master memutuskan bagaimana akan melanjutkan.
Selanjutnya adalah pengalamatan register internal. Register internal adalah lokasi dalam memori slave yang berisi berbagai informasi atau data. Misalnya, Akselerometer ADX345 memiliki alamat perangkat unik dan alamat register internal tambahan untuk sumbu X, Y dan Z. Jadi jika kita ingin membaca data sumbu X, pertama kita perlu mengirim alamat perangkat dan kemudian alamat register internal tertentu untuk sumbu X. Alamat ini dapat ditemukan dari datasheet sensor.
Setelah pengalamatan, urutan transfer data dimulai baik dari master atau slave tergantung pada mode yang dipilih pada bit R/W. Setelah data selesai dikirim, transfer akan berakhir dengan kondisi stop yang terjadi ketika garis SDA berjalan dari rendah ke tinggi sementara garis SCL tinggi.
Contoh
Sebagai contoh saya akan menggunakan papan breakout GY-80 yang terdiri dari 5 sensor berbeda dan papan breakout GY-521 yang terdiri dari 3 sensor berbeda. Jadi kita dapat mendapatkan data dari 8 sensor berbeda dengan hanya dua kabel dengan bus I2C.
Anda dapat mendapatkan komponen ini dari salah satu situs di bawah ini:
ADXL345 3-Axis Akselerator………………………………………………………
2 in 1: MPU6050 6-Axis Giroscop & Akselerometer …………………
3 in 1: GY-80 9-Axis Medan Magnet Akselerasi Giroscop……… Amazon
Berikut adalah cara kita akan menghubungkan papan. Pin Serial Clock Papan Arduino akan terhubung ke pin Serial Clock dua papan breakout, hal yang sama berlaku untuk pin Serial Data dan kita akan menyediakan daya pada papan dengan pin Gnd dan 5V dari Papan Arduino. Perhatikan di sini kita tidak menggunakan resistor pull-up karena papan breakout sudah memilikinya.
Sekarang untuk berkomunikasi dengan chip atau sensor ini kita perlu mengetahui alamat unik mereka. Kita dapat menemukannya dari datasheet sensor. Untuk papan breakout GY-80 kita memiliki 4 alamat berikut: heksadesimal 0x53 untuk sensor Akselerometer 3 Axis, heksadesimal 0x69 untuk Giroscop 3 Axis, heksadesimal 0x1E untuk Magnetometer 3 Axis dan heksadesimal 0x77 untuk sensor Barometer dan Termometer.
Untuk papan breakout GY-521 kita hanya memiliki satu alamat yaitu heksadesimal 0x68. Kita juga dapat mendapatkan atau memeriksa alamat menggunakan sketsa I2C Scanner Arduino yang dapat ditemukan dari situs resmi Arduino. Jadi di sini jika kita mengunggah dan menjalankan sketsa tersebut, kita akan mendapatkan alamat perangkat yang terhubung pada bus I2C.
Nomor Bagian Sensor Alamat I2C
Akselerometer 3 Axis Analog Devices ADXL345 0x53 Datasheet
Giroscop 3 Axis ST Microelectronics L3G4200D 0x69 Datasheet
Setelah kita menemukan alamat perangkat kita juga perlu menemukan alamat register internal mereka untuk membaca data dari mereka. Misalnya jika kita ingin membaca data untuk sumbu X dari sensor Akselerometer 3 Axis papan breakout GY-80, kita perlu menemukan alamat register internal di mana data sumbu X disimpan. Dari datasheet sensor, kita dapat melihat bahwa data untuk sumbu X sebenarnya disimpan dalam dua register, DATAX0 dengan alamat heksadesimal 0x32 dan DATAX1 dengan alamat heksadesimal 0x33.
Kode I2C Arduino
Sekarang mari kita buat kode yang akan mendapatkan data untuk sumbu X. Jadi kita akan menggunakan Pustaka Wire Arduino yang harus disertakan dalam sketsa. Di sini pertama kita harus menentukan alamat sensor dan dua alamat register internal yang sebelumnya kita temukan. Fungsi Wire.begin() akan memulai Pustaka Wire dan juga kita perlu memulai komunikasi serial karena kita akan menggunakan Serial Monitor untuk menampilkan data dari sensor.
Di dalam loop() kita akan memulai dengan fungsi Wire.beginTransmission() yang akan memulai transmisi ke sensor tertentu, Akselerometer 3 Axis dalam kasus kita. Kemudian dengan fungsi Wire.write() kita akan meminta data tertentu dari dua register sumbu X. Fungsi Wire.endTransmission() akan mengakhiri transmisi dan mentransmisikan data dari register. Sekarang dengan fungsi Wire.requestFrom() kita akan meminta data yang ditransmisikan atau dua byte dari dua register.
Fungsi Wire.available() akan mengembalikan jumlah byte yang tersedia untuk diambil dan jika jumlah tersebut cocok dengan byte yang kita minta, dalam kasus kita 2 byte, menggunakan fungsi Wire.read() kita akan membaca byte dari dua register sumbu X. Pada akhirnya kita akan mencetak data ke serial monitor. Berikut adalah data tersebut, tetapi ingat bahwa ini adalah data mentah dan beberapa matematika perlu dilakukan untuk mendapatkan nilai yang benar dari sumbu X. Anda dapat menemukan lebih banyak detail untuk itu dalam tutorial saya selanjutnya tentang penggunaan akselerometer dengan Papan Arduino karena saya tidak ingin membebani tutorial ini karena tujuan utamanya adalah untuk menjelaskan cara kerja komunikasi I2C Arduino.
/* * How I2C Communication Protocol Works - Arduino I2C Tutorial * * by Dejan, www.HowToMechatronics.com * */ #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); }Code language: Arduino (arduino)