아두이노 I2C 통신 센서 연결이 계속 실패한다면
센서가 안 보일 때 코드부터 고치지 마세요
첫 번째 실수: 배선 확인 없이 예제 스케치만 바꾸는 습관
아두이노에서 I2C 통신 센서를 붙였는데 시리얼 모니터에 값이 0으로만 나오거나, 아예 주소가 검색되지 않는다면 가장 먼저 의심할 곳은 코드가 아닙니다. 현장에서 반복되는 실패는 의외로 단순합니다. SDA와 SCL을 반대로 꽂았거나, 센서 전원 전압을 잘못 넣었거나, GND가 공통으로 묶이지 않은 경우가 많습니다.
특히 초보자는 라이브러리 예제를 열고 주소값만 바꾸면 해결될 것이라고 생각합니다. 하지만 버스에 장치가 전기적으로 붙어 있지 않으면 어떤 라이브러리도 센서를 읽을 수 없습니다. 아두이노의 기본 개념처럼 보드와 외부 장치를 연결하는 구조를 이해해야, 예제 코드가 왜 실패하는지도 보입니다.
- SDA와 SCL 위치: 보드마다 핀 위치가 다릅니다. UNO 계열과 ESP32, 라즈베리파이는 핀 번호 표기가 다르므로 보드 핀맵을 기준으로 확인합니다.
- GND 공통 연결: 센서 전원과 마이크로컨트롤러의 기준 전위가 다르면 통신 신호가 정상으로 해석되지 않습니다.
- 전압 확인: 5V 보드와 3.3V 센서를 직접 연결하면 즉시 고장 나지 않아도 장기적으로 불안정해질 수 있습니다.
- 주소 스캐너 실행: 코드 디버깅 전에 I2C 스캐너로 장치가 버스에 보이는지 먼저 확인합니다.
센서값이 이상할 때는 라이브러리보다 먼저 전원, GND, SDA, SCL 네 줄을 눈으로 다시 따라가 보세요. 실패 원인의 절반 이상은 그 안에 있습니다.
주소가 검색된다고 성공은 아닙니다
I2C 스캐너에서 주소가 보였다고 해서 센서 연결이 끝난 것은 아닙니다. 주소 응답은 살아 있다는 신호일 뿐, 데이터 레지스터를 올바르게 읽는다는 뜻은 아닙니다. 같은 주소를 쓰는 모듈이 두 개 붙어 있거나, 라이브러리가 다른 칩 모델을 전제로 작성된 경우에는 주소는 잡히는데 값은 엉망으로 나옵니다.
예를 들어 온습도 센서라고 모두 같은 레지스터 구조를 쓰지 않습니다. 겉모양이 비슷한 보드라도 내부 칩이 AHT20인지 SHT31인지, BME280인지 BMP280인지에 따라 초기화 명령과 데이터 해석 방식이 달라집니다. 제품 페이지의 칩 이름을 확인하지 않고 예제 코드를 복사하면, 운 좋게 컴파일은 되지만 측정값은 믿을 수 없게 됩니다.
전압이 맞아 보여도 레벨 변환을 건너뛰지 마세요
두 번째 실수: 3.3V 센서를 5V 보드에 그냥 꽂기
센서 연결에서 가장 위험한 착각은 “전원이 들어오니 괜찮다”는 생각입니다. 많은 I2C 센서 모듈은 3.3V 칩을 사용하지만, 판매 페이지에는 3.3V~5V 지원이라고 적혀 있기도 합니다. 이때 모듈에 레귤레이터와 레벨 시프터가 함께 들어 있는지, 아니면 전원 입력만 넓게 받는지 반드시 구분해야 합니다.
전원 핀은 5V를 받아도 SDA, SCL 신호선은 3.3V까지만 허용되는 모듈이 있습니다. 이런 센서를 5V 아두이노에 직접 연결하면 처음에는 동작하는 것처럼 보이다가 특정 온도, 배선 길이, 다른 모듈 추가 상황에서 갑자기 실패합니다. 바로 이 지점이 실험실에서는 되는데 실제 프로젝트에서는 안 되는 전형적인 원인입니다.
- 센서 데이터시트에서 logic level 또는 I/O voltage 항목을 확인합니다.
- 보드가 5V 로직인지 3.3V 로직인지 확인합니다. 아두이노 UNO는 보통 5V, 라즈베리파이는 3.3V 기준입니다.
- 전압이 다르면 양방향 I2C 레벨 변환 모듈을 사용합니다.
- 전원은 충분한 전류를 공급하되, 신호선 전압은 센서 허용 범위를 넘기지 않습니다.
풀업 저항보다 먼저 볼 것은 버스 전체 전압입니다
이미 풀업 저항을 다룬 글들이 많지만, 실무에서 더 먼저 봐야 할 것은 풀업이 어느 전압으로 걸려 있는가입니다. 3.3V 센서와 5V 보드가 섞인 상태에서 SDA, SCL이 5V로 끌어올려지면 센서 입력 보호 회로가 계속 스트레스를 받습니다. 반대로 5V 보드가 3.3V 신호를 충분히 HIGH로 인식하지 못하는 조합도 있습니다.
저가 모듈을 여러 개 섞을 때는 각 모듈에 이미 풀업 저항이 붙어 있는지도 확인해야 합니다. 모듈 세 개를 병렬로 붙였는데 모두 4.7kΩ 풀업을 갖고 있다면 전체 저항값이 너무 낮아져 신호 상승은 빨라져도 버스 드라이버에 부담이 커질 수 있습니다. 실패를 줄이려면 “센서 하나씩 추가하며 측정”하는 방식이 가장 안전합니다.
| 상황 | 하지 말아야 할 행동 | 권장 대응 |
|---|---|---|
| 5V 아두이노 + 3.3V 센서 | 직결 후 예제 실행 | 레벨 변환 여부 확인 |
| 모듈 여러 개 병렬 연결 | 풀업 상태 미확인 | 각 모듈의 풀업 저항 유무 점검 |
| 라즈베리파이 연결 | 5V I2C 신호 입력 | 3.3V 기준 유지 |
같은 주소 센서를 두 개 꽂고 버스 탓하지 마세요
세 번째 실수: 주소 충돌을 노이즈로 오해하기
I2C는 여러 장치를 같은 SDA, SCL 라인에 묶을 수 있어 사물인터넷 프로젝트에 편리합니다. 하지만 조건이 있습니다. 같은 버스에 붙은 각 장치의 주소가 달라야 합니다. 같은 주소를 가진 센서 두 개가 동시에 응답하면 마스터는 어느 장치의 데이터인지 구분할 수 없습니다.
예를 들어 같은 조도 센서 두 개로 실내와 실외 밝기를 비교하려고 할 때, 두 모듈의 기본 주소가 같으면 단순 병렬 연결로는 해결되지 않습니다. 일부 센서는 주소 선택 핀이 있어 납땜 점퍼로 바꿀 수 있지만, 그렇지 않은 센서는 I2C 멀티플렉서나 다른 인터페이스 센서를 써야 합니다. 이 문제를 노이즈로 착각하면 배선을 짧게 줄이고 저항을 바꿔도 해결되지 않습니다.
- 주소 선택 핀 확인: ADDR, A0, A1 같은 표기가 있는지 봅니다.
- 데이터시트의 주소 범위 확인: 0x76/0x77처럼 선택 가능한 주소가 있는 센서가 있습니다.
- I2C 멀티플렉서 사용: 동일 주소 센서를 여러 개 써야 한다면 TCA9548A 같은 멀티플렉서를 고려합니다.
- 기능 중복 줄이기: 꼭 같은 센서를 두 개 써야 하는지, 다른 측정 방식으로 나눌 수 있는지 검토합니다.
버스에 장치를 추가할 때마다 I2C 스캐너 결과를 저장해 두면, 어느 시점부터 충돌이 생겼는지 빠르게 찾을 수 있습니다.
장치 드라이버와 라이브러리도 충돌합니다
하드웨어 주소만 문제가 되는 것은 아닙니다. 같은 프로젝트에 여러 센서 라이브러리를 추가하다 보면 내부에서 Wire 객체를 초기화하는 방식이 충돌할 수 있습니다. 어떤 라이브러리는 기본 I2C 포트를 전제로 하고, 어떤 라이브러리는 begin 함수에서 속도나 핀을 다시 설정합니다. 디바이스 드라이버 통합개발환경의 개요를 떠올리면, 하드웨어와 소프트웨어 계층이 함께 맞아야 안정성이 나온다는 점을 이해하기 쉽습니다.
ESP32처럼 I2C 핀을 자유롭게 지정할 수 있는 보드는 편리하지만, 그만큼 실수도 늘어납니다. 한 라이브러리는 21번, 22번 핀을 쓰고 다른 코드 조각은 다른 핀으로 Wire.begin을 다시 호출하면 센서가 중간에 사라진 것처럼 보입니다. 프로젝트가 커질수록 I2C 초기화는 한 곳에서만 처리하는 편이 좋습니다.
라즈베리파이에서만 실패한다면 권한과 부팅 순서를 보세요
아두이노에서는 되는데 라즈베리파이에서는 안 되는 이유
많은 분이 아두이노에서 센서를 읽은 뒤, 같은 센서를 라즈베리파이로 옮겨 데이터 로깅이나 웹 대시보드에 연결합니다. 이때 배선은 맞는데 파이썬 코드에서 장치가 열리지 않는 일이 자주 생깁니다. 원인은 센서보다 운영체제 설정일 가능성이 큽니다. I2C 인터페이스가 비활성화되어 있거나, 사용자 권한이 맞지 않거나, 부팅 직후 센서 전원이 안정되기 전에 스크립트가 먼저 실행될 수 있습니다.
라즈베리파이는 마이크로컨트롤러가 아니라 리눅스 컴퓨터입니다. 그래서 센서를 읽기 전에 커널 모듈, 장치 파일, 서비스 실행 순서가 모두 영향을 줍니다. 최근 사물인터넷 장비는 센서값을 단순 출력하는 수준을 넘어 로컬 AI 보드나 엣지 장치와 묶이는 흐름도 강해졌습니다. 예를 들어 차세대 드론용 AI 보드 관련 소식처럼 엣지 장치가 복잡해질수록, 센서 통신의 기본 안정성은 더 중요해집니다.
- i2cdetect로 주소가 보이는지 먼저 확인합니다.
- 설정 도구에서 I2C 인터페이스가 활성화되어 있는지 확인합니다.
- 서비스로 자동 실행한다면 네트워크보다 센서 초기화 대기 시간이 더 필요한지 봅니다.
- 센서 전원 공급이 USB 주변기기 추가 후에도 충분한지 확인합니다.
- 파이썬 가상환경에서 필요한 smbus, board, busio 계열 패키지가 같은 환경에 설치되어 있는지 점검합니다.
“랜덤하게 한 번씩 실패해요”라는 질문에 대한 답
가장 자주 받는 질문은 이것입니다. “평소에는 잘 되는데 하루에 한두 번 센서 읽기가 실패합니다. 코드를 다시 실행하면 살아납니다.” 이런 증상은 단일 원인으로 단정하기 어렵지만, 경험상 세 가지를 함께 봐야 합니다. 전원 흔들림, 예외 처리 부재, 버스 복구 루틴 미구현입니다.
센서가 순간적으로 응답하지 않을 때 프로그램이 그대로 멈추면 장비 전체가 죽은 것처럼 보입니다. 반대로 실패를 감지하고 재시도, 버스 재초기화, 값 무효 처리까지 해두면 사용자는 일시적인 통신 오류를 거의 느끼지 못합니다. 실패하지 않는 회로를 만드는 것보다 실패해도 회복하는 구조를 만드는 쪽이 실제 프로젝트에서는 더 강합니다.
- 읽기 실패를 정상 시나리오로 다루기: 센서값이 없을 때 None, null, 이전값 유지 중 무엇을 쓸지 정합니다.
- 재시도 횟수 제한: 무한 루프 대신 2~3회 재시도 후 로그를 남깁니다.
- 부팅 후 대기: 전원 인가 직후 1~3초 대기를 넣어 센서 초기화를 기다립니다.
- 로그에 주소와 시간 기록: 어느 센서가 언제 실패했는지 남겨야 다음 수정이 가능합니다.
- 버스 분리 검토: 중요한 센서와 부가 센서를 같은 I2C 버스에 모두 묶지 않는 설계도 방법입니다.
가격이 낮은 센서 모듈로도 충분히 안정적인 임베디드 개발을 할 수 있습니다. 다만 실패를 숨기지 말고, 어떤 조건에서 실패하는지 기록해야 합니다. 센서 연결은 한 번 성공했다고 끝나는 작업이 아니라 전원, 주소, 드라이버, 실행 순서가 함께 맞물리는 작은 시스템 설계입니다.

- 이전글엣지AI 보드에 I2C 센서 붙여본 지 한 달 26.10.06
- 다음글“요즘은 I2C 통신 안 쓴다”는 말이 틀린 이유 26.10.04
등록된 댓글이 없습니다.
