기초 · 난이도 보통
I²C 장치 여러 개 연결하기 주소 확인 충돌 해결 풀업 저항
I²C는 선 두 개로 센서와 화면 여러 개를 함께 쓰는 방식이에요. 장치마다 다른 주소, i2c.scan()으로 확인하는 법, MPU6050과 DS3231처럼 주소가 겹칠 때 고치는 세 가지 방법, 풀업 저항과 선 길이, 5V 모듈을 쓸 때 주의할 점을 정리했어요.
선 두 개에 장치 여러 개
I²C는 SDA(데이터)와 SCL(시계) 두 선으로 통신해요. 센서마다 핀을 따로 쓰지 않고, 여러 장치가 같은 두 선에 나란히 붙어요. 피코가 "0x76번 장치, 대답해 줘"처럼 주소를 불러서 그 장치하고만 이야기하는 방식이에요. 그래서 BME280(기압), OLED 화면, MPU6050(가속도)을 GP4·GP5 두 핀에 모두 이을 수 있어요.
배선 규칙은 단순해요. 모든 장치의 SDA끼리, SCL끼리, VCC끼리, GND끼리 이어요. 브레드보드에서는 SDA와 SCL을 한 열씩 정해 두고 장치 선을 그 열에 모으면 깔끔해요.
주소 확인하기
주소는 장치마다 정해져 있어요. 이 자료실에서 자주 쓰는 장치의 기본 주소는 이래요.
| 장치 | 기본 주소 | 바꾸는 방법 |
|---|---|---|
| SSD1306 OLED | 0x3C | 뒷면 점퍼로 0x3D |
| LCD1602 I²C 백팩 | 0x27 | 칩 종류에 따라 0x3F, 점퍼로 바뀜 |
| BME280 | 0x76 | SDO를 3.3V에 이으면 0x77 |
| MPU6050 | 0x68 | AD0를 3.3V에 이으면 0x69 |
| DS3231 시계 모듈 | 0x68 | 바꿀 수 없음(모듈의 기억 칩이 0x57도 씀) |
| MLX90614 | 0x5A | EEPROM에 새 주소를 써서 바꿀 수 있지만 보통 그대로 써요 |
| MAX30102 | 0x57 | 바꿀 수 없음 |
| VL53L0X | 0x29 | 코드로만 바꿈 |
| SEN0322 산소 | 0x73 | 스위치로 0x70~0x73 |
표는 제품 설명서에서 확인한 기본값이에요. 같은 이름이라도 모듈마다 다를 수 있으니, 연결한 뒤 꼭 주소를 직접 찾아봐요.
from machine import Pin, I2C
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
found = i2c.scan()
print("찾은 장치:", [hex(a) for a in found])
print(f"DATA: devices={len(found)}")
i2c.scan()은 대답한 장치의 주소 목록을 돌려줘요. 목록이 비어 있으면 SDA·SCL을 바꿔 꽂았거나, 전원·GND가 빠졌거나, 풀업 저항이 없는 경우가 많아요.
주소가 겹칠 때
같은 버스에 주소가 같은 장치가 둘 있으면 둘이 동시에 대답해서 값이 엉망이 돼요. 대표적인 예가 MPU6050과 DS3231(둘 다 0x68), DS3231 모듈의 기억 칩과 MAX30102(둘 다 0x57)예요. 고치는 방법은 세 가지예요.
- 주소 핀 바꾸기: MPU6050의 AD0를 3.3V에 이으면 0x69가 돼요. 코드에서도 0x69로 불러요.
- 다른 I²C 버스 쓰기: 피코에는 I2C0과 I2C1 두 버스가 있어요. 한 장치를 I2C1(예: GP6·GP7)으로 옮기면 주소가 같아도 괜찮아요.
- 멀티플렉서 쓰기: TCA9548A 같은 모듈은 버스를 여러 갈래로 나눠 줘요. 장치가 많을 때 써요. 이 모듈도 자기 주소(기본 0x70)가 있어서, SEN0322를 0x70으로 바꿔 두었다면 겹치지 않게 해요.
시나브로 PICO 작업대에 MPU6050과 DS3231을 함께 꽂으면 점검 칸에 주소 충돌이 뜨고, [다른 I²C 버스로 옮기기] 단추로 2번 방법을 바로 적용할 수 있어요.
풀업 저항
I²C 선은 평소에 저항으로 전원 쪽에 당겨져 있어야(풀업) 신호가 제대로 오가요. 대부분의 센서 모듈에는 4.7kΩ이나 10kΩ 풀업 저항이 이미 붙어 있어서 따로 달 필요가 없어요. 반대로 모듈을 많이 이으면 풀업 저항이 나란히 여러 개 붙어 저항이 작아져요. 장치를 여러 개 이은 뒤 통신이 불안해지면, 일부 모듈의 풀업 점퍼를 끊는 방법을 판매처 자료에서 찾아봐요.
모듈 없이 칩만 쓰는 경우에는 SDA와 SCL 각각에 3.3V로 4.7kΩ 풀업을 달아요.
선 길이와 속도
I²C는 원래 한 기판 안의 짧은 거리용이에요. 브레드보드와 짧은 점퍼선(수십 cm 이내)에서 잘 동작해요. 센서를 멀리(예를 들어 1m 넘게) 떨어뜨려야 하면 속도를 100kHz보다 낮춰 보고, 그래도 불안하면 UART처럼 먼 거리에 맞는 통신을 쓰는 센서를 골라요.
5V I²C 모듈
LCD1602 I²C 백팩처럼 5V로 켜야 밝게 보이는 모듈이 있어요. 이 모듈의 풀업 저항이 5V 쪽에 붙어 있으면 SDA·SCL 선에도 5V가 걸려요. I²C는 같은 선으로 신호가 양쪽으로 오가서 분압 저항으로 해결할 수 없어요. 양방향 레벨 변환기(레벨 시프터)를 쓰거나, 3.3V에서도 동작하는 모듈인지 확인해 3.3V로 켜요.
장치 두 개를 함께 읽는 코드
from machine import Pin, I2C
import time
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
found = i2c.scan()
print("주소:", [hex(a) for a in found])
for want, name in ((0x76, "BME280"), (0x68, "MPU6050")):
print(name, "있음" if want in found else "없음")
print(f"DATA: bme={int(0x76 in found)}, mpu={int(0x68 in found)}")
이렇게 시작할 때 필요한 장치가 모두 있는지 먼저 확인하면, 배선 문제를 코드 문제로 착각하지 않아요.
스캔 결과로 문제 찾기
| 스캔 결과 | 의심할 것 |
|---|---|
| 빈 목록 [] | SDA·SCL 바꿔 꽂음, 전원·GND 빠짐, 버스 번호와 핀 묶음이 다름 |
| 장치 수보다 주소가 적음 | 두 장치의 주소가 같음(충돌), 한 장치의 전원이 빠짐 |
| 처음 보는 주소가 있음 | 모듈에 다른 칩이 함께 붙어 있음(예: DS3231 모듈의 0x57) |
| 가끔만 보임 | 선이 헐거움, 선이 길거나 풀업이 너무 많음, 속도가 빠름 |
스캔은 배선을 확인하는 가장 빠른 방법이에요. 새 장치를 하나 이을 때마다 스캔해서 목록이 하나씩 늘어나는지 보면, 문제가 생긴 장치를 바로 찾을 수 있어요.
자주 하는 실수
- SDA와 SCL을 바꿔 꽂기. 스캔 목록이 비어요. 핀 이름을 다시 봐요.
- I2C(0)에 I2C1 핀 쓰기. GP6·GP7은 I2C1이에요. 버스 번호와 핀 묶음이 맞아야 해요(피코 핀 지도).
- 주소를 코드에 잘못 적기. 스캔에서 0x77이 나왔는데 코드는 0x76을 부르면 "장치 없음"이 나와요.
- GND 공유를 빼먹기. 전원을 따로 쓰는 장치도 GND는 피코와 이어야 해요.
더 알아보기
- 공식 자료: Raspberry Pi "RP2350 datasheet"(I2C 핀 기능), MicroPython 문서 "machine.I2C"
- 기초 글: 피코 핀 지도, 전원 계산
- I²C 센서 글: BME280, SEN0322 산소