Dasar · 11 mnt baca

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.

Modul adaptor LCD I2C dengan chip PCF8574
Adaptor LCD I2C: disolder di bagian belakang LCD, chip PCF8574 mengubah LCD 16 pin menjadi hanya empat kabel (GND, VCC, SDA, SCL) dan biasanya menjawab di alamat 0x27 atau 0x3F.

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:

  1. START: Ketika SCL tinggi, controller menarik SDA dari 1 ke 0, dan setiap perangkat di bus mulai mendengarkan.
  2. Alamat dan bit arah: Alamat 7-bit dikirim, diikuti bit baca (1) atau tulis (0).
  3. 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.
  4. 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.
  5. 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:

FiturI2CSPIUART (Serial)
Kabel sinyal2 (SDA, SCL)3 bersama (MOSI, MISO, SCK) + satu CS per perangkat2 (TX, RX)
Jumlah perangkatLebih dari 100 alamat di satu busSebanyak pin CS yang tersediaBiasanya 2 perangkat
Kecepatan umum100 kHz, 400 kHz, 1 MHz10 MHz ke atas9600 – 115200 baud
Pemilihan perangkatLewat alamatLewat pin CSTidak ada, titik ke titik
Pemakaian umumSensor, modul jam, layar kecil, EEPROMKartu SD, layar TFT, RFIDGPS, Bluetooth, koneksi ke komputer

Kecepatan I2C dan batas teknisnya

ModeKecepatan maksimumWaktu naik maksimumDipakai di mana?
Standard mode (Sm)100 kHz1000 nsBawaan, kabel panjang
Fast mode (Fm)400 kHz300 nsOLED, MPU6050, BMP280
Fast mode plus (Fm+)1 MHz120 nsPico dan beberapa sensor yang lebih baru
High-speed mode (Hs)3,4 MHz80 ns (400 pF), butuh driver khususJarang 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.

ModulChipAlamat bawaanBisa diubah?
Modul LCD I2C (16x2, 20x4)PCF8574 / PCF8574A0x27 / 0x3FDengan jumper A0–A2: 0x20–0x27 atau 0x38–0x3F
OLED 0,96 inciSSD13060x3C0x3D lewat resistor di bagian belakang
Akselerometer dan giroskopMPU60500x680x69 ketika AD0 = 1
Jam waktu nyata (RTC)DS1307 / DS32310x68Tidak
Tekanan dan suhuBMP280 / BME2800x76 atau 0x77Tergantung pin SDO
Intensitas cahayaBH17500x230x5C ketika ADDR = 1
ADC 16-bitADS11150x480x48–0x4B lewat pin ADDR
Driver servo dan PWM 16 kanalPCA96850x40Puluhan alamat mulai 0x40 lewat jumper A0–A5
Memori EEPROMAT24C32 / AT24C2560x500x50–0x57 lewat A0–A2
Multiplexer I2CTCA9548A0x700x70–0x77 lewat A0–A2
Ketika kamu memindai modul Tiny RTC (DS1307), alamat 0x50 muncul di samping 0x68; itu bukan error, melainkan EEPROM AT24C32 di modul tersebut. Di modul ZS-042 dengan DS3231, memori yang sama menjawab di 0x57.

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.

SituasiPull-up yang disarankanCatatan
Satu modul, kabel pendek, 100 kHz4,7 kΩ – 10 kΩKebanyakan modul sudah punya
Beberapa modul, 400 kHz2,2 kΩ – 4,7 kΩResistor di modul-modul itu jadi terparalel
Kabel lebih dari 50 cm2,2 kΩ dan 100 kHzJangan 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
Kebanyakan modul sudah membawa resistor pull-up 4,7 kΩ atau 10 kΩ, dan resistor dari modul-modul di bus yang sama menjadi terparalel. Kalau tiga modul masing-masing punya 4,7 kΩ, totalnya sekitar 1,57 kΩ; di 5 V, itu tepat di bawah batas 3 mA. Kalau kamu menggabungkan empat atau lima modul, mungkin kamu perlu melepas pull-up dari sebagian modul atau memutus jumper solder-nya.

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

BoardSDASCLCatatan
Arduino Uno / NanoA4A5Di Uno R3, pin SDA dan SCL di samping AREF adalah bus yang sama dengan A4/A5
Arduino Mega 25602021Di Mega, A4 dan A5 bukan I2C
Arduino Leonardo / MicroD2D3Ini pin digital
ESP32 (DevKit)GPIO 21GPIO 22Pin lain bisa dipilih dengan Wire.begin(SDA, SCL); bus kedua adalah Wire1
ESP8266 NodeMCUD2 (GPIO 4)D1 (GPIO 5)I2C software, pinnya bisa diubah
Raspberry Pi PicoGP4 (I2C0)GP5 (I2C0)I2C0 dan I2C1 tersedia di banyak pasangan pin
Arduino Uno bekerja di 5 V, sedangkan ESP32, ESP8266, dan Pico bekerja di 3,3 V. Kalau modul yang dihubungkan ke board 3,3 V diberi daya 5 V dan pull-up-nya tersambung ke 5 V, jalur SDA dan SCL naik ke 5 V dan bisa merusak pin yang tidak tahan 5 V. Beri daya modul dari 3,3 V atau pakai level shifter dua arah berbasis transistor BSS138 di antara kedua tegangan.

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.

  1. Hubungkan GND modul ke GND Arduino dan VCC-nya ke 5V (ke 3.3V untuk modul yang hanya mendukung 3,3 V).
  2. Hubungkan SDA ke A4 dan SCL ke A5. Kalau modulnya lebih dari satu, gabungkan semua pin SDA dan SCL di breadboard.
  3. Upload sketch di bawah dan buka Serial Monitor di 115200 baud.
  4. Catat alamat yang muncul. Kalau tidak ada yang muncul, periksa pengkabelan, GND bersama, dan resistor pull-up.
  5. Cabut dan sambungkan lagi modul satu per satu untuk memastikan alamat mana milik perangkat mana; scanner memindai ulang setiap 5 detik.
C++ (Arduino IDE)
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()ArtiYang dilakukan
0Perangkat mengakui alamatnya (ACK)Pakai alamat ini di kodemu
1Data terlalu panjang untuk bufferTidak pernah muncul di scanner; jangan tulis lebih dari 32 byte sekaligus di Uno
2NACK pada alamatTidak ada perangkat di alamat itu, normal ketika memindai
3NACK pada dataPerangkat menolak perintahnya; periksa nomor register
4Error bus lainnyaKorsleting, pull-up tidak ada, atau gangguan
5TimeoutBus 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.

Modul akselerometer dan giroskop MPU-6050
Modul MPU-6050: terhubung ke bus I2C lewat pin VCC, GND, SCL, dan SDA, dan pin AD0 memilih alamat 0x68 atau 0x69.
C++ (Arduino IDE)
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?.

C++ (Arduino IDE)
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?.

MicroPython
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 0x68

Ide 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

GejalaKemungkinan penyebabSolusi
Scanner tidak menemukan perangkatSDA dan SCL tertukar, tidak ada GND bersama, atau modul tidak mendapat dayaPeriksa pengkabelan; di Uno, A4 = SDA dan A5 = SCL
Scanner macet atau melaporkan error di setiap alamatBus korsleting atau pull-up tidak adaTambahkan setWireTimeout; ukur tegangan catu di SDA dan SCL yang sedang diam
Sketch bisa dikompilasi tetapi layar tetap kosongAlamat di kode salah (0x27, padahal 0x3F)Pakai alamat yang ditemukan scanner
Di belakang board tertulis 0x78 dan kodenya tidak jalanYang dipakai alamat 8-bitBagi 2: 0x78 → 0x3C
Dua sensor tidak mau bekerja bersamaBentrok alamatUbah pin alamat, pakai bus kedua atau TCA9548A
Macet acak, gangguan ketika motor berjalanKabel panjang, gangguan listrik, atau catu daya lemahPerpendek kabel, turunkan ke 100 kHz, tambahkan kapasitor 100 nF di modul
Pin ESP32 atau Pico rusakPull-up yang tersambung ke 5 V dihubungkan ke pin 3,3 VBeri daya modul dari 3,3 V atau pakai level shifter
Multimeter adalah sahabat terbaikmu untuk masalah I2C: dengan daya menyala dan tanpa komunikasi, kamu seharusnya mengukur tegangan catu (5 V atau 3,3 V) di SDA dan SCL. Kalau terbaca 0 V, ada perangkat yang membuat jalurnya korsleting atau macet. Dengan board dalam keadaan mati, kamu juga bisa memperkirakan nilai total pull-up di bus dengan mengukur hambatan di antara SDA dan VCC.

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.

Lihat semua proyek
Menggunakan Layar LCD dengan I2C
#32Pemula
Premium

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

4.8(53)
70
Layar LCD I2C ESP32 (16x2)
#119Menengah
Premium

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).

4.9(23)
40
Jam Digital dengan ESP32 dan RTC DS1307 (I2C + LCD)
#120Menengah
Premium

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.

4.6(26)
40
Kalkulator I2C Arduino
#94Menengah
Premium

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.

5.0(31)
43
Game Bola Pemukul - SSD1306
#86Menengah
Premium

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

4.5(47)
65
HTTPClient + API Cuaca ESP32 (dengan Layar OLED SSD1306)
#134Mahir
Premium

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).

4.3(10)
19
Jam dan Kalender Dot Matrix (MAX7219, DS1307)
#84Menengah
Premium

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

5.0(37)
59
Pencatat Data Suhu ESP32 (DHT22 + RTC DS1307 + microSD + OLED)
#144Mahir
Premium

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.

4.7(7)
12