Microcontroller boards can communicate with a wide variety of sensors using several standard protocols. This guide serves as a practical resource for quickly referencing the pin connections for I2C, SPI, and UART communication on popular microcontroller boards, including Arduino, ESP32, and Raspberry Pi. If you're new to Arduino and need the basics on board setup and the IDE, start with our Arduino getting started guide for beginners.
I2C (Inter-Integrated Circuit)
Diagram courtesy of SparkFun
I2C is a master-slave protocol where the Arduino acts as the master and sensors are slaves. Each device has a unique 7-bit or 10-bit address, allowing multiple devices to share the same SDA and SCL lines. The master initiates communication by sending the device address followed by read or write commands. Data is transmitted in bytes, synchronized by the clock line, and both master and slave can acknowledge receipt of each byte.
Pin Descriptions
| Pin | Type | Description |
|---|---|---|
| SDA | Data | Carries data between master and slave devices |
| SCL | Clock | Synchronizes data transfer |
Pin Mapping
| Board | SDA | SCL | Notes |
|---|---|---|---|
| Arduino Uno / Nano / Mini | A4 | A5 | Fixed hardware pins |
| Arduino Mega 2560 | 20 | 21 | Fixed hardware pins |
| Arduino Leonardo / Micro | 2 | 3 | Fixed hardware pins |
| Arduino Due / Zero | 20 | 21 | Fixed hardware pins |
| ESP32 | 21 (default) | 22 (default) - configurable via code | Can be reassigned in software |
| ESP8266 (NodeMCU) | D2 (GPIO4) | D1 (GPIO5) - configurable via code | Can be reassigned in software |
| Raspberry Pi Pico / Pico 2 | I2C0: GP0 I2C1: GP2 |
I2C0: GP1 I2C1: GP3 |
2 I2C buses (I2C0 default) |
SPI (Serial Peripheral Interface)
Diagram courtesy of SparkFun
SPI uses a master-slave setup with separate lines for data transmission (MOSI / PICO), data reception (MISO / POCI), clock (SCK), and a unique chip select (CS) for each device. The master controls the clock, and communication occurs full-duplex, meaning data can be sent and received simultaneously. Each slave listens only when its CS pin is active, allowing multiple devices to share the SPI bus.
Pin Descriptions
| Pin | Type | Description |
|---|---|---|
| MOSI / PICO | Data Out | Sends data from master to slave |
| MISO / POCI | Data In | Receives data from slave to master |
| SCK | Clock | Synchronizes data transfer |
| CS / SS | Chip Select | Selects the active slave device |
Pin Mapping
| Board | MOSI / PICO | MISO / POCI | SCK | CS / SS |
|---|---|---|---|---|
| Arduino Uno / Nano / Mini | 11 | 12 | 13 | 10 (default SS) |
| Arduino Mega 2560 | 51 | 50 | 52 | 53 (default SS) |
| Arduino Leonardo / Micro | D16 | D14 | D15 | 10 (default SS) |
| ESP32 | 23 (default) | 19 (default) | 18 (default) | 5 (default) - configurable |
| ESP8266 (NodeMCU) | D7 (GPIO13) | D6 (GPIO12) | D5 (GPIO14) | D8 (GPIO15) |
| Raspberry Pi Pico / Pico 2 | GP3 / GP7 | GP4 / GP8 | GP2 / GP6 | Custom |
UART / Serial
Diagram courtesy of SparkFun
UART is a point-to-point, asynchronous protocol that sends data as a stream of bits using TX and RX lines. There are no addresses; each device connects directly to another. The data is framed with start and stop bits, and both devices must agree on a baud rate to ensure accurate timing.
Pin Descriptions
| Pin | Type | Description |
|---|---|---|
| TX | Transmit | Sends data from this device to another UART device |
| RX | Receive | Receives data from another UART device |
Pin Mapping
| Board | TX | RX | Notes |
|---|---|---|---|
| Arduino Uno / Nano / Mini | 1 | 0 | Single hardware UART |
| Arduino Mega 2560 | TX0: 1 TX1: 18 TX2: 16 TX3: 14 |
RX0: 0 RX1: 19 RX2: 17 RX3: 15 |
Four hardware UARTs |
| Arduino Leonardo / Micro | TX: 1 (USB Serial via MCU) | RX: 0 (USB Serial via MCU) | Hardware Serial available on pins 0/1, plus USB Serial |
| ESP32 | TX0: 1 TX1: 17 TX2: 16 |
RX0: 3 RX1: 16 RX2: 17 |
Multiple UARTs, configurable pins |
| ESP8266 (NodeMCU) | TX: D10 (GPIO1) | RX: D9 (GPIO3) | Single hardware UART |
| Raspberry Pi Pico / Pico 2 | TX0: GP0 TX1: GP4 |
RX0: GP1 RX1: GP5 |
Two UARTs, pins configurable |
Comparison of I2C, SPI, and UART
Each communication protocol has its own advantages and typical use cases depending on the number of devices, speed requirements, and wiring complexity. Here's a detailed comparison:
| Category | I2C | SPI | UART / Serial |
|---|---|---|---|
| Number of Wires | 2 (SDA, SCL) | 4 minimum (MOSI / PICO, MISO / POCI, SCK, CS per device) | 2 (TX, RX) |
| Speed | Standard: 100 kbps Fast: 400 kbps Fast+: 1 Mbps |
Fast: typically up to 10–50 Mbps (depending on MCU) | Standard baud rates: 9600–115200 bps, can be higher |
| Device Addressing | Each slave has a unique 7-bit or 10-bit address | No addressing, each slave has dedicated CS line | Point-to-point (no addressing) |
| Typical Use Cases | Multiple sensors, EEPROMs, RTCs, display modules | High-speed sensors, SD cards, displays, ADC/DAC modules | GPS modules, Bluetooth modules, serial debugging, simple devices |
| Pros | Few wires, supports multiple devices on same bus, widely used | Very fast, full-duplex communication, simple protocol | Simple to implement, widely supported, long cable distance possible |
| Cons | Slower than SPI, limited cable length, may need pull-up resistors | More wires required, limited number of CS lines, each device needs separate CS | Only supports 1-to-1 communication per hardware UART, slower than SPI for multiple devices |
When to Use Which Protocol
- I2C: Use when you have multiple low-to-medium speed devices that need to share the same bus with minimal wiring, like temperature sensors, EEPROMs, RTCs, or small displays.
- SPI: Use when you need high-speed communication, full-duplex data transfer, or when working with SD cards, TFT displays, ADC/DAC chips, or any device where speed is critical.
- UART / Serial: Use for simple point-to-point communication, debugging via serial console, or modules like GPS, Bluetooth, or other serial peripherals where only two wires are needed.
1 comment
Saya ingin menambahkan sedikit catatan praktis dari pengalaman di lapangan. Meskipun secara teori UART terlihat “hanya 2 kabel”, ada dua hal krusial yang sering luput dari perhatian:
Level Tegangan (Voltage Logic): Sangat penting untuk memastikan level tegangan TX/RX kedua perangkat cocok (misal 3.3V vs 5V). Menghubungkan UART 5V (Arduino Uno) langsung ke UART 3.3V (ESP32) tanpa logic level converter bisa merusak modul penerima. Ini adalah penyebab umum kegagalan komunikasi serial selain ketidaksesuaian baud rate.
RX ke TX dan TX ke RX: Aturan dasar yang tak boleh dilupakan, yaitu kabel RX penerima harus dihubungkan ke TX pengirim lawan, dan sebaliknya.
Saya sangat setuju dengan tabel perbandingan yang Anda buat. Rekomendasi “When to Use Which Protocol” juga sudah tepat sasaran. Dalam pengembangan sistem embedded modern, ketiga protokol ini bukanlah pesaing, melainkan alat pelengkap. Misalnya, di satu proyek IoT, kita bisa menggunakan I2C untuk membaca sensor suhu/tekanan (BMP280), SPI untuk mengakses kartu SD atau display TFT yang membutuhkan refresh cepat, dan UART untuk berkomunikasi dengan modul GPS atau mencetak log debugging ke Serial Monitor.
Pemahaman mendalam tentang fondasi komunikasi data seperti UART, I2C, dan SPI ini adalah skill wajib bagi siapa pun yang terjun di dunia embedded systems, robotika, dan Internet of Things (IoT). Materi seperti ini sangat krusial dan menjadi bagian dari kurikulum inti di program studi Teknik Elektro, Informatika, atau Teknik Komputer. Di Universitas Telkom Surabaya (surabaya.telkomuniversity.ac.id), mahasiswa tidak hanya dibekali teori tentang ketiga protokol ini di kelas, tetapi juga langsung mempraktikkannya dalam sesi laboratorium embedded system menggunakan berbagai mikrokontroler seperti Arduino, ESP32, dan Raspberry Pi Pico. Mereka diajak untuk membandingkan langsung kinerja ketiga protokol ini dalam studi kasus nyata, misalnya membaca data dari multiple sensor secara simultan—sehingga lulusannya benar-benar siap menghadapi tantangan industri 4.0 yang menuntut penguasaan perangkat keras dan perangkat lunak secara terintegrasi.
Sekali lagi, terima kasih atas ringkasan yang sangat bermanfaat ini. Jika nanti Anda memiliki pertanyaan lebih spesifik terkait implementasi kode atau troubleshooting koneksi serial pada board tertentu, jangan ragu untuk mendiskusikannya lebih lanjut!