같은 주소 I2C 센서 여러 개, TCA9548A로 해결될까?

profile_image
작성자 버스탐험가준서
댓글 0건 조회 8회

같은 모델의 I2C 센서 두 개를 아두이노에 연결했더니 하나만 잡히거나 값이 뒤섞였습니다. 배선을 다시 확인하고 풀업 저항도 바꿨지만 원인은 단순했습니다. 두 센서가 똑같은 주소로 응답하고 있었던 것입니다.

주소 변경 핀이 없는 센서라면 TCA9548A I2C 멀티플렉서가 꽤 현실적인 해법입니다. 저는 거리 센서와 환경 센서를 여러 개 연결하는 과정에서 이 모듈을 직접 사용했고, 편해진 점뿐 아니라 예상 밖의 불편도 경험했습니다.

I2C 스캔에는 하나만 보이는데 센서는 둘 다 살아 있었다

처음 겪은 주소 충돌 증상

테스트에 사용한 센서 두 개는 모두 기본 I2C 주소가 같았습니다. 각각 따로 연결하면 측정값이 정상인데 병렬로 묶는 순간 초기화가 불규칙하게 실패했습니다. 운 좋게 실행되더라도 어느 센서에서 읽은 값인지 구분할 방법이 없었습니다.

I2C는 SDA와 SCL 선을 여러 장치가 공유하지만, 마스터는 주소로 통신 대상을 선택합니다. 따라서 주소가 같은 슬레이브 두 개가 동시에 응답하면 소프트웨어만으로 둘을 구별하기 어렵습니다. 장치가 고장 난 것처럼 보여도 실제로는 주소 충돌일 수 있습니다.

  • 센서를 하나씩 연결하면 각각 정상 작동합니다.
  • 두 개를 동시에 연결하면 초기화 실패나 타임아웃이 발생합니다.
  • I2C 스캐너에는 동일한 주소 하나만 표시됩니다.
  • 센서 라이브러리가 장치별 주소 변경 기능을 제공하지 않습니다.

아두이노 자체가 낯설다면 아두이노의 기본 개념과 활용 범위를 먼저 확인하면 보드, 스케치, 센서 라이브러리의 관계를 이해하기 쉽습니다. 제 경우에도 센서 코드를 의심하기 전에 스캐너로 주소부터 확인했더라면 시간을 훨씬 덜 썼을 것입니다.

TCA9548A를 넣자 통신 경로가 어떻게 달라졌을까

주소를 바꾸는 대신 버스를 나누는 방식

TCA9548A는 센서의 주소를 변환해 주는 부품이 아닙니다. 마스터 쪽 I2C 버스를 최대 8개의 채널로 나누고, 그중 통신할 채널을 선택해 연결하는 스위치에 가깝습니다. 같은 주소의 센서를 서로 다른 채널에 배치하면 동시에 버스에 나타나지 않으므로 충돌을 피할 수 있습니다.

제가 사용한 보드에는 입력 측 SDA·SCL과 채널별 SD0·SC0부터 SD7·SC7까지가 표시돼 있었습니다. 아두이노는 멀티플렉서의 주소로 채널 번호를 먼저 지정한 뒤, 평소와 같은 센서 주소로 데이터를 요청합니다. 기존 센서 라이브러리를 대대적으로 수정하지 않아도 된다는 점이 가장 마음에 들었습니다.

  1. 아두이노의 SDA와 SCL을 TCA9548A 입력 단자에 연결합니다.
  2. 첫 번째 센서를 채널 0, 두 번째 센서를 채널 1에 배선합니다.
  3. 사용할 채널을 선택하는 함수부터 호출합니다.
  4. 해당 채널의 센서 초기화 또는 측정 함수를 실행합니다.
  5. 다른 센서를 읽기 전 채널을 다시 선택합니다.
사용 팁: 채널 선택은 한 번만 해 두는 설정이 아닙니다. 코드 흐름 중 다른 채널을 사용했다면 센서를 읽을 때마다 원하는 채널을 명시하는 편이 안전합니다.

처음에는 채널마다 별도의 센서 객체가 반드시 필요하다고 생각했지만 라이브러리 구조에 따라 하나의 객체를 재사용할 수도 있었습니다. 다만 센서별 보정값이나 내부 상태를 보관하는 라이브러리라면 객체를 분리해야 값이 섞이지 않았습니다.

직접 배선할 때 가장 오래 붙잡았던 세 가지 실수

전압, 풀업 저항, 공통 접지 확인

멀티플렉서를 연결했다고 해서 전기적인 문제가 사라지는 것은 아니었습니다. 제가 처음 사용한 모듈에는 풀업 저항이 이미 실장돼 있었고 센서 모듈에도 각각 풀업이 붙어 있었습니다. 여러 채널을 동시에 활성화하자 전체 풀업 저항값이 지나치게 낮아져 신호 파형이 깔끔하지 않았습니다.

또 하나는 전압입니다. TCA9548A 칩과 판매되는 완제품 모듈의 허용 조건은 구분해서 봐야 합니다. 보드에 레귤레이터나 레벨 변환 회로가 있는지, 풀업 저항이 어느 전압에 연결됐는지를 회로도로 확인해야 합니다. 3.3V 센서에 5V 풀업이 걸리는 구성은 센서 손상 위험이 있으므로 막연히 호환된다고 판단하면 곤란합니다.

  • 공통 접지: 마스터, 멀티플렉서, 외부 전원 센서의 GND를 함께 연결했습니다.
  • 전원 전압: 각 센서의 데이터시트와 모듈 회로도를 따로 확인했습니다.
  • 풀업 구성: 보드와 센서에 실장된 저항을 합산해 과도한 병렬 연결을 피했습니다.
  • 배선 길이: 브레드보드 점퍼선을 짧게 하고 SDA와 SCL을 전원선에서 떨어뜨렸습니다.
  • 채널 표기: 케이블 양쪽에 채널 번호 라벨을 붙였습니다.

제 작업대에서는 선을 짧게 줄인 것만으로 간헐적인 NACK가 크게 감소했습니다. 특히 여러 센서 케이블을 한 다발로 묶었을 때보다 채널별로 정돈했을 때 재현성이 좋아졌습니다. 독자님의 회로도 손으로 센서를 건드릴 때만 값이 튄다면 코드보다 커넥터와 접지를 먼저 의심해 볼 만합니다.

아두이노 코드에는 채널 선택 한 줄이 더 필요했다

반복문으로 센서를 순서대로 읽은 후기

구현은 예상보다 단순했습니다. Wire 라이브러리로 TCA9548A 주소에 접근해 1바이트를 보내는데, 선택하려는 채널의 비트만 1로 설정하면 됩니다. 예를 들어 채널 0은 1, 채널 1은 2, 채널 2는 4에 해당합니다. 채널 번호를 그대로 전송하는 실수는 초기에 제가 실제로 했던 실수입니다.

채널 선택 함수를 만든 뒤에는 센서 배열을 순회하며 선택, 측정, 결과 저장 순서로 처리했습니다. 이 방식은 센서 수가 늘어날 때 복사한 코드를 줄여 줬습니다. 다만 센서가 측정을 시작한 뒤 결과가 준비될 때까지 기다려야 한다면 모든 장치를 단순히 순차 처리하는 구조는 느려질 수 있습니다.

  1. Wire.begin()으로 마스터의 I2C 통신을 시작합니다.
  2. TCA9548A 주소로 전송을 시작하고 1 << channel 값을 보냅니다.
  3. 전송 성공 여부를 확인한 후 센서 라이브러리를 호출합니다.
  4. 센서 ID와 채널 번호를 함께 기록해 데이터 출처를 보존합니다.
  5. 실패 시 무한 재시도하지 말고 오류 횟수와 채널을 출력합니다.

아두이노의 하드웨어와 소프트웨어 구성이 궁금할 때는 아두이노 플랫폼 설명도 참고할 수 있습니다. 실제 프로젝트에서는 예제 코드가 실행되는지만 보는 것보다 Wire 전송의 반환값을 시리얼 모니터에 남기는 습관이 훨씬 유용했습니다.

디버깅 팁: 시작할 때 전체 채널을 차례로 선택해 채널별 I2C 스캔 결과를 출력하면 잘못 꽂은 센서와 끊어진 케이블을 빠르게 찾을 수 있습니다.

써 보니 편했지만 모든 프로젝트의 답은 아니었다

장점이 크게 느껴진 상황

가장 큰 장점은 동일 주소 센서를 여러 개 사용할 수 있다는 점입니다. 센서의 주소 핀을 제어하려고 별도의 GPIO를 소비하거나 전원을 순서대로 켜는 복잡한 초기화도 필요하지 않았습니다. 프로토타입 단계에서는 채널만 바꿔 센서를 추가할 수 있어 회로 수정 시간이 눈에 띄게 줄었습니다.

반면 통신 경로에 부품이 하나 더 들어가므로 코드와 배선의 고장 지점도 늘어납니다. 멀티플렉서 자체 주소가 기존 장치와 충돌할 가능성을 확인해야 하고, 채널을 바꾸는 I2C 전송도 매번 추가됩니다. 아주 빠른 샘플링이나 엄격한 실시간성이 필요한 장치에서는 이 작은 지연도 측정해 봐야 합니다.

  • 잘 맞는 경우: 주소가 고정된 동일 센서를 여러 개 연결할 때
  • 편리한 경우: 채널별로 센서 묶음을 분리해 점검하고 싶을 때
  • 아쉬운 경우: 고속으로 여러 센서를 거의 동시에 읽어야 할 때
  • 주의할 경우: 케이블이 길거나 노이즈가 심한 산업 환경
  • 다른 방법이 나은 경우: 센서의 주소 변경 핀이나 명령을 간단히 사용할 수 있을 때

가격은 판매처, 기판 품질, 커넥터 포함 여부에 따라 차이가 컸습니다. 저가형 호환 모듈은 시험용으로 부담이 적었지만 납땜 상태와 주소 설정 패드 표기가 일정하지 않았습니다. 장기간 운용할 장치라면 단순 최저가보다 회로도 제공 여부, 전압 구성, 커넥터 고정 방식을 기준으로 선택하는 편이 낫습니다.

센서 값이 가끔 멈출 때 제가 확인한 순서

무작정 부품을 교체하기 전 재현 조건 만들기

실사용 중 가장 곤란했던 문제는 수 시간에 한 번 특정 채널만 멈추는 현상이었습니다. 처음에는 멀티플렉서 불량으로 생각했지만, 로그를 남겨 보니 긴 케이블을 사용한 채널에서 센서 전원이 흔들릴 때 문제가 시작됐습니다. 채널 선택 성공과 센서 응답 성공을 따로 기록한 것이 원인 분리에 도움이 됐습니다.

문제가 생기면 저는 마스터에서 가까운 부분부터 단계적으로 확인했습니다. 먼저 TCA9548A 자체 주소가 스캔되는지 보고, 그다음 각 채널을 하나씩 활성화해 센서 주소를 찾았습니다. 모든 채널을 한꺼번에 켠 상태에서 검사하면 동일 주소 센서가 다시 충돌할 수 있으므로 진단 중에도 한 채널씩 선택해야 합니다.

  1. 멀티플렉서를 제외한 마스터 단독 I2C 동작을 확인합니다.
  2. 센서를 떼고 TCA9548A 주소와 전원 전압을 측정합니다.
  3. 채널 0부터 하나씩 스캔해 주소 목록을 기록합니다.
  4. 오류 채널의 센서를 정상 채널과 바꿔 꽂아 증상이 이동하는지 봅니다.
  5. 센서가 따라가면 센서나 케이블, 채널에 남으면 보드와 배선을 의심합니다.
  6. 동작 시간을 늘려 NACK 횟수와 재시작 발생 시점을 기록합니다.

버스 복구 코드도 도움이 됐지만 근본적인 전원 문제를 감추는 용도로 사용해서는 안 됐습니다. 재초기화로 잠시 살아난다는 이유만으로 제품에 넣으면 현장에서 같은 문제가 반복됩니다. 저는 오류가 일정 횟수를 넘으면 해당 채널만 비활성화하고 다른 센서의 측정은 계속하도록 처리했습니다.

센서와 라이브러리가 바뀌면 다시 확인해야 할 조건

부품 교체 뒤에도 같은 코드가 통할지는 별개다

TCA9548A를 한 번 안정화했다고 해서 이후 구성이 계속 동일하게 작동하는 것은 아니었습니다. 같은 이름으로 판매되는 센서 모듈도 기판 개정에 따라 풀업 저항과 레귤레이터가 달라질 수 있습니다. 센서 라이브러리 업데이트로 초기화 순서나 내부 대기 시간이 변하면 기존 반복문의 측정 간격도 다시 조정해야 합니다.

아두이노에서 라즈베리파이 또는 다른 마이크로컨트롤러로 마스터를 교체할 때도 기본 I2C 전압, 버스 번호, 클록 설정을 확인해야 합니다. 운영체제가 있는 보드는 프로세스가 동시에 같은 버스를 사용할 가능성도 있으므로 애플리케이션 수준의 접근 순서를 관리해야 합니다. 회로가 같아 보여도 실행 환경까지 같은 것은 아닙니다.

  • 구매한 모듈의 칩 마킹과 회로도 버전을 보관합니다.
  • 센서 및 통신 라이브러리 버전을 소스와 함께 기록합니다.
  • 보드 교체 후 채널별 스캔 결과를 기준 데이터와 비교합니다.
  • I2C 클록을 높이기 전 가장 긴 케이블 채널부터 장시간 시험합니다.
  • 부품 단종이나 대체품 적용 시 풀업 전압과 주소 설정을 재검토합니다.

제가 남겨 둔 기록 중 가장 유용했던 것은 채널 번호, 센서 모델, I2C 주소, 전원 전압, 라이브러리 버전을 한 줄로 묶은 표였습니다. 이후 센서 하나가 신형 모듈로 교체됐을 때 무엇이 달라졌는지 바로 찾을 수 있었습니다. 모듈 사양과 라이브러리 동작은 시간이 지나며 바뀔 수 있으므로, 새로 구매하거나 업데이트한 시점에는 제조사 자료를 기준으로 전압과 초기화 절차를 다시 검증하는 것이 안전합니다.

같은 주소 I2C 센서 여러 개, TCA9548A로 해결될까?

댓글목록

등록된 댓글이 없습니다.