Protokol I2C yang populer memungkinkan dua atau lebih papan Arduino untuk berkomunikasi. Temukan cara menghubungkan dan mengkodekannya.

Sementara satu Arduino dapat menyelesaikan banyak tugas, beberapa proyek mungkin memerlukan penggunaan lebih dari satu papan untuk menangani fungsi yang berbeda. Jadi, untuk mengaktifkan transfer data antara dua mikrokontroler, protokol komunikasi seperti CAN, SPI, I2C, atau UART harus disiapkan.

Dalam panduan ini, kita akan membahas dasar-dasar cara kerja I2C, koneksi perangkat keras, dan implementasi perangkat lunak yang diperlukan untuk menyiapkan dua papan Arduino sebagai perangkat master dan slave I2C.

Apa itu I2C?

Inter-Integrated Circuit (I2C) adalah protokol komunikasi yang banyak digunakan dalam sistem tertanam dan mikrokontroler untuk memungkinkan transfer data antar perangkat elektronik. Tidak seperti SPI (Serial Peripheral Interface), I2C memungkinkan Anda menghubungkan lebih dari satu perangkat master ke bus dengan satu atau beberapa perangkat slave. Ini pertama kali digunakan oleh Philips dan juga dikenal sebagai protokol komunikasi Two Wire Interface (TWI).

instagram viewer

Bagaimana Cara Kerja Komunikasi I2C?

I2C menggunakan dua jalur dua arah: Serial Data (SDA) dan Serial Clock (SCL) untuk mentransfer data dan menyinkronkan komunikasi antar perangkat. Setiap perangkat yang terhubung ke bus I2C memiliki alamat unik yang mengidentifikasinya selama komunikasi. Protokol I2C memungkinkan banyak perangkat berbagi bus yang sama, dan setiap perangkat dapat bertindak sebagai master atau budak.

Komunikasi diprakarsai oleh perangkat master, dan pengalamatan perangkat slave yang salah dapat menyebabkan kesalahan dalam transfer. Lihat panduan mendalam kami tentang bagaimana komunikasi serial UART, SPI, dan I2C bekerja untuk memberi Anda beberapa konteks.

Keuntungan utama komunikasi I2C yang perlu diperhatikan adalah fleksibilitas yang ditawarkannya dalam hal manajemen daya. Perangkat yang beroperasi pada level voltase berbeda masih dapat berkomunikasi secara efektif dengan bantuan pemindah voltase. Ini berarti perangkat yang beroperasi pada 3.3V memerlukan pemindah tegangan untuk terhubung ke bus 5V I2C.

Perpustakaan Kawat

Perpustakaan Wire adalah perpustakaan Arduino bawaan yang menyediakan fungsi untuk berkomunikasi melalui I2C. Ini menggunakan dua pin — SDA dan SCL — di papan Arduino untuk komunikasi I2C.

Pin I2C pada Arduino Uno:

Pin Arduino Nano I2C:

Untuk menggunakan perpustakaan, Anda harus menyertakan Kawat.h file header di awal sketsa Arduino Anda.

#termasuk

Pustaka Wire menyediakan fungsi untuk memulai komunikasi dengan perangkat I2C, mengirim data, dan menerima data. Beberapa fungsi penting yang harus Anda ketahui antara lain:

  • Wire.begin(): digunakan untuk bergabung dengan bus I2C dan memulai komunikasi.
  • Wire.beginTransmission(): digunakan untuk menentukan alamat slave dan memulai transmisi.
  • Kawat.tulis(): digunakan untuk mengirim data ke perangkat I2C.
  • Wire.endTransmission(): digunakan untuk mengakhiri transmisi dan memeriksa kesalahan.
  • Wire.requestFrom(): digunakan untuk meminta data dari perangkat I2C.
  • Kawat.tersedia(): digunakan untuk memeriksa apakah data tersedia untuk dibaca dari perangkat I2C.
  • Kawat.baca(): digunakan untuk membaca data dari perangkat I2C.

Menggunakan Wire.beginTransmission() berfungsi untuk mengatur alamat sensor, yang dimasukkan sebagai argumen. Misalnya, jika alamat sensor adalah 0x68, Anda akan menggunakan:

Kabel.beginTransmission(0x68);

Pengaturan Perangkat Keras Arduino I2C

Untuk menghubungkan dua papan Arduino menggunakan I2C, Anda memerlukan komponen perangkat keras berikut:

  • Dua papan Arduino (master dan slave)
  • Papan tempat memotong roti
  • Kabel jumper
  • Dua resistor pull-up 4,7kΩ

Hubungkan SDA Dan SCL pin kedua papan Arduino ke papan tempat memotong roti. Hubungkan resistor pull-up antara SDA Dan SCL pin dan 5V rel listrik di papan tempat memotong roti. Terakhir, sambungkan kedua papan tempat memotong roti menggunakan kabel jumper.

Rangkaian Arduino Uno

Sirkuit Arduino Nano

Kredit Gambar: Dokumentasi Arduino I2C

Menyiapkan Papan Arduino sebagai Perangkat I2C Master dan Slave

Menggunakan Wire.requestFrom() berfungsi untuk menentukan alamat perangkat slave yang ingin kita komunikasikan. Kemudian gunakan Kawat.baca() berfungsi untuk mendapatkan data dari perangkat slave.

Kode perangkat utama:

#termasuk
ruang kosongmempersiapkan(){
Kabel.mulai(); // bergabung dengan bus i2c
Serial.mulai(9600); // mulai serial untuk output
}
ruang kosongterima Data(){
int alamat = 8;
int bytesToRead = 6;
Kabel.requestFrom(alamat, bytesToRead);
ketika (Kabel.tersedia()) {
arang data = Kabel.membaca();
Serial.mencetak(data);
}
menunda(500);
}
ruang kosonglingkaran(){
terimaData();
}

Itu Wire.onReceive() fungsi digunakan untuk menentukan apa yang harus dilakukan ketika budak menerima data dari perangkat master. Pada kode di atas, file Kawat.tersedia() fungsi memeriksa apakah data tersedia, dan Kawat.baca() fungsi membaca data yang dikirim oleh perangkat master.

Kode perangkat budak:

#termasuk
ruang kosongmempersiapkan(){
Kabel.mulai(8); // bergabung dengan bus I2C dengan alamat 8
Kabel.onReceive(menerimaAcara); // panggil acceptEvent saat data diterima
}
ruang kosonglingkaran(){
menunda(100);
}
ruang kosongterimaAcara(int byte){
Kabel.menulis("Halo "); // tanggapi dengan pesan 6 byte seperti yang diharapkan oleh master
}

Mengirim dan Menerima Data Menggunakan I2C

Dalam contoh ini, mari kita baca suhu dari sensor suhu DHT11 yang dihubungkan dengan Arduino slave dan mencetaknya di monitor serial Arduino master.

Mari kita ubah kode yang kita tulis sebelumnya untuk menyertakan pengukuran suhu yang kemudian akan kita kirim ke papan induk melalui bus I2C. Papan master kemudian dapat membaca nilai yang kami kirim, lalu menampilkannya di monitor serial.

Kode perangkat utama:

#termasuk
ruang kosongmempersiapkan(){
Kabel.mulai();
Serial.mulai(9600);
Serial.println("Tuan Diinisialisasi!");
}
ruang kosonglingkaran(){
Kabel.requestFrom(8, 1); // Meminta data suhu dari budak
jika (Kabel.tersedia()) {
byte suhu = Kabel.membaca(); // Baca data suhu dari budak
Serial.mencetak("Suhu:");
Serial.mencetak(suhu);
Serial.println("°C");
}
menunda(2000); // Tunggu selama 2 detik sebelum meminta suhu lagi
}

Kode perangkat budak:

#termasuk
#termasuk

#mendefinisikan DHTPIN 4 // Pin terhubung ke sensor DHT
#mendefinisikan DHTTYPE DHT11 // Jenis sensor DHT
DHT dht(DHTPIN, DHTTYPE);
byte suhu;

ruang kosongmempersiapkan(){
Kabel.mulai(8); // Alamat budak adalah 8
Kabel.dalam permintaan(permintaanPeristiwa);
dht.mulai();
}

ruang kosonglingkaran(){
menunda(2000); // Tunggu 2 detik hingga DHT stabil
suhu = dt.readTemperature(); // Baca suhu dari sensor DHT
}

ruang kosongrequestEvent(){
Kabel.menulis(suhu); // Kirim data suhu ke master
}

Anda dapat menyesuaikan kode ini agar sesuai dengan sensor apa pun yang mungkin Anda miliki di proyek Anda, atau bahkan menampilkan nilai sensor pada modul tampilan untuk buat sendiri termometer ruangan dan alat pengukur kelembapan.

Pengalamatan Budak Dengan I2C di Arduino

Untuk membaca nilai dari komponen yang ditambahkan ke bus I2C dalam proyek semacam itu, penting bagi Anda untuk menyertakan alamat slave yang benar saat membuat kode. Untungnya, Arduino menawarkan perpustakaan pemindai yang menyederhanakan proses identifikasi budak alamat, menghilangkan kebutuhan untuk menyaring lembar data sensor yang panjang dan online yang membingungkan dokumentasi.

Gunakan kode berikut untuk mengidentifikasi alamat perangkat slave yang ada di bus I2C.

#termasuk // Sertakan perpustakaan Wire untuk komunikasi I2C

ruang kosongmempersiapkan(){
Kabel.mulai(); // Inisialisasi komunikasi I2C
Serial.mulai(9600); // Inisialisasi komunikasi serial dengan baud rate 9600
ketika (!Serial); // Tunggu koneksi serial dibuat
Serial.println("\nPemindai I2C"); // Cetak pesan yang menunjukkan dimulainya pemindaian I2C
}

ruang kosonglingkaran(){
byte kesalahan, alamat; // Deklarasikan variabel untuk menyimpan kesalahan dan alamat perangkat
int nPerangkat; // Deklarasikan variabel untuk menyimpan jumlah perangkat yang ditemukan

Serial.println("Memindai ..."); // Cetak pesan yang menunjukkan dimulainya pemindaian I2C

nPerangkat = 0; // Setel jumlah perangkat yang ditemukan ke 0
untuk (alamat = 1; alamat < 127; alamat++) { // Ulangi semua kemungkinan alamat I2C
Kabel.beginTransmission(alamat); // Mulai transmisi ke alamat saat ini
kesalahan = Kabel.endTransmission(); // Akhiri transmisi dan simpan semua kesalahan

jika (kesalahan == 0) { // Jika tidak ada kesalahan yang ditemukan
Serial.mencetak("Perangkat I2C ditemukan di alamat 0x"); // Cetak pesan yang menunjukkan perangkat ditemukan
jika (alamat < 16) Serial.mencetak("0"); // Jika alamatnya kurang dari 16, tambahkan awalan 0 untuk tujuan pemformatan
Serial.mencetak(alamat, HEX); // Cetak alamat dalam format heksadesimal
Serial.println(" !"); // Cetak pesan yang menunjukkan perangkat ditemukan

nDevices++; // Menambah jumlah perangkat yang ditemukan
}
kalau tidakjika (kesalahan == 4) { // Jika ditemukan kesalahan
Serial.mencetak("Kesalahan tidak dikenal di alamat 0x"); // Cetak pesan yang menunjukkan kesalahan ditemukan
jika (alamat < 16) Serial.mencetak("0"); // Jika alamatnya kurang dari 16, tambahkan awalan 0 untuk tujuan pemformatan
Serial.println(alamat, HEX); // Cetak alamat dalam format heksadesimal
}
}
jika (nPerangkat == 0) { // Jika tidak ada perangkat yang ditemukan
Serial.println("Tidak ditemukan perangkat I2C\n"); // Cetak pesan yang menunjukkan tidak ada perangkat yang ditemukan
}
kalau tidak { // Jika perangkat ditemukan
Serial.println("selesai\n"); // Cetak pesan yang menunjukkan akhir pemindaian I2C
}
menunda(5000); // Tunda selama 5 detik sebelum memulai pemindaian berikutnya
}

Perluas Proyek Anda Sekarang

Menghubungkan dua papan Arduino menggunakan protokol komunikasi I2C menawarkan cara yang fleksibel dan efisien untuk mencapai tugas kompleks yang tidak dapat ditangani oleh satu papan. Dengan bantuan perpustakaan Wire, komunikasi antara dua papan menggunakan I2C menjadi mudah, memungkinkan Anda menambahkan lebih banyak komponen ke proyek Anda.