Apa Itu I2C? SDA, SCL, Resistor Pull-up, dan Scanner Arduino
Apa itu I2C dan bagaimana cara kerjanya? SDA dan SCL, alamat 7-bit, perhitungan resistor pull-up, sketch I2C scanner, bentrok alamat, serta pin Uno, ESP32, dan Pico.
I2C (Inter-Integrated Circuit) adalah protokol komunikasi serial yang memungkinkan mikrokontroler berbicara dengan puluhan sensor, layar, dan modul hanya lewat dua kabel sinyal (SDA dan SCL). Cara bacanya “I-squared-C”, dan beberapa datasheet menyebutnya IIC atau TWI (Two Wire Interface). LCD I2C, layar OLED, akselerometer MPU6050, sensor tekanan BMP280, dan modul jam (RTC) DS1307 yang kamu pakai di proyek Arduino semuanya berbicara dengan protokol ini; kamu bisa menghubungkan semuanya secara paralel ke dua kabel yang sama dan menjangkau masing-masing lewat alamatnya sendiri.
Di panduan ini kamu akan mempelajari cara kerja I2C secara elektrik, arti alamat, kenapa resistor pull-up wajib ada, dan cara menghitung nilainya. Setelah itu, langkah demi langkah, kamu akan melihat tabel pin untuk Arduino Uno, ESP32, dan Raspberry Pi Pico, sketch I2C scanner yang menemukan semua perangkat di bus, contoh membaca register tanpa library, dan solusi untuk masalah umum seperti bentrok alamat.

Apa itu I2C dan bagaimana cara kerjanya?
I2C dikembangkan oleh Philips (sekarang NXP) pada 1982 agar chip-chip di papan sirkuit yang sama bisa berkomunikasi dengan sedikit kabel. Ada dua peran di bus: controller (dulu disebut master), yang memulai setiap transfer dan menghasilkan clock, dan target (dulu slave), yang menanggapinya. Di proyek Arduino, controller hampir selalu Arduino, ESP32, atau Pico, sedangkan sensor dan layar adalah target.
- SDA (Serial Data): Jalur yang membawa data ke dua arah. Controller mengirim alamat dan perintah, dan sensor mengirim balik bacaannya di jalur yang sama.
- SCL (Serial Clock): Jalur clock. Satu bit di SDA dibaca di setiap pulsa clock, dan controller yang menghasilkan clock-nya.
- GND (ground bersama): Referensi untuk sinyal. Modul dengan catu daya terpisah pun harus berbagi GND yang sama.
Jalurnya bersifat open-drain: tidak ada perangkat yang pernah mendorong jalur ke tinggi, perangkat hanya bisa menariknya ke rendah. Yang menahan jalur di nilai 1 adalah resistor pull-up yang menghubungkan SDA dan SCL ke tegangan catu. Karena itu tidak terjadi korsleting walaupun dua perangkat mencoba bicara bersamaan; kalau ada perangkat yang menarik jalur ke rendah, semua melihat 0. Sebuah pesan I2C berjalan seperti ini:
- START: Ketika SCL tinggi, controller menarik SDA dari 1 ke 0, dan setiap perangkat di bus mulai mendengarkan.
- Alamat dan bit arah: Alamat 7-bit dikirim, diikuti bit baca (1) atau tulis (0).
- ACK: Perangkat pemilik alamat menarik SDA ke rendah selama pulsa clock ke-9 untuk mengatakan “aku di sini”. Kalau tidak ada yang menjawab, itu disebut NACK.
- Byte data: Setiap byte dikirim sebagai 8 bit dan penerima menjawab masing-masing dengan ACK. Di kebanyakan sensor, byte pertama adalah nomor register yang akan dibaca atau ditulis.
- STOP: Ketika SCL tinggi, SDA naik dari 0 ke 1 dan bus kembali bebas. Untuk pembacaan, dipakai repeated START, bukan STOP, agar arahnya bisa berubah tanpa melepas bus.
Membandingkan I2C dengan dua protokol umum lain di dunia Arduino memperjelas kapan sebaiknya memilihnya:
| Fitur | I2C | SPI | UART (Serial) |
|---|---|---|---|
| Kabel sinyal | 2 (SDA, SCL) | 3 bersama (MOSI, MISO, SCK) + satu CS per perangkat | 2 (TX, RX) |
| Jumlah perangkat | Lebih dari 100 alamat di satu bus | Sebanyak pin CS yang tersedia | Biasanya 2 perangkat |
| Kecepatan umum | 100 kHz, 400 kHz, 1 MHz | 10 MHz ke atas | 9600 – 115200 baud |
| Pemilihan perangkat | Lewat alamat | Lewat pin CS | Tidak ada, titik ke titik |
| Pemakaian umum | Sensor, modul jam, layar kecil, EEPROM | Kartu SD, layar TFT, RFID | GPS, Bluetooth, koneksi ke komputer |
Kecepatan I2C dan batas teknisnya
| Mode | Kecepatan maksimum | Waktu naik maksimum | Dipakai di mana? |
|---|---|---|---|
| Standard mode (Sm) | 100 kHz | 1000 ns | Bawaan, kabel panjang |
| Fast mode (Fm) | 400 kHz | 300 ns | OLED, MPU6050, BMP280 |
| Fast mode plus (Fm+) | 1 MHz | 120 ns | Pico dan beberapa sensor yang lebih baru |
| High-speed mode (Hs) | 3,4 MHz | 80 ns (400 pF), butuh driver khusus | Jarang di proyek hobi |
Library Wire di Arduino secara bawaan mulai di 100 kHz; kebanyakan sensor juga mendukung 400 kHz, dan kamu bisa beralih ke sana dengan Wire.setClock(400000). Kecepatan yang lebih tinggi membuat layar diperbarui lebih mulus, tetapi juga membuat bus lebih sensitif terhadap panjang kabel dan nilai pull-up. Menurut standarnya, kapasitansi total bus (kabel plus pin perangkat) tidak boleh melebihi 400 pF. Kabel jumper dan kabel pita biasa menambah 50–100 pF per meter dan setiap pin perangkat menambah sampai 10 pF, karena itu I2C dirancang untuk dipakai di satu board atau dengan kabel sepanjang beberapa puluh sentimeter. Lebih dari 1 meter, kamu perlu menurunkan kecepatan, memakai pull-up yang lebih kuat, atau menambahkan bus extender seperti P82B715.
Alamat I2C: 7-bit, 8-bit, dan alamat yang dicadangkan
Setiap perangkat di bus punya alamat 7-bit, yang secara teori memberi 128 alamat. Karena rentang 0x00–0x07 dan 0x78–0x7F dicadangkan untuk keperluan khusus, alamat yang bisa dipakai adalah 112 alamat dari 0x08 sampai 0x77. Alamatnya biasanya ditentukan oleh pembuat chip, tetapi di banyak modul kamu bisa mengubah bit terakhirnya dengan jumper solder atau pin bernama A0, A1, A2, atau AD0.
Inilah bagian yang membingungkan: beberapa datasheet dan label di bagian belakang modul menuliskan alamatnya sebagai 8 bit, termasuk bit arahnya. Misalnya, di bagian belakang board OLED tertulis “0x78”, tetapi alamat di kode adalah 0x3C; kalau modul LCD bertuliskan 0x4E, alamat di kode adalah 0x27. Aturannya sederhana: bagi nilai 8-bit dengan 2 (geser ke kanan satu bit) dan kamu mendapat alamat 7-bit. Library Arduino, ESP32, dan MicroPython semuanya mengharapkan alamat 7-bit.
| Modul | Chip | Alamat bawaan | Bisa diubah? |
|---|---|---|---|
| Modul LCD I2C (16x2, 20x4) | PCF8574 / PCF8574A | 0x27 / 0x3F | Dengan jumper A0–A2: 0x20–0x27 atau 0x38–0x3F |
| OLED 0,96 inci | SSD1306 | 0x3C | 0x3D lewat resistor di bagian belakang |
| Akselerometer dan giroskop | MPU6050 | 0x68 | 0x69 ketika AD0 = 1 |
| Jam waktu nyata (RTC) | DS1307 / DS3231 | 0x68 | Tidak |
| Tekanan dan suhu | BMP280 / BME280 | 0x76 atau 0x77 | Tergantung pin SDO |
| Intensitas cahaya | BH1750 | 0x23 | 0x5C ketika ADDR = 1 |
| ADC 16-bit | ADS1115 | 0x48 | 0x48–0x4B lewat pin ADDR |
| Driver servo dan PWM 16 kanal | PCA9685 | 0x40 | Puluhan alamat mulai 0x40 lewat jumper A0–A5 |
| Memori EEPROM | AT24C32 / AT24C256 | 0x50 | 0x50–0x57 lewat A0–A2 |
| Multiplexer I2C | TCA9548A | 0x70 | 0x70–0x77 lewat A0–A2 |
Resistor pull-up: kenapa dibutuhkan dan cara memilih nilainya
Karena perangkat di bus I2C hanya bisa menarik jalur ke rendah, resistor pull-up yang menyediakan level tinggi. Kalau resistornya terlalu besar, kapasitansi bus memperlambat transisi dari 0 ke 1, tepi sinyal jadi membulat, dan bit salah dibaca di kecepatan tinggi. Kalau terlalu kecil, arus yang harus ditarik perangkat ketika menarik jalur ke rendah jadi naik; standarnya hanya mewajibkan perangkat mampu menarik minimal 3 mA di 0,4 V, jadi pull-up harus menjaga arusnya di bawah nilai itu.
Rumus berikut memberikan kedua batasnya: hambatan minimum R(min) = (VCC − 0,4 V) / 3 mA, dan maksimum R(max) = t(rise) / (0,8473 × C(bus)). Untuk 5 V, R(min) = 4,6 V / 0,003 A ≈ 1,53 kΩ, dan untuk 3,3 V ≈ 0,97 kΩ. Pada bus pendek dengan kapasitansi 100 pF, R(max) ≈ 11,8 kΩ di 100 kHz dan ≈ 3,5 kΩ di 400 kHz. Karena itu dalam praktiknya, 4,7 kΩ untuk 100 kHz dan 2,2 kΩ untuk 400 kHz serta bus yang ramai adalah nilai yang paling umum. Kamu bisa memakai alat Kode Warna Resistor untuk membaca gelang resistor dan alat konstanta waktu RC untuk melihat jeda yang ditimbulkan hambatan dan kapasitansi.
| Situasi | Pull-up yang disarankan | Catatan |
|---|---|---|
| Satu modul, kabel pendek, 100 kHz | 4,7 kΩ – 10 kΩ | Kebanyakan modul sudah punya |
| Beberapa modul, 400 kHz | 2,2 kΩ – 4,7 kΩ | Resistor di modul-modul itu jadi terparalel |
| Kabel lebih dari 50 cm | 2,2 kΩ dan 100 kHz | Jangan pilin SDA dengan SCL; pilin masing-masing dengan GND |
| Bus 3,3 V (ESP32, Pico) | 2,2 kΩ – 4,7 kΩ | Hubungkan resistor ke 3,3 V, bukan 5 V |
Di Arduino Uno, memanggil Wire.begin() juga menyalakan resistor pull-up internal 20–50 kΩ di ATmega328P. Dengan satu modul dan kabel 10–20 cm, resistor ini sering kali cukup, tetapi tidak bisa diandalkan; resistor eksternal selalu lebih baik. Kalau kamu memakai board sensor polos tanpa pull-up, jangan lupa menambahkan resistor 4,7 kΩ dari SDA dan SCL ke VCC.
Pin I2C: Arduino Uno, Mega, ESP32, ESP8266, dan Pico
| Board | SDA | SCL | Catatan |
|---|---|---|---|
| Arduino Uno / Nano | A4 | A5 | Di Uno R3, pin SDA dan SCL di samping AREF adalah bus yang sama dengan A4/A5 |
| Arduino Mega 2560 | 20 | 21 | Di Mega, A4 dan A5 bukan I2C |
| Arduino Leonardo / Micro | D2 | D3 | Ini pin digital |
| ESP32 (DevKit) | GPIO 21 | GPIO 22 | Pin lain bisa dipilih dengan Wire.begin(SDA, SCL); bus kedua adalah Wire1 |
| ESP8266 NodeMCU | D2 (GPIO 4) | D1 (GPIO 5) | I2C software, pinnya bisa diubah |
| Raspberry Pi Pico | GP4 (I2C0) | GP5 (I2C0) | I2C0 dan I2C1 tersedia di banyak pasangan pin |
Langkah demi langkah: mencari alamat dengan sketch I2C scanner
Ketika mendapat modul baru, tugas pertama adalah mencari tahu alamat perangkat di bus. I2C scanner mengirim pesan kosong ke setiap alamat dari 0x08 sampai 0x77 dan mencantumkan alamat yang menjawab dengan ACK. Dengan begitu kamu tahu bahwa modulnya terpasang dengan benar sekaligus alamat mana yang perlu ditulis di kode.
- Hubungkan GND modul ke GND Arduino dan VCC-nya ke 5V (ke 3.3V untuk modul yang hanya mendukung 3,3 V).
- Hubungkan SDA ke A4 dan SCL ke A5. Kalau modulnya lebih dari satu, gabungkan semua pin SDA dan SCL di breadboard.
- Upload sketch di bawah dan buka Serial Monitor di 115200 baud.
- Catat alamat yang muncul. Kalau tidak ada yang muncul, periksa pengkabelan, GND bersama, dan resistor pull-up.
- Cabut dan sambungkan lagi modul satu per satu untuk memastikan alamat mana milik perangkat mana; scanner memindai ulang setiap 5 detik.
1#include <Wire.h>
2
3void printHex(byte addr) {
4 Serial.print(F("0x"));
5 if (addr < 16) Serial.print('0'); // tek haneliye sıfır ekle / pad single digit
6 Serial.print(addr, HEX);
7}
8
9void setup() {
10 Serial.begin(115200);
11 Wire.begin(); // Uno: A4 = SDA, A5 = SCL
12#if defined(ARDUINO_ARCH_AVR)
13 Wire.setWireTimeout(3000, true); // AVR (Uno, Nano, Mega): hat kilitlenirse 3 ms sonra kurtar / recover a stuck bus after 3 ms
14#endif
15 Serial.println(F("I2C tarayici / I2C scanner"));
16}
17
18void loop() {
19 byte found = 0;
20 for (byte addr = 0x08; addr <= 0x77; addr++) { // geçerli 7 bit adresler / valid 7-bit addresses
21 Wire.beginTransmission(addr);
22 byte err = Wire.endTransmission(); // 0 = cihaz ACK verdi / device acknowledged
23 if (err == 0) {
24 Serial.print(F("Bulundu / found: "));
25 printHex(addr);
26 Serial.println();
27 found++;
28 } else if (err == 4 || err == 5) {
29 Serial.print(F("Hat hatasi / bus error at "));
30 printHex(addr);
31 Serial.println();
32 }
33 }
34 if (found == 0) {
35 Serial.println(F("Cihaz yok: kablolari ve pull-up'lari kontrol et / no devices: check wiring and pull-ups"));
36 } else {
37 Serial.print(found);
38 Serial.println(F(" cihaz bulundu / device(s) found"));
39 }
40 Serial.println();
41 delay(5000); // 5 sn sonra yeniden tara / rescan after 5 s
42}| Hasil endTransmission() | Arti | Yang dilakukan |
|---|---|---|
| 0 | Perangkat mengakui alamatnya (ACK) | Pakai alamat ini di kodemu |
| 1 | Data terlalu panjang untuk buffer | Tidak pernah muncul di scanner; jangan tulis lebih dari 32 byte sekaligus di Uno |
| 2 | NACK pada alamat | Tidak ada perangkat di alamat itu, normal ketika memindai |
| 3 | NACK pada data | Perangkat menolak perintahnya; periksa nomor register |
| 4 | Error bus lainnya | Korsleting, pull-up tidak ada, atau gangguan |
| 5 | Timeout | Bus macet; periksa pengkabelan dan catu daya |
Baris setWireTimeout di sketch ini penting: ketika SDA atau SCL korsleting, atau sebuah perangkat macet sambil menahan jalur di rendah, library Wire di Uno dengan pengaturan bawaan bisa menunggu selamanya dan membekukan programmu. Dengan timeout aktif, library menyerah setelah 3 ms, mereset hardware I2C, dan scanner melaporkan masalahnya dengan kode error. Baris ini dibungkus #if agar hanya dikompilasi di board AVR (Uno, Nano, Mega); library Wire di ESP32 dan ESP8266 sudah punya perlindungan timeout sendiri, jadi sketch yang sama bisa dikompilasi dan dijalankan tanpa perubahan di ketiga platform.
I2C tanpa library: membaca dan menulis register
Library memang memudahkan, tetapi di baliknya semuanya melakukan hal yang sama: mengirim nomor register ke perangkat, lalu membaca byte dari atau menulis byte ke register itu. Melakukannya sendiri sekali saja membuatmu bisa membaca datasheet sensor baru dan memakainya bahkan tanpa library. Contoh di bawah membangunkan sensor MPU6050 dari mode sleep, membaca register identitasnya (WHO_AM_I), lalu menghitung suhu dan percepatan sumbu Z dari nilai mentahnya.

1#include <Wire.h>
2
3const byte MPU_ADDR = 0x68; // AD0 GND'de; AD0 = 3.3V ise 0x69 / AD0 low; 0x69 if AD0 high
4
5void writeReg(byte reg, byte value) {
6 Wire.beginTransmission(MPU_ADDR);
7 Wire.write(reg); // önce yazmaç adresi / register address first
8 Wire.write(value); // sonra veri / then the data
9 Wire.endTransmission(); // STOP gönder / send STOP
10}
11
12int16_t readWord(byte reg) {
13 Wire.beginTransmission(MPU_ADDR);
14 Wire.write(reg);
15 Wire.endTransmission(false); // STOP yok, tekrarlı START / no STOP, repeated START
16 Wire.requestFrom(MPU_ADDR, (byte)2); // 2 bayt iste / request 2 bytes
17 uint8_t hi = Wire.read();
18 uint8_t lo = Wire.read();
19 return (int16_t)(((uint16_t)hi << 8) | lo);
20}
21
22void setup() {
23 Serial.begin(115200);
24 Wire.begin();
25 Wire.setClock(400000); // hızlı mod 400 kHz / fast mode 400 kHz
26 writeReg(0x6B, 0x00); // PWR_MGMT_1: uykudan uyandır / wake up from sleep
27 Wire.beginTransmission(MPU_ADDR);
28 Wire.write(0x75); // WHO_AM_I yazmacı / WHO_AM_I register
29 Wire.endTransmission(false);
30 Wire.requestFrom(MPU_ADDR, (byte)1);
31 Serial.print(F("WHO_AM_I = 0x"));
32 Serial.println(Wire.read(), HEX); // 68 beklenir / expect 68
33}
34
35void loop() {
36 int16_t raw = readWord(0x41); // TEMP_OUT_H ve TEMP_OUT_L / TEMP_OUT_H and TEMP_OUT_L
37 float tempC = raw / 340.0 + 36.53; // veri sayfasındaki formül / datasheet formula
38 int16_t az = readWord(0x3F); // Z ekseni ivmesi / Z-axis acceleration
39 Serial.print(F("Sicaklik / temp: "));
40 Serial.print(tempC, 1);
41 Serial.print(F(" C AccZ: "));
42 Serial.println(az / 16384.0, 2); // +-2g aralığında 16384 = 1 g / 16384 = 1 g at +-2g
43 delay(500);
44}Perhatikan baris endTransmission(false) di fungsi pembacaan: baris ini mengubah arah dengan repeated START, bukan STOP, sehingga tidak ada perangkat lain yang bisa menyela dan sensor tidak lupa register mana yang diminta. Kalau WHO_AM_I terbaca 0x68, komunikasinya sempurna. Di modul klon murah, nilainya bisa 0x70 atau angka lain; artinya chip-nya adalah model yang kompatibel tetapi berbeda, seperti MPU6500, dan itulah alasan beberapa library siap pakai melaporkan “sensor not found”. Rumus suhunya (nilai mentah / 340 + 36,53) diambil langsung dari datasheet MPU6050; untuk percepatan di rentang ±2 g, nilai mentah 16384 sama dengan 1 g, jadi sensor yang tergeletak rata di meja menunjukkan sekitar 1,00 di sumbu Z.
Beberapa perangkat di satu bus dan bentrok alamat
Keunggulan terbesar I2C adalah kamu bisa menghubungkan perangkat secara paralel ke dua kabel yang sama selama alamatnya berbeda. Misalnya, LCD (0x27), OLED (0x3C), BMP280 (0x76), dan modul jam DS3231 (0x68) bisa dengan tenang berbagi pin A4 dan A5 yang sama; setiap library berbicara dengan alamatnya sendiri, sementara perangkat lain diam mendengarkan. Masalah muncul ketika dua perangkat punya alamat yang sama: keduanya mengirim ACK, datanya bertabrakan, dan biasanya tidak ada yang berfungsi. Inilah cara mengatasinya:
- Ubah pin alamat: Kalau pin AD0 MPU6050 kamu hubungkan ke 3,3 V, alamatnya menjadi 0x69 dan bentrok dengan DS3231 (0x68) hilang.
- Pakai jumper solder: Jumper A0–A2 di modul LCD menawarkan 8 alamat, dan pin ADDR di ADS1115 menawarkan 4.
- Buka bus I2C kedua: Pindahkan perangkat yang bentrok ke pin terpisah dengan Wire1 di ESP32 atau I2C1 di Pico.
- Tambahkan multiplexer I2C: TCA9548A membuka delapan sub-bus terpisah dari satu alamat (0x70); kamu bahkan bisa menghubungkan delapan OLED dengan alamat yang sama.
- Perangkat dengan alamat tetap: Beberapa chip, seperti DS1307 atau HTU21D, punya alamat yang sama sekali tidak bisa diubah; untuk chip ini, hanya bus terpisah atau multiplexer yang bisa membantu.
I2C di ESP32: pin bebas dan dua bus terpisah
Di ESP32, hardware I2C bisa diarahkan ke pin secara fleksibel. Pin bawaannya GPIO 21 (SDA) dan GPIO 22 (SCL), tetapi dengan Wire.begin(SDA, SCL) kamu bisa memilih hampir dua GPIO mana pun yang kamu mau. ESP32 klasik dan ESP32-S3 punya dua controller I2C, jadi kamu bisa menjalankan dua sensor dengan alamat yang sama di dua bus terpisah; ESP32-C3 hanya punya satu controller. GPIO 34–39 hanya untuk input dan tidak bisa dipakai untuk I2C. Untuk peta pin lengkap board-nya, cek alat Pinout, dan untuk pengenalan umum baca Apa Itu ESP32?.
1#include <Wire.h>
2
3// Klasik ESP32'de iki I2C denetleyicisi vardır: Wire ve Wire1 / the classic ESP32 has two I2C controllers: Wire and Wire1
4
5void scan(TwoWire &bus, const char *name) {
6 Serial.printf("%s:\n", name);
7 for (uint8_t addr = 0x08; addr <= 0x77; addr++) {
8 bus.beginTransmission(addr);
9 if (bus.endTransmission() == 0) {
10 Serial.printf(" bulundu / found 0x%02X\n", addr);
11 }
12 }
13}
14
15void setup() {
16 Serial.begin(115200);
17 Wire.begin(21, 22); // SDA, SCL: varsayılan pinler / default pins
18 Wire1.begin(32, 33, 400000); // SDA, SCL, hız: başka iki GPIO / SDA, SCL, speed: any two other GPIOs
19 scan(Wire, "Wire (SDA 21, SCL 22)");
20 scan(Wire1, "Wire1 (SDA 32, SCL 33)");
21}
22
23void loop() {
24}I2C di Raspberry Pi Pico (MicroPython)
Chip RP2040 di Pico punya dua controller bernama I2C0 dan I2C1, dan masing-masing bisa diarahkan ke beberapa pasangan pin yang berbeda. Untuk I2C0 kamu bisa memakai GP0/GP1, GP4/GP5, GP8/GP9, GP12/GP13, GP16/GP17, dan GP20/GP21; untuk I2C1, GP2/GP3, GP6/GP7, GP10/GP11, GP14/GP15, GP18/GP19, dan GP26/GP27. Di setiap pasangan, pin bernomor genap adalah SDA dan pin bernomor ganjil adalah SCL. Di MicroPython, scanner-nya cukup satu baris: i2c.scan() mengembalikan daftar alamat yang menjawab dengan ACK. Karena Pico bekerja di 3,3 V, memberi daya modul dari pin 3V3(OUT) adalah pilihan paling aman; walaupun RP2040 juga mendukung Fast mode plus 1 MHz, tetap di 400 kHz di breadboard memberi lebih sedikit kejutan. Untuk langkah pertamamu dengan Pico, baca Apa Itu Raspberry Pi Pico?.
1from machine import Pin, I2C
2
3i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000) # I2C0: GP4 = SDA, GP5 = SCL
4devices = i2c.scan() # ACK veren adresler / addresses that ACK
5
6if devices:
7 for addr in devices:
8 print("Bulundu / found:", hex(addr))
9else:
10 print("Cihaz yok / no devices")
11
12# MPU6050 varsa WHO_AM_I yazmacını oku / if an MPU6050 is present, read WHO_AM_I
13if 0x68 in devices:
14 i2c.writeto_mem(0x68, 0x6B, b"\x00") # uykudan uyandır / wake up
15 who = i2c.readfrom_mem(0x68, 0x75, 1)[0]
16 print("WHO_AM_I:", hex(who)) # 0x68 beklenir / expect 0x68Ide proyek dengan I2C
- Stasiun cuaca mini: Ukur tekanan dan suhu dengan BMP280 lalu tampilkan di layar OLED; kedua modul berbagi dua kabel yang sama.
- Jam digital: Baca waktu dari modul jam (RTC) DS3231 dan cetak di layar LCD I2C.
- Indikator kemiringan: Hitung sudut dengan MPU6050 dan gambar hasilnya di OLED seperti waterpass.
- Node sensor Wi-Fi: Pantau sensor yang terhubung ke pin D1 dan D2 ESP8266 NodeMCU dari ponselmu.
- Lengan robot 16 servo: Kendalikan 16 servo hanya dari dua pin dengan driver PCA9685.
- Pencatat data: Tulis satu bacaan ke EEPROM AT24C256 setiap menit agar datanya tetap aman ketika listrik padam.
Kesalahan umum dan cara mengatasinya
| Gejala | Kemungkinan penyebab | Solusi |
|---|---|---|
| Scanner tidak menemukan perangkat | SDA dan SCL tertukar, tidak ada GND bersama, atau modul tidak mendapat daya | Periksa pengkabelan; di Uno, A4 = SDA dan A5 = SCL |
| Scanner macet atau melaporkan error di setiap alamat | Bus korsleting atau pull-up tidak ada | Tambahkan setWireTimeout; ukur tegangan catu di SDA dan SCL yang sedang diam |
| Sketch bisa dikompilasi tetapi layar tetap kosong | Alamat di kode salah (0x27, padahal 0x3F) | Pakai alamat yang ditemukan scanner |
| Di belakang board tertulis 0x78 dan kodenya tidak jalan | Yang dipakai alamat 8-bit | Bagi 2: 0x78 → 0x3C |
| Dua sensor tidak mau bekerja bersama | Bentrok alamat | Ubah pin alamat, pakai bus kedua atau TCA9548A |
| Macet acak, gangguan ketika motor berjalan | Kabel panjang, gangguan listrik, atau catu daya lemah | Perpendek kabel, turunkan ke 100 kHz, tambahkan kapasitor 100 nF di modul |
| Pin ESP32 atau Pico rusak | Pull-up yang tersambung ke 5 V dihubungkan ke pin 3,3 V | Beri daya modul dari 3,3 V atau pakai level shifter |
I2C adalah cara paling praktis untuk menambahkan layar, modul jam, sensor, dan memori ke proyekmu hanya dengan dua kabel; begitu kamu paham alamat, resistor pull-up, dan sketch scanner, sebagian besar masalah bisa kamu selesaikan dalam beberapa menit. Di aplikasi BlueGrays ada proyek yang memakai I2C, seperti layar LCD I2C, game Pong di layar OLED, jam digital dengan DS1307, dan layar cuaca ESP32, masing-masing dengan skema rangkaian dan kode langkah demi langkah.
Pertanyaan umum
Apa perbedaan I2C dan SPI?
I2C memakai pengalamatan untuk menaruh lebih dari seratus perangkat di dua kabel yang sama, tetapi biasanya terbatas di 100–400 kHz. SPI butuh tiga kabel bersama ditambah pin chip-select (CS) terpisah untuk setiap perangkat; sebagai gantinya, SPI mencapai 10 MHz atau lebih. I2C lebih dipilih untuk sensor dan layar kecil, SPI untuk kartu SD dan layar TFT berwarna.
Berapa banyak perangkat yang bisa dihubungkan ke bus I2C?
Pengalamatan 7-bit memberi 112 alamat yang bisa dipakai. Dalam praktiknya, batasnya lebih ditentukan oleh kapasitansi bus (maksimum 400 pF) dan resistor pull-up yang terparalel daripada jumlah alamat; 5–10 perangkat bekerja dengan baik di breadboard. Untuk lebih banyak, pakai multiplexer TCA9548A atau bus I2C kedua.
Berapa nilai resistor pull-up I2C yang sebaiknya dipakai?
4,7 kΩ untuk 100 kHz dan kabel pendek, serta 2,2 kΩ untuk 400 kHz atau bus dengan banyak perangkat, adalah nilai yang paling umum. Jangan turun di bawah 1,5 kΩ di bus 5 V atau 1 kΩ di bus 3,3 V. Ingat juga bahwa resistor di modul-modulmu menjadi terparalel.
Pin mana yang menjadi I2C di Arduino Uno?
Di Arduino Uno dan Nano, SDA adalah pin A4 dan SCL adalah pin A5. Uno R3 punya dua pin lagi berlabel SDA dan SCL di samping AREF, tetapi keduanya tersambung ke A4 dan A5 di board, bukan bus terpisah. Di Mega, pin I2C-nya adalah 20 (SDA) dan 21 (SCL).
Berapa panjang maksimum kabel I2C?
I2C dirancang untuk jarak pendek di papan sirkuit; di 100 kHz dan dengan pull-up yang sesuai, biasanya bekerja sampai sekitar 1 meter. Untuk jarak lebih jauh, kamu perlu menurunkan kecepatan, memakai kabel twisted pair, atau beralih ke driver bus seperti P82B715. Untuk beberapa meter, RS-485 atau koneksi nirkabel adalah pilihan yang lebih baik.
Apa yang harus dilakukan kalau I2C scanner tidak menemukan perangkatku?
Pertama, pastikan SDA dan SCL ada di pin yang benar, GND bersama tersambung, dan modul mendapat daya. Setelah itu, pastikan pull-up-nya dengan mengukur tegangan catu di SDA dan SCL yang sedang diam. Kalau masih tidak ditemukan, coba modulnya sendirian dengan kabel pendek di 100 kHz, dan di ESP32 pastikan kamu memberikan pin yang benar ke Wire.begin.
Proyek untuk dibuat setelah membaca ini
Lihat semua proyek
Menggunakan Layar LCD dengan I2C
Beri Arduino-mu layar sendiri dan buat ia menulis pesan pertamanya. Layar LCD dua baris tersambung hanya dengan beberapa kabel; sapaan muncul di baris atas, lalu pesan kedua di baris bawah, layar dibe

Layar LCD I2C ESP32 (16x2)
Di proyek ini, kita menampilkan teks dengan menyambungkan layar LCD karakter 16x2 ke ESP32 lewat protokol I2C. Berkat I2C, kita bisa mengendalikan layar hanya dengan dua pin data (SDA dan SCL), sehingga tidak perlu memboroskan 6+ pin seperti pada sambungan paralel klasik. Kode mencetak pesan tetap di baris pertama dan penghitung yang naik setiap detik di baris kedua. Selain itu, kita menjalankan pemindai I2C di awal untuk mencetak alamat layar ke Serial Monitor (biasanya 0x27).

Jam Digital dengan ESP32 dan RTC DS1307 (I2C + LCD)
Di proyek ini, kita menampilkan waktu dan tanggal di layar LCD I2C 16x2 memakai modul jam real-time (RTC) DS1307. DS1307 adalah RTC berbaterai cadangan yang tetap menjaga waktu meskipun ESP32 dimatikan. Kedua modul berbagi bus I2C yang sama (SDA/SCL), sehingga kita belajar mengendalikan beberapa perangkat hanya dengan dua kabel sinyal. Lewat proyek ini kamu mendapat pengetahuan praktis tentang protokol komunikasi I2C, cara kerja modul RTC, dan tampilan data dinamis di LCD.

Kalkulator I2C Arduino
Proyek kalkulator berbasis Arduino yang melakukan penjumlahan, pengurangan, perkalian, dan pembagian memakai keypad membran 4x4 dan layar LCD I2C 16x2. Berkat I2C, sambungan layar hanya butuh 2 kabel, sehingga kabel tidak semrawut dan lebih banyak pin tetap bebas dipakai. Kalkulator ini juga mendukung input bilangan desimal dan bilangan negatif.

Game Bola Pemukul - SSD1306
Satu bola, dua pemukul, dan kamu: kamu bermain tenis meja, salah satu video game paling awal, di layar OLED kecil. Dua tombol menggerakkan pemukulmu di kanan ke atas dan ke bawah, sementara komputer m

HTTPClient + API Cuaca ESP32 (dengan Layar OLED SSD1306)
Di proyek ini, kita memakai ESP32 untuk melakukan panggilan REST API ke API cuaca (wttr.in) lewat internet dengan HTTPClient.h. Berbeda dengan versi LCD I2C sebelumnya, di sini kita memakai layar OLED SSD1306 (128×64), yang memungkinkan font besar, ikon vektor, dan tampilan visual yang kaya di satu layar. Tujuh ikon vektor untuk kondisi cuaca (cerah, berawan sebagian, berawan, hujan, salju, badai, berkabut) digambar ketika program berjalan (tanpa file bitmap).

Jam dan Kalender Dot Matrix (MAX7219, DS1307)
Papan bercahaya untuk meja atau dinding yang menampilkan waktu dan tanggal dengan teks berjalan. Layar LED 8x32 menampilkan jam berangka besar dengan dua titik yang berkedip setiap detik; di awal seti

Pencatat Data Suhu ESP32 (DHT22 + RTC DS1307 + microSD + OLED)
Buat pencatat suhu bercap waktu dengan ESP32! Baca suhu/kelembapan DHT22 setiap menit, ambil waktu sebenarnya dari RTC DS1307, dan catat ke kartu microSD sebagai CSV. OLED menampilkan suhu langsung (font besar), kelembapan, cap waktu, dan penghitung catatan. File /temp_log.csv bisa dibuka di Excel, Google Sheets, atau Python pandas; cocok untuk rumah kaca, suhu kamar, data laboratorium, penyimpanan makanan, atau sarang lebah.
Artikel lainnya
Aplikasi BlueGrays
Rakit rangkaian ini langkah demi langkah di ponselmu
Skema pengkabelan, kode, dan daftar komponen dalam satu layar. 200+ proyek Arduino, ESP32, dan Pico siap dibuat.
Pindai dengan ponselmu
Arahkan kamera ke kode ini dan toko aplikasi di ponselmu akan terbuka.
atau buka toko aplikasi

