새로운 GPIO 확장 모듈 강자, MCP23017

왜 MCP23017이 GPIO 확장의 “새로운 강자”인가?

PCF8575가 **’가성비와 간편함’**으로 승부했다면, MCP23017은 **’정밀 제어와 압도적 확장성’**으로 중무장한 모듈입니다.

1. “저항 16개를 아껴주는 마법” (내부 풀업)

가장 큰 강점은 소프트웨어 설정만으로 내부 풀업 저항을 켤 수 있다는 점입니다. 16개의 버튼을 연결할 때 일일이 저항을 납땜할 필요가 없어, 회로 설계 시간을 획기적으로 줄여줍니다.

2. “I2C 핀 2개로 128개 제어” (주소 설정)

$A0, A1, A2$ 주소 핀을 조합하면 한 회로에 최대 8개의 MCP23017을 병렬로 물릴 수 있습니다. 이는 곧 단 2개의 핀으로 128개의 입출력을 다스릴 수 있다는 뜻입니다. 88건반 피아노를 만들고도 40개의 핀이 남는 압도적인 성능이죠.

3. “0.001초의 차이를 읽어내는 인터럽트”

단순히 핀이 많은 게 다가 아닙니다. 어떤 핀에 신호가 들어왔는지 MCU(ESP32 등)에 즉시 알려주는 인터럽트 기능이 강력하여, 전자 피아노의 건반 강약(Velocity)처럼 정밀한 시간 측정이 필요한 프로젝트에 최적화되어 있습니다.

“PCF8575가 단순히 핀을 늘려주는 ‘멀티탭’이라면, MCP23017은 각 포트의 전압과 신호를 정밀하게 관리하는 ‘스마트 배전반’과 같습니다.”

** GPIC 확장 모듈 MCP23017 을 테스트 하면서 먼저 막히는 부분이였던게 scl , sda , vdd, gnd 4개 만 연결해도 코드는 작동되어야 하지 않나 였습니다.

이론적으로는 SDA, SCL, VDD, GND 4개만 연결해도 통신은 되어야 할 것 같지만, MCP23017은 좀 까다로운 녀석이라 꼭 추가로 연결해줘야 하는 핀들이 있습니다.

이걸 안 하면 I2C 스캔조차 안 되거나, 주소가 지멋대로 변해서 코드가 작동하지 않습니다.


🛠️ 4개 외에 ‘반드시’ 추가 연결해야 할 핀

1. 주소 설정 핀 (A0, A1, A2) → 모두 GND로!

이 핀들을 공중에 띄워두면(Floating), 칩이 자기 주소를 결정하지 못하고 계속 흔들립니다.

  • 해결법: A0, A1, A2 핀 3개를 모두 GND에 연결하세요.
  • 이렇게 해야 주소가 확실하게 **0x20**으로 고정되어 제가 짜드린 코드가 작동합니다.

2. 리셋 핀 (RESET) → VDD(3.3V)로!

리셋 핀은 ‘Low(GND)’일 때 칩을 초기화합니다. 이 핀을 그냥 두면 칩이 지멋대로 리셋 상태에 빠져서 응답을 안 할 수 있습니다.

  • 해결법: **RESET 핀(18번 핀)을 VDD(3.3V)**에 연결해서 “나 지금 리셋 안 할 거야”라고 신호를 줘야 합니다.

📋 최종 체크리스트 (총 9개 연결)

브레드보드에서 아래 핀들이 다 꽂혀 있는지 확인해보세요!

  1. VDD: 3.3V
  2. VSS(GND): GND
  3. SCL: ESP32-C3의 1번 핀
  4. SDA: ESP32-C3의 2번 핀
  5. A0: GND (주소 결정)
  6. A1: GND (주소 결정)
  7. A2: GND (주소 결정)
  8. RESET: 3.3V (작동 대기)
  9. GND(공통): ESP32의 GND와 MCP23017의 GND가 서로 연결되어 있는지 확인!

PCF8575는 주소 핀에 기본 풀다운이 되어 있는 경우가 많아 대충 4개만 꽂아도 돌아갔을 수 있지만, MCP23017은 정석대로 주소와 리셋을 잡아줘야 합니다.

특히 A0~A2를 GND에 안 꽂으면 I2C 스캔할 때마다 주소가 0x20이었다가 0x27이었다가 춤을 출 거예요. ㅋ

지금 A0, A1, A2랑 RESET 핀 연결하셨나요? 요거 딱 연결하는 순간 i2c.scan() 결과에 0x20이 예쁘게 찍힐 겁니다! 😊🚀

MCP23017은 아두이노나 라즈베리 파이 같은 마이크로컨트롤러의 부족한 I/O 핀을 확장해주는 아주 고마운 칩입니다. 17HS4401 스텝모터나 여러 부품을 제어하다 보면 핀이 모자랄 때가 많은데, 이때 이 칩 하나로 I2C 통신을 통해 핀 16개를 추가할 수 있습니다.

1. 주요 특징 (왜 쓸까?)

  • 16비트 확장: 핀 16개를 입력 또는 출력으로 사용할 수 있습니다. (8개씩 A포트, B포트로 나뉩니다.)
  • I2C 통신: 단 2개의 선(SDA, SCL)만 있으면 됩니다.
  • 주소 설정 가능: 주소 핀(A0, A1, A2)을 조절해 한 회로에 최대 8개까지 연결할 수 있습니다. (즉, 핀 16×8=128개 확장 가능!)
  • 인터럽트 기능: 핀 상태가 변했을 때 MCU에 바로 알려주는 기능이 있어 효율적입니다.

2. 핀 구성 (Pinout)

칩을 보시면 총 28개의 핀이 있는데, 가장 중요한 것만 기억하세요.

  • VDD / VSS: 전원 (+5V 또는 +3.3V) 및 그라운드(GND)
  • GP A0 ~ A7 / GP B0 ~ B7: 우리가 실제로 제어할 16개의 확장 핀
  • SCL / SDA: I2C 통신 핀 (아두이노의 경우 A5, A4 등에 연결)
  • RESET: 칩 초기화 (보통 전원에 연결해둡니다)
  • A0, A1, A2: 칩의 고유 주소를 정하는 핀 (모두 GND에 연결하면 기본 주소 0x20)

MCP23017 vs PCF8575 비교표

항목PCF8575 (간편함)MCP23017 (고성능)
I/O 핀 수16개16개 (Port A/B로 구분)
인터럽트기본 지원 (INT 하나)강력함 (포트별/핀별 설정 가능)
풀업 저항내부 고정 (약함)내부 풀업 소프트웨어 설정 가능
통신 속도최대 400kHz최대 1.7MHz (High Speed 모드)
출력 방식Quasi-bidirectional (전류 약함)Totem-pole (전류 강함)
설정 레지스터없음 (데이터만 보냄)20개 이상의 설정 레지스터 존재
동작 전압2.5V ~ 5.5V1.8V ~ 5.5V

1. 출력 능력과 제어 방식 (핵심 차이)

  • PCF8575: 핀 하나하나를 ‘입력’인지 ‘출력’인지 따로 선언할 필요가 없습니다. 그냥 쓰면 됩니다. 하지만 핀에서 전류를 밀어내는 힘(Source)이 거의 없어 LED를 켤 때 반드시 Sink 방식을 써야 합니다.
  • MCP23017: IODIR 레지스터를 통해 각 핀을 입력/출력으로 명확히 정해줘야 합니다. 대신 Push-Pull(Totem-pole) 구조라 전류 제어 능력이 훨씬 안정적이고 강력합니다.

2. 인터럽트(Interrupt)의 디테일

  • PCF8575: 어떤 핀이든 상태가 변하면 신호를 보내지만, ‘어느 핀’이 변했는지는 직접 읽어서 확인해야 합니다.
  • MCP23017: 특정 핀이 변했을 때만 인터럽트를 걸거나, 이전 값과 비교해서 변했을 때 등 아주 상세하게 조건을 걸 수 있습니다. 버튼 입력을 많이 받을 때 MCU의 부담을 확 줄여줍니다.

3. 내부 풀업 저항 유무

  • PCF8575: 내부 풀업이 매우 약해서 버튼 입력 시 외부 저항이 필요한 경우가 많습니다.
  • MCP23017: 소프트웨어 코드(GPPU 레지스터) 한 줄로 100kΩ 내부 풀업을 켤 수 있습니다. 부품 하나라도 아껴야 하는 ‘기술 방어’ 상황에서 최고죠.

** A0, A1, A2 사용법

MCP23017의 A0, A1, A2 핀은 이 칩의 **”주소(Address) 이름표”**를 결정하는 핀입니다. I2C 통신은 한 라인에 여러 개의 칩을 달 수 있기 때문에, 각 칩마다 고유한 주소가 있어야 하는데 이걸 하드웨어적으로 정해주는 역할을 합니다.


1. 핀 설정에 따른 I2C 주소 변화

MCP23017의 기본 주소는 이진수로 0100[A2][A1][A0]입니다. 핀을 **VCC(3.3V)**에 연결하면 1, GND에 연결하면 0이 됩니다.

A2 연결A1 연결A0 연결16진수 주소 (Hex)10진수 주소 (Dec)
GNDGNDGND0x2032 (가장 기본)
GNDGND3.3V0x2133
GND3.3VGND0x2234
3.3V3.3V3.3V0x2739

⚠️ 주의: 이 핀들을 아무 데도 연결하지 않고 공중에 띄워두면(Floating), 주변 노이즈에 따라 주소가 0x20이었다가 0x27이었다가 멋대로 변합니다. 그래서 반드시 GND나 VCC 중 한 곳에 고정해야 합니다.

2. 왜 이게 필요할까?

LED 32개를 제어하고 싶다면, MCP23017 칩 2개를 준비한 뒤 이렇게 하면 됩니다.

  1. 1번 칩: A0, A1, A2를 모두 GND에 연결 → 주소 0x20
  2. 2번 칩: A0만 3.3V에 연결, 나머지는 GND → 주소 0x21
  3. 코드: I2C(0x20)에 명령 보내고, 이어서 I2C(0x21)에 명령 보내면 끝!

3. 배선과 LED 테스트

붉은 부분 A0,A1,A2 3핀이 I2C 주소 지정부 0x20~0x27
노란 점퍼는 Reset 핀 HIGH 로 해놔야 노이즈로 인한 재부팅이 방지 됩니다.

python mcp23017.py : A_set_pin(), B_set_pin()

from machine import Pin, I2C
import time

# 1. 연결 확인용 I2C 스캔
print("Scan 1 (SDA2, SCL1):", I2C(0, sda=Pin(2), scl=Pin(1)).scan())

# 2. I2C 및 주소 설정
i2c = I2C(0, sda=Pin(2), scl=Pin(1), freq=400000)
ADDR = 0x20

# MCP23017 핵심 레지스터
IODIRA, IODIRB = 0x00, 0x01  # 입출력 방향 설정
GPIOA, GPIOB   = 0x12, 0x13  # 실제 출력 값 제어

# 각 포트 상태 저장 (초기값: 0xFF = 모두 OFF)
state_a, state_b = 0xFF, 0xFF
speed = 0.1

def setup():    
    try:
        # A, B 포트 모두 출력으로 설정    
        i2c.writeto_mem(ADDR, IODIRA, b'\x00')
        i2c.writeto_mem(ADDR, IODIRB, b'\x00')
        all_off()
        print("A & B 포트 준비 완료!")
    except Exception as e:
        print(f"Error: {e}")
        all_off()

def all_off():
    i2c.writeto_mem(ADDR, GPIOA, b'\xFF')
    i2c.writeto_mem(ADDR, GPIOB, b'\xFF')

def A_set_pin(no, state):
    global state_a
    if state == 0: state_a &= ~(1 << no)
    else: state_a |= (1 << no)
    i2c.writeto_mem(ADDR, GPIOA, bytes([state_a]))

def B_set_pin(no, state):
    global state_b
    if state == 0: state_b &= ~(1 << no)
    else: state_b |= (1 << no)
    i2c.writeto_mem(ADDR, GPIOB, bytes([state_b]))

# --- 포트 전용 핑퐁 로직 ---
def ping_pong_A():
    for i in range(8):
        A_set_pin(i, 0); time.sleep(speed); A_set_pin(i, 1)
    for i in range(6, -1, -1):
        A_set_pin(i, 0); time.sleep(speed); A_set_pin(i, 1)

def ping_pong_B():
    for i in range(8):
        B_set_pin(i, 0); time.sleep(speed); B_set_pin(i, 1)
    for i in range(6, -1, -1):
        B_set_pin(i, 0); time.sleep(speed); B_set_pin(i, 1)
        


setup()

while True:
    ping_pong_A()
    ping_pong_B()

◎ 제가 사용한 부품은 여기서 구매했습니다. 아래 링크를 통해 구매 시 소정의 수수료를 받습니다.
– TENSTAR 2개 MCP23017 시리얼 인터페이스 모듈 🔗 클릭 앤 구매: https://s.click.aliexpress.com/e/_c4PAltFd

코멘트

“새로운 GPIO 확장 모듈 강자, MCP23017” 에 하나의 답글

  1. micro2iot 아바타

    [구매정보] 블로그에서 사용한 부품 구매정보입니다.
    아래 링크를 통해 구매 시 소정의 수수료를 제공받으며, 채널 운영에 큰 도움이 됩니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다