I2C 통신은 풀업 저항을 빼면 반드시 흔들린다

profile_image
작성자 회로실패분석가서준
댓글 0건 조회 1회

센서가 가끔 멈춘다면 코드보다 배선을 먼저 의심해야 합니다

실패는 대부분 통신 시작 전에 만들어집니다

아두이노나 라즈베리파이에 센서를 붙였는데 처음 몇 번은 값이 잘 나오다가 어느 순간 I2C 통신이 멈추는 경우가 있습니다. 이때 많은 분이 라이브러리 버전, 예제 코드, delay 시간부터 고치지만 실제 현장에서는 코드가 아니라 배선과 전기적 조건에서 문제가 시작되는 일이 훨씬 많습니다.

I2C는 SDA와 SCL 두 선만 있으면 된다고 설명되기 쉽지만, 그 두 선이 안정적으로 0과 1을 오가려면 기준 전압, 풀업 저항, 배선 길이, 공통 GND가 맞아야 합니다. 특히 브레드보드에서 테스트할 때는 접촉 저항과 점퍼선 품질까지 영향을 주기 때문에 책상 위 성공이 곧 제품화 성공을 뜻하지 않습니다.

  • 하지 말아야 할 실수: 센서가 한 번 인식됐다고 배선을 검증하지 않는 것
  • 자주 보이는 증상: 주소 스캔은 되지만 측정값이 0, 255, -1처럼 튀는 것
  • 먼저 볼 지점: SDA/SCL 풀업, GND 공통, 전원 전압, 배선 길이

특히 아두이노 입문 단계에서는 예제 코드가 워낙 많아 코드를 정답처럼 받아들이기 쉽습니다. 아두이노 자체의 개념을 확인하려면 아두이노에 대한 기본 설명을 참고해도 좋지만, 실제 센서 연결에서는 보드보다 버스 조건을 더 꼼꼼히 봐야 합니다.

센서 연결이 불안정할 때는 새 라이브러리를 찾기 전에 멀티미터로 전원과 GND부터 재는 습관이 가장 빠른 디버깅입니다.

풀업 저항을 자동으로 해결된다고 믿으면 안 됩니다

내장 풀업은 편하지만 만능이 아닙니다

I2C 통신에서 가장 흔한 오해는 “보드에 이미 풀업이 있으니 신경 쓰지 않아도 된다”는 생각입니다. 일부 센서 모듈에는 풀업 저항이 붙어 있고, 마이크로컨트롤러도 내부 풀업을 설정할 수 있습니다. 하지만 그 값은 대개 약하고, 배선이 길어지거나 센서가 여러 개 붙으면 신호 상승 시간이 느려져 통신이 흔들릴 수 있습니다.

SDA와 SCL은 오픈드레인 방식으로 동작하기 때문에 HIGH 상태를 저항이 끌어올립니다. 이 저항이 너무 크면 신호가 늦게 올라가고, 너무 작으면 전류 부담이 커집니다. 그래서 “풀업이 있느냐”보다 현재 회로에 맞는 풀업 값이냐가 더 중요합니다.

풀업 값은 회로 규모에 따라 달라집니다

일반적인 짧은 배선 테스트에서는 4.7kΩ이 자주 쓰이고, 센서 수가 늘거나 선이 길어지는 경우 2.2kΩ 근처를 검토하기도 합니다. 반대로 여러 센서 모듈에 각각 풀업이 들어 있으면 병렬 합성 저항이 너무 낮아질 수 있으므로 모듈별 회로도를 확인해야 합니다.

  1. 센서 모듈에 풀업 저항이 실장되어 있는지 확인합니다.
  2. 보드의 내부 풀업만으로 버티는 구조인지 확인합니다.
  3. 여러 모듈을 병렬로 붙였다면 합성 저항을 계산합니다.
  4. 오실로스코프가 있다면 SCL 상승 시간이 지나치게 둔하지 않은지 봅니다.

이 단계에서 하지 말아야 할 행동은 센서가 안 잡힌다고 무작정 주소만 바꾸는 것입니다. 주소 충돌도 실제 문제지만, 풀업이 맞지 않으면 주소 스캐너 결과 자체가 들쭉날쭉해집니다. 스캔 결과가 매번 다르면 주소보다 신호 품질을 먼저 보셔야 합니다.

주소 충돌을 모른 채 센서만 추가하면 원인을 놓칩니다

같은 주소 센서 두 개는 한 버스에서 싸웁니다

온습도 센서, 조도 센서, OLED, 가속도 센서처럼 I2C 장치를 하나씩 붙일 때는 문제가 없다가 두세 개를 동시에 연결하면 갑자기 전체가 멈추는 경우가 있습니다. 이때는 I2C 주소 충돌 가능성을 반드시 확인해야 합니다. 같은 주소를 가진 장치가 같은 버스에 있으면 마스터 입장에서는 누가 응답했는지 구분할 수 없습니다.

특히 같은 모델 센서를 여러 개 쓰는 프로젝트에서 이 문제가 자주 생깁니다. 예를 들어 같은 온도 센서를 여러 위치에 배치하고 싶을 때, 센서가 주소 변경 핀을 제공하지 않으면 단순 병렬 연결로는 해결되지 않습니다. 이 경우에는 멀티플렉서, 별도 버스, 소프트웨어 I2C 같은 구조를 검토해야 합니다.

  • 하지 말아야 할 실수: 센서 사양서의 기본 주소를 확인하지 않고 같은 모듈을 여러 개 사는 것
  • 확인 방법: I2C 스캐너로 연결 전후 주소 변화를 기록하는 것
  • 대안: TCA9548A 같은 I2C 멀티플렉서 사용, 주소 핀 설정, 버스 분리

주소 스캔 결과도 기록해야 비교가 됩니다

현장에서는 “어제는 됐는데 오늘은 안 된다”는 말이 자주 나옵니다. 이때 연결 순서, 전원 공급 방식, 스캔 주소 결과를 기록해두지 않으면 문제를 재현하기 어렵습니다. 간단히라도 표 형태로 남겨두면 불량 센서인지, 주소 충돌인지, 배선 문제인지 빠르게 좁힐 수 있습니다.

예를 들어 센서 A만 연결했을 때 0x40, 센서 B만 연결했을 때도 0x40이라면 둘을 같은 버스에 바로 붙이면 안 됩니다. 반대로 A는 0x40, B는 0x76인데 둘을 붙이면 사라진다면 주소가 아니라 전원, 풀업, 배선 길이를 의심해야 합니다.

간단 기록 예시: 단독 연결 주소, 동시 연결 주소, 전원 전압, 점퍼선 길이, 사용 보드, 라이브러리 버전을 함께 적어두면 나중에 같은 문제가 반복될 때 시간을 크게 줄일 수 있습니다.

전압 레벨을 대충 맞추면 보드와 센서를 같이 망칠 수 있습니다

3.3V와 5V를 같은 논리로 보면 위험합니다

아두이노 UNO 계열은 5V 논리를 쓰는 경우가 많고, 라즈베리파이는 3.3V 논리를 기준으로 합니다. 문제는 I2C 센서 모듈이 3.3V 전용인지, 5V 입력을 견디는지, 레벨 시프터가 포함되어 있는지 제품마다 다르다는 점입니다. “전원이 들어오니 괜찮다”는 판단은 가장 위험한 판단 중 하나입니다.

3.3V 전용 센서의 SDA/SCL에 5V 풀업이 걸리면 당장 고장 나지 않아도 장기 신뢰성이 떨어질 수 있습니다. 반대로 5V 보드와 3.3V 센서를 섞을 때 레벨 변환이 없으면 통신이 되는 듯하다가 온도, 케이블, 부하 변화에 따라 실패할 수 있습니다.

  • 하지 말아야 할 실수: VCC만 3.3V에 꽂고 SDA/SCL 풀업 전압은 확인하지 않는 것
  • 확인할 항목: 센서 데이터시트의 VDD, VIH, VIL, absolute maximum rating
  • 권장 방식: 3.3V 시스템은 전체 버스를 3.3V 기준으로 맞추고 필요한 경우 레벨 시프터를 사용

라즈베리파이는 특히 보호 관점으로 접근해야 합니다

라즈베리파이 GPIO는 5V tolerant가 아니므로 5V 신호를 직접 넣는 구성을 피해야 합니다. 인터넷 예제에서 누군가 성공했다고 해서 같은 회로가 안전하다는 뜻은 아닙니다. 판매 페이지에 “아두이노 호환”이라고 적힌 모듈도 라즈베리파이에 그대로 안전하다고 볼 수 없습니다.

임베디드 개발에서는 보드 지원 환경과 드라이버 구조도 함께 봐야 합니다. 디바이스가 운영체제와 어떻게 연결되는지 큰 흐름을 이해하려면 디바이스 드라이버 통합개발환경의 개요 같은 자료를 참고해보면, 단순 배선 이후에 소프트웨어 계층이 왜 중요한지도 감이 잡힙니다.

전압 레벨은 “통신이 되느냐”가 아니라 “반복 사용해도 안전하냐”로 판단해야 합니다.

긴 배선과 빠른 속도를 동시에 욕심내면 데이터가 깨집니다

I2C는 보드 안쪽 통신에 가까운 버스입니다

I2C 통신은 간단하고 편하지만 원래 긴 거리 통신을 위해 만들어진 방식은 아닙니다. 책상 위 10cm 점퍼선에서는 잘 되던 센서가 케이스 조립 후 50cm 이상 떨어지면 갑자기 튀는 이유가 여기에 있습니다. 선이 길어질수록 정전용량이 늘고, 신호 상승이 늦어지며, 주변 노이즈 영향을 더 받습니다.

실패 사례 중에는 센서를 멀리 빼야 한다는 이유로 SDA/SCL을 그대로 연장한 뒤, 코드에서 통신 속도만 낮춰 해결하려는 경우가 많습니다. 속도를 낮추는 것은 도움이 될 수 있지만 근본 해결이 아닐 수 있습니다. 배선 구조, 실드, 접지, 풀업 값, 대체 통신 방식까지 같이 봐야 합니다.

  • 하지 말아야 할 실수: 점퍼선을 길게 이어 붙이고 제품 배선처럼 쓰는 것
  • 위험한 상황: 모터, 릴레이, 전원 어댑터, 긴 LED 배선 옆으로 I2C 선을 나란히 두는 것
  • 현실적 대안: 센서 근처에 작은 MCU를 두고 UART, RS-485, CAN, 무선으로 상위 보드와 통신

속도는 낮추되 원인을 숨기면 안 됩니다

100kHz에서 불안정한 회로를 50kHz로 낮추면 당장은 나아질 수 있습니다. 하지만 이것이 배선 불량을 덮는 조치라면 나중에 온도 변화, 전원 노이즈, 케이스 조립 상태에서 다시 문제가 나옵니다. 개발 단계에서는 일부러 케이블을 흔들고, 전원을 껐다 켜고, 센서 여러 개를 동시에 읽는 식으로 실패 조건을 만들어보는 것이 좋습니다.

사물인터넷 프로젝트에서는 센서 데이터가 서버로 올라간 뒤에야 이상치를 발견하는 일이 많습니다. 라이프로그처럼 기기에서 수집되는 데이터의 흐름을 생각하면, 센서 단계의 작은 오류가 전체 서비스 품질에 영향을 줍니다. 데이터 수집 개념은 라이프로그 서비스 설명에서도 확인할 수 있는데, 결국 시작점의 측정값이 흔들리면 뒤쪽 분석도 흔들립니다.

따라서 “읽히긴 한다”는 상태에서 멈추지 말고, 최소한 1시간 이상 연속 로그를 남겨 이상치 비율을 확인해보세요. 센서값이 간헐적으로 0으로 떨어지거나 같은 값에 고정된다면 통신 실패를 정상값처럼 처리하고 있을 가능성이 있습니다.

라이브러리 예제를 그대로 제품 코드에 넣으면 장애 대응이 늦어집니다

예제 코드는 성공 경로만 보여주는 경우가 많습니다

많은 센서 라이브러리 예제는 초기화하고, 값을 읽고, 시리얼 모니터에 출력하는 흐름으로 되어 있습니다. 학습에는 충분하지만 실제 프로젝트에서는 실패했을 때 어떻게 다시 연결할지, 값이 비정상일 때 어떻게 버릴지, 통신이 멈췄을 때 시스템을 어떻게 회복시킬지가 더 중요합니다.

특히 I2C 버스가 한 번 꼬이면 특정 장치가 SDA를 붙잡고 있는 상태가 될 수 있습니다. 이때 단순히 loop 안에서 read만 반복하면 시스템 전체가 멈춘 것처럼 보입니다. 임베디드 개발에서는 타임아웃, 재시도, 버스 복구, 오류 로그를 처음부터 넣는 편이 안전합니다.

  1. 센서 초기화 실패 시 재시도 횟수를 제한합니다.
  2. 읽기 실패 값을 정상 데이터와 구분해 저장합니다.
  3. 연속 실패 횟수가 일정 기준을 넘으면 센서 전원 재인가 또는 버스 재초기화를 수행합니다.
  4. 실패 시각, 주소, 에러 코드를 로그로 남깁니다.

정상값 필터링도 통신 설계의 일부입니다

예를 들어 온도 센서가 실내에서 갑자기 -40도나 125도를 반환한다면 실제 환경 변화보다 통신 오류일 가능성이 큽니다. 조도 센서가 한 번씩 최대값으로 튀거나, 압력 센서가 같은 값을 계속 반복하는 경우도 마찬가지입니다. 이런 값은 서버로 보내기 전에 장치 쪽에서 1차 필터링해야 합니다.

다만 필터링을 너무 세게 걸면 실제 이벤트를 놓칠 수 있습니다. 그래서 단순히 이상값을 삭제하기보다 “측정 실패”, “범위 초과”, “이전값 유지”처럼 상태를 분리해 기록하는 방식이 좋습니다. 이렇게 해두면 나중에 센서 불량인지, 통신 불안정인지, 환경 변화인지 구분할 수 있습니다.

제품 코드에서 가장 피해야 할 방식은 실패를 조용히 무시하는 것입니다. 겉으로는 대시보드가 깔끔해 보이지만, 실제로는 센서가 멈춘 상태를 정상 상태처럼 표시할 수 있습니다. 사용자는 값이 맞다고 믿고 행동하기 때문에 작은 회로 실수가 운영 문제로 커질 수 있습니다.

판단 순서를 바꾸면 I2C 통신 실패가 훨씬 빨리 잡힙니다

비싼 장비보다 우선순위가 먼저입니다

I2C 통신 문제를 해결할 때 처음부터 오실로스코프를 꺼내야 하는 것은 아닙니다. 물론 파형을 보면 빠르지만, 대부분의 실수는 순서를 바꾸는 것만으로도 잡힙니다. 코드 수정 전에 전원, GND, 풀업, 주소, 전압 레벨, 배선 길이를 차례대로 확인하면 삽질 시간이 크게 줄어듭니다.

우선순위는 단순해야 합니다. 첫째, 센서에 맞는 전압이 들어가는지 봅니다. 둘째, GND가 공통인지 확인합니다. 셋째, SDA/SCL이 바뀌지 않았는지 봅니다. 넷째, 풀업 저항과 주소 충돌을 확인합니다. 다섯째, 그 다음에 라이브러리와 코드 흐름을 봅니다. 이 순서를 지키면 문제를 감으로 찍지 않게 됩니다.

  • 1순위: 전원 전압과 GND 공통 확인
  • 2순위: SDA/SCL 배선 방향과 접촉 상태 확인
  • 3순위: 풀업 저항 존재 여부와 합성 저항 확인
  • 4순위: I2C 주소 스캔과 주소 충돌 여부 기록
  • 5순위: 전압 레벨 변환, 배선 길이, 노이즈 환경 점검
  • 6순위: 라이브러리 버전, 타임아웃, 예외 처리 코드 수정

하지 말아야 할 일을 정하면 설계가 단단해집니다

센서 연결에서 가장 위험한 습관은 “일단 꽂아보고 되면 넘어가는 것”입니다. 개인 실습에서는 괜찮아 보여도, 실제 사물인터넷 장치나 임베디드 프로젝트에서는 설치 위치와 사용 시간이 길어질수록 약한 부분이 드러납니다. 특히 전원과 통신선이 함께 지나가는 구조, 센서가 여러 개인 구조, 라즈베리파이와 5V 모듈을 섞는 구조에서는 처음부터 보수적으로 설계하는 편이 낫습니다.

마지막으로 우선순위를 다시 세우면 답은 분명합니다. I2C 통신이 흔들릴 때는 코드보다 전기적 조건을 먼저 검증하고, 센서 추가 전에는 주소와 전압을 먼저 확인해야 합니다. 그 다음에 속도 조절과 예외 처리 코드를 붙이면 실패 원인을 숨기지 않고 줄일 수 있습니다. 이 순서만 지켜도 아두이노, 라즈베리파이, 센서 연결 프로젝트에서 반복되는 통신 장애의 절반 이상은 훨씬 이른 단계에서 잡힙니다.

I2C 통신은 풀업 저항을 빼면 반드시 흔들린다

댓글목록

등록된 댓글이 없습니다.