오늘의 프로젝트는 폐하드드라이브 추출 모터 구동 테스트입니다. 결론부터 말씀드리면 ‘절반의 성공, 절반의 실패’입니다. L298N의 전압 강하와 스텝 신호의 한계 때문에 하드디스크 특유의 초고속 회전(7200RPM)을 구현하기엔 역부족이었습니다. 실패를 통해 배운 BLDC 모터의 특성을 공유합니다.
Python spin.py : Test code
BLDC vs Stepper: “스핀들 모터는 3상 BLDC 방식이라, 일반적인 H-브리지 드라이버로는 위상 제어가 정교하지 못하다.”
L298N의 한계: “L298N은 전압 강하(1.2V∼3V)가 커서 고속 모터에 전력을 밀어주기 힘들다.”
※ ESC 드라이버 원리
하드드라이브 스핀들 모터 테스트에서 왜 L298N이 실패했는지, 그 해답은 바로 **ESC(Electronic Speed Controller, 전자 변속기)**의 작동 원리에 있습니다.
스핀들 모터는 일반적인 모터와 달리 3상 BLDC(Brushless DC) 모터입니다. 이 모터를 돌리려면 단순히 전기를 주는 게 아니라, 아주 정교한 ‘타이밍’이 필요합니다.
1. ESC의 핵심 역할: “전자식 브러시”
일반 DC 모터는 내부에 물리적인 브러시가 있어 회전할 때 알아서 전극을 바꿔줍니다. 하지만 BLDC(Brushless) 모터는 이름 그대로 브러시가 없습니다. 대신 ESC가 3개의 선(U, V, W)에 번갈아 가며 전류를 흘려 가상의 회전 자기장을 만들어줍니다.
2. 작동 원리 (3상 제어)
ESC는 내부의 MCU와 MOSFET을 사용해 다음 과정을 초고속으로 수행합니다.
전류 스위칭: 3개의 코일에 120∘씩 위상차를 두고 전류를 공급합니다. (U→V, V→W, W→U 방식)
역기전력(Back-EMF) 감지: 모터가 돌 때 발생하는 미세한 전기를 감지하여, 현재 자석(로터)이 어디쯤 있는지 파악합니다. (센서리스 방식)
피드백 루프: 자석의 위치에 딱 맞춰서 다음 코일에 전기를 흘려줍니다. 이 타이밍이 어긋나면 모터가 덜덜거리기만 하고 돌지 않습니다.
3. 왜 L298N으로는 제 성능이 안 났을까?
‘제 속도가 안 나는 현상’의 기술적인 이유는 이렇습니다.
제어 방식의 한계: L298N은 단순히 전압을 줬다 뺐다 하는 H-브리지 방식입니다. 스핀들 모터처럼 수천 RPM으로 도는 모터의 ‘역기전력’을 계산해서 타이밍을 맞추는 기능이 없습니다.
스위칭 속도: HDD 모터는 7,200RPM 이상으로 돕니다. 이를 위해선 초당 수천 번 전극을 바꿔야 하는데, 일반적인 코딩(Soft PWM)이나 L298N의 반응 속도로는 이 속도를 따라갈 수 없습니다.
전압 강하: L298N 내부의 바이폴라 트랜지스터는 열로 에너지를 많이 소비하여, 모터에 충분한 전류를 전달하지 못합니다.
4. ESC를 쓰면 달라지는 점
만약 저가형 알리발 ESC(예: HW-30A 등)나 전용 BLDC 드라이버 칩을 사용하시면:
자동 타이밍: 모터의 회전 위치를 스스로 파악해 최적의 효율로 밀어줍니다.
고속 회전: 하드디스크 특유의 “키이이잉~” 하는 고주파 소리와 함께 초고속 회전을 볼 수 있습니다.
간편한 제어: 마이크로파이썬에서 PWM 신호(서보모터와 동일한 방식) 하나만 보내면 속도 조절이 끝납니다.
5. “L298N은 스핀들 모터의 ‘눈(역기전력 감지)’ 역할을 못 해주기 때문에 눈 감고 달리는 것과 같다”
※ pc팬에 있는 자기장 홀센서를 달아서 회전수를 측정해서 u,w,v 변환속도를 조절하게 하면 되지 않을까?
이론적으로는 맞지만 실제로 고급 BLDC 모터들은 **홀 센서(Hall Effect Sensor)**를 내부에 3개 달아서 자석의 위치를 정확히 파악하고 전기를 넣어줍니다. 이를 ‘센서드(Sensored) BLDC’ 방식이라고 합니다.
1. 왜 가능하지만 어려운가?
1) 속도의 장벽 (CPU의 한계) HDD 모터는 보통 7,200 RPM입니다. 초당 120바퀴를 돌죠.
3상 제어를 하려면 한 바퀴 돌 때 전극을 6번 바꿔줘야 합니다. (120×6=720번/초)
홀 센서 신호를 받아서(Interrupt), 계산하고, L298N에 신호를 쏘는 이 과정을 1.3ms(밀리초) 안에 완벽하게 끝내야 합니다.
마이크로파이썬은 인터프리터 방식이라 이 정도 속도로 실시간 피드백을 처리하면 타이밍이 조금만 어긋나도 모터가 “드르륵” 하며 멈춰버립니다.
2) 홀 센서 배치(정렬) 문제 PC 팬은 이미 센서가 최적의 위치에 고정되어 있지만, 하드디스크 모터는 센서가 없습니다.
홀 센서를 120∘ 간격으로 아주 정밀하게 배치해야 합니다. 1mm만 틀어져도 위상(Phase)이 꼬여서 효율이 떡락하거나 열만 발생합니다.
3) L298N의 느린 응답속도 L298N 내부의 소자(Bipolar Transistor)는 켜고 꺼지는 속도가 최신 MOSFET에 비해 느립니다. 고속 스위칭을 하려고 하면 신호가 뭉개져서 모터에 제대로 된 힘을 전달하지 못합니다.
※ 홀센서 3개나 달 필요없이 하나만 달아도 회전수는 나오니까 회전수에 비례해서 u,w,v 전환속도만 올려주면 되지 않을까?
1. 회전수만 알면 안 되는 이유: “타이밍(Phase)”
모터가 도는 속도를 알아서 그에 맞춰 전극 전환 속도($Hz$)를 올리는 건 가능합니다. 하지만 자석이 지금 어디 있는지 모르면 이런 상황이 발생합니다.
최악의 시나리오: 자석이 코일 앞에 딱 왔을 때 밀어줘야 하는데, 타이밍이 안 맞아서 자석을 뒤에서 잡아당기는 위치에서 전기를 주게 될 수도 있습니다.
결과: 모터가 회전력을 얻는 게 아니라, 서로 밀고 당기다가 진동만 커지고 열이 나면서 멈춰버립니다(탈조 현상).
2. 홀센서 1개의 한계
홀센서가 1개라면 “한 바퀴 도는 데 10ms 걸렸네?”라는 건 알 수 있지만, 지금 이 순간 자석이 U번 코일에 있는지 V번 코일에 있는지는 알 수 없습니다.
3개일 때: 각 센서가 $120^\circ$ 마다 신호를 주므로, “지금 자석이 V번 통과했으니 U번에 전기를 줘!”라고 실시간 지시가 가능합니다.
1개일 때: “방금 자석이 지나갔어! 근데 그다음은… 음… 아마 이 속도면 지금쯤 V번 근처겠지?”라고 추측해서 전기를 줘야 합니다.
[Image showing the 6-step commutation sequence of a BLDC motor compared to a single hall sensor pulse]
3. “오픈 루프” 가속 방식 (Open-loop Acceleration)
사실 주인장님이 말씀하신 방식은 실제 산업 현장에서도 씁니다. 센서 없이 일단 박자에 맞춰서 억지로 돌리는 방식이죠.
낮은 주파수에서 모터를 강제로 부들부들 떨게 하며 출발시킵니다.
모터가 박자를 타기 시작하면 서서히 주파수를 올립니다.
문제점: 조금만 속도를 빨리 올리거나 부하가 걸리면 박자를 놓치고(탈조) 바로 멈춥니다.
🚀 시도해볼 만한 코드 로직 (MicroPython)
만약 정말 해보고 싶으시다면, 홀센서 1개를 Interrupt로 잡아서 **’한 바퀴 도는 시간(T)’**을 계산한 뒤, 다음 바퀴에서 T/6 시간마다 전극을 바꾸는 코드를 짜볼 수는 있습니다.
Python
※ 보다 빠른 아두이노 C 언어로 짜면 좀 더 나을까?
1. C언어로 짜면 나아지는 점 (Software 측면)
인터럽트 속도: 센서 신호가 들어오자마자 반응하는 속도가 파이썬보다 수십 배 빠릅니다.
직접 제어:digitalWrite 대신 레지스터를 직접 건드리는 방식을 쓰면 나노초(ns) 단위로 전극을 바꿀 수 있어 박자를 놓칠 확률이 줄어듭니다.
정밀 타이밍:micros() 함수를 이용해 자석의 위치를 훨씬 정교하게 예측할 수 있습니다.
2. 하지만 여전히 안 되는 이유 (Hardware 측면)
문제는 L298N 드라이버 자체에 있습니다.
스위칭 손실 (Heat): L298N은 구식 바이폴라 트랜지스터 방식이라, 고속으로 켰다 껐다 하면 내부 저항 때문에 엄청난 열이 발생하고 전압이 깎입니다. 모터에 충분한 에너지가 전달되지 않습니다.
역기전력(Back-EMF) 처리 불가능: 7,200 RPM으로 돌면 모터에서 엄청난 역전기가 발생합니다. 전용 ESC는 이 전기를 활용하거나 제어하는데, L298N은 이를 그냥 열로 태워버리거나 칩이 타버릴 수 있습니다.
위상 전환의 한계: 최고 속도에 도달하려면 단순히 전기를 주는 게 아니라, 회전 속도에 맞춰 전기를 주는 시점을 앞당기는 ‘진각(Timing Advance)’ 제어가 필요한데, 이걸 생으로 코딩하는 건 거의 박사 학위 수준의 난이도입니다.
※최종결론: “돌릴 수는 있으나 제 성능을 발휘하려면 전용 ESC(전자 변속기)나 전용 드라이버 칩이 필요하다”
ESP32-C3는 뛰어난 가성비와 RISC-V 아키텍처, 그리고 강력한 내장 WiFi/Bluetooth 기능으로 많은 메이커의 사랑을 받고 있습니다. 하지만 실제 프로젝트 하다 보면 한계에 부딪히곤 합니다.
“벽 하나만 통과해도 끊기는 WiFi 거리, 배터리를 순식간에 갉아먹는 전력 소모까지…”
이런 고민을 해결하기 위해 우리는 ESP32-C3의 내장 기능을 넘어 외부 무선 전용 모듈로 눈을 돌려야 합니다. 오늘 포스팅에서는 ESP32-C3의 적은 핀으로도 효율적으로 연결할 수 있는 CC1101, CC1120, CC1200, LoRa, 그리고 CC1310까지, 5종의 무선 모듈을 전격 비교해 보겠습니다. 내 프로젝트에 ‘딱’ 맞는 무선 솔루션은 무엇일까요? 지금 바로 확인해 보시죠.
** 무선 모듈 5종 스펙 비교 (ESP-NOW vs Sub-1GHz)
프로젝트의 성패는 내 상황에 맞는 ‘주파수’와 ‘칩셋’을 고르는 데 있습니다. 속도가 중요한 영상 전송인지, 거리가 중요한 원격 제어인지 아래 표를 통해 확인해 보세요.
[한눈에 보는 무선 모듈 비교표]
항목
ESP-NOW (내장)
CC1101
CC1120 / CC1200
LoRa (SX1276)
CC1310
주요 주파수
2.4GHz
433 / 868 / 915MHz
433 / 868 / 915MHz
433 / 915MHz
433 / 868 / 915MHz
최대 속도
~4 Mbps (매우 빠름)
~600 kbps
~1 Mbps
~37.5 kbps (매우 느림)
~4 Mbps
통신 거리
약 100~200m
약 300~500m
약 1km 이상
최대 5~10km
약 1km 이상
소비 전력
높음 (80~300mA)
매우 낮음 (15~30mA)
낮음 (20~40mA)
낮음 (10~20mA)
낮음 (15~30mA)
특징
추가 비용 없음
가성비 최고, 입문용
고성능, 신뢰성 위주
초장거리, 저속 데이터
멀티 프로토콜 지원
** 모듈별 상세 분석: 내 프로젝트에는 무엇이 좋을까?
① ESP-NOW: “추가 비용 제로, 빠른 속도”
ESP32-C3 내장 WiFi 기능을 활용합니다. 별도의 모듈 연결이 필요 없어 회로가 깔끔합니다.
장점: 속도가 빨라 저해상도 이미지 전송이 가능합니다.
단점: WiFi 대역(2.4GHz)을 써서 장애물(벽)에 약하고 전기를 많이 먹습니다.
② CC1101: “가성비와 저전력의 교과서”
가장 대중적인 Sub-1GHz 모듈입니다.
장점: 가격이 저렴하고 ESP32-C3의 3.3V 핀으로도 충분히 구동됩니다. 조종기 배터리를 오래 쓰고 싶을 때 최고의 선택입니다.
단점: 거리가 LoRa만큼 길지는 않습니다.
③ CC1120 / CC1200: “전문가급 성능과 신뢰성”
CC1101의 상위 버전으로, 통신 신뢰성이 매우 높습니다.
장점: 데이터 전송 속도가 빠르면서도 수신 감도가 좋아 장애물 투과력이 뛰어납니다. 산업용 로봇 제어에 적합합니다.
④ LoRa (SX127x): “거리에 모든 것을 걸었다”
속도를 포기하는 대신 거리를 극한으로 끌어올린 방식입니다.
장점: 수 킬로미터 밖에서도 명령을 전달할 수 있습니다.
단점: 속도가 너무 느려 실시간 조이스틱 반응이 약간 답답할 수 있고, 영상 전송은 절대 불가능합니다.
⑤ CC1310: “차세대 무선 통신의 올인원”
강력한 성능의 SoC(System on Chip) 기반 모듈입니다.
장점: Sub-1GHz 대역임에도 불구하고 매우 빠른 전송 속도를 자랑합니다. 저전력과 고속 통신 두 마리 토끼를 잡고 싶을 때 선택합니다.
** 핵심 요약: 선택 가이드
“돈 안 들이고 근거리에서 로봇을 조종하고 싶다” → ESP-NOW
“조종기 배터리가 오래가야 하고 전선 연결이 간편해야 한다” → CC1101
“로봇이 보이지 않는 아주 먼 곳까지 보내고 싶다” → LoRa
“데이터 양도 많고 거리도 포기할 수 없다” → CC1200 / CC1310
** ESP32-C3와 CC1101을 연결하는 회로도와 마이크로파이썬 예제 코드를 통해 무선 통신을 직접 구현해 보겠습니다!
모듈 2개를 사서 하나는 ‘송신기(Transmitter)’, 다른 하나는 ‘수신기(Receiver)’로 설정하면 완벽한 무선 통신 시스템이 됩니다.
CC1101 433MHz 무선 모듈은 TI(Texas Instruments) 사의 칩을 기반으로 한 RF 송수신 장치입니다. 로봇카를 조종하거나 멀리 떨어진 센서의 데이터를 받을 때 아주 유용합니다.
SMA(안테나 커넥터) 모델은 교체 가능한 안테나를 달 수 있어, 일반 스프링 안테나보다 **훨씬 긴 전송 거리(최대 300~500m 이상)**를 확보할 수 있는 상급 모델입니다.
1. 주요 특징 및 용도
트랜시버(Transceiver): 송신과 수신이 모두 가능합니다. 로봇에 달면 명령을 받을 수도 있고, 현재 배터리 상태(INA219 값)를 나에게 다시 보낼 수도 있습니다.
강력한 투과력: 2.4GHz(WiFi/Bluetooth)보다 주파수가 낮은 433MHz 대역을 써서 벽이나 장애물을 훨씬 잘 통과합니다.
SMA 안테나: 돌려서 끼우는 방식의 안테나를 사용합니다. 안테나를 큰 것으로 바꾸면 도달 거리가 수 킬로미터까지 늘어나기도 합니다.
2. 하드웨어 연결 (ESP32-C3와 SPI 통신)
CC1101은 SPI 인터페이스를 사용합니다. ESP32-C3와 다음과 같이 연결하세요.
CC1101 핀
ESP32-C3 핀
설명
VCC
3.3V
주의: 5V 금지 (칩 타버림)
GND
GND
공통 접지
SCK
Pin 4
SPI Clock
MISO(GDO1)
Pin 5
SPI Master In (데이터 받기)
MOSI
Pin 6
SPI Master Out (데이터 보내기)
CSN
Pin 7
Chip Select (장치 선택)
GDO0
Pin 2
데이터 수신 알림용 (인터럽트)
3. 마이크로파이썬 사용 방법
마이크로파이썬에서 CC1101을 제어하려면 SPI 라이브러리를 사용해야 합니다.
Python
꿀팁: CC1101은 설정할 레지스터가 수십 개로 매우 복잡합니다. 직접 코딩하기보다는 GitHub에서 micropython-cc1101 라이브러리를 다운로드하여 사용하는 것을 강력 추천합니다.
4. 주의사항 (사용 전 필독!)
안테나 미연결 금지: 안테나(SMA)를 끼우지 않은 상태에서 전원을 넣고 **송신(Transmit)**을 하면, 밖으로 나가지 못한 전파 에너지가 칩으로 되돌아와 모듈이 타버릴 수 있습니다. 반드시 안테나를 먼저 조립하세요.
전압 주의: CC1101은 3.3V 전용입니다. 보조배터리 12V를 직접 연결하면 안 되며, 반드시 ESP32-C3의 3.3V 출력 핀이나 별도의 강압 회로를 거쳐야 합니다.
법적 규제: 433MHz 대역은 국내에서 출력과 사용 용도에 제한이 있을 수 있습니다. 취미용 로봇 제어(소출력)는 괜찮지만, 너무 큰 안테나로 출력을 높여 다른 통신을 방해하지 않도록 주의해야 합니다.
** CC1101의 상급(상위) 제품군
CC1101이 “가성비 보급형”이라면, 더 먼 거리나 더 정밀한 통신을 위한 상위 모델들이 있습니다.
상위 모델
특징 및 차이점
추천 용도
CC1120
성능 라인 (Performance Line). CC1101보다 수신 감도가 훨씬 좋아 통신 거리가 비약적으로 깁니다.
1km 이상의 장거리 통신
CC1200
최신 고속 라인. 데이터 전송 속도가 최대 1Mbps로 빠르고, 최신 무선 표준(802.15.4g)을 지원합니다.
고성능 로봇 제어 및 데이터 전송
LoRa (SX1276/78)
장거리 끝판왕. CC1101과 같은 대역을 쓰지만 기술 방식이 달라 수 킬로미터(10km+) 전송이 가능합니다.
산악 지형이나 초장거리 무선 조종
CC1310 (SoC)
두뇌 통합형. CC1101 기능에 ARM Cortex-M3 CPU가 합쳐진 칩입니다. 별도의 ESP32 없이 이 칩 하나로 로봇 제어와 무선을 다 합니다.
초소형/저전력 통합 시스템
전송 속도 및 영상/소리 가능 여부 비교
모델명
최대 전속 속도
영상 전송 가능 여부
소리(음성) 전송 가능 여부
CC1101
약 600 kbps
불가능 (초당 0.1프레임 미만)
매우 낮은 음질 (무전기 수준 이하)
CC1120
약 200 kbps
불가능
불가능
CC1200
약 1,000 kbps (1Mbps)
초저해상도 스틸컷 가능
무전기 수준 (64kbps 이하)
LoRa (SX1276)
약 37.5 kbps
절대 불가능
불가능
CC1310
약 4,000 kbps (4Mbps)
아주 거친 흑백 영상 가능
가능 (단, 프로그래밍 매우 어려움)
[ESP32-C3 상태별 소비전력 비교 (평균)]
상태 (Mode)
평균 전류 (mA)
전력 (3.3V 기준)
특징
CPU Only (RF Off)
약 20 ~ 25mA
~80mW
WiFi/BT를 완전히 끄고 연산만 할 때
WiFi Active (TX)
약 190 ~ 335mA
~1W
영상 스트리밍, 데이터 업로드 중 (피크치 높음)
WiFi Active (RX)
약 80 ~ 90mA
~280mW
데이터 수신 대기 중
ESP-NOW (Active)
약 70 ~ 120mA
~300mW
직접 통신 중 (WiFi보다 오버헤드가 적음)
Modem-sleep
약 15 ~ 20mA
~50mW
WiFi 연결은 유지하되 무선 회로만 잠시 끔
Deep-sleep
약 5 ~ 10µA
~0.03mW
타이머 외 모든 기능 정지 (초절전)
[CC1101 소비전력 상세 (3.3V 기준)]
상태 (Mode)
소비 전류 (mA)
비고
송신 (TX)
약 12 ~ 30mA
출력 설정(-30dBm ~ +10dBm)에 따라 다름
수신 (RX)
약 15 ~ 17mA
데이터가 오길 기다리는 상태
대기 (Idle)
약 1.7mA
회로는 켜져 있으나 송수신 안 함
절전 (Sleep)
약 0.2 ~ 0.4µA
초절전 상태. 거의 0에 가까움
1. ESP-NOW vs CC1101 전력 비교
로봇카 제어 신호를 주고받을 때, 무선 모듈 자체의 전력 소모 차이는 어마어마합니다.
ESP-NOW (C3 내장 WiFi 활용): 수신 대기 시에도 최소 80mA 이상 소모.
CC1101: 수신 대기 시 15mA 내외 소모.
결론: 무선 통신만 놓고 보면 CC1101이 ESP-NOW보다 약 5~6배 더 배터리에 유리합니다.
2. 왜 이렇게 차이가 날까요?
주파수의 특성: 2.4GHz(WiFi)는 초당 처리해야 할 데이터 양이 많고 회로가 복잡해 기본 전력이 많이 듭니다. 반면 433MHz 대역을 쓰는 CC1101은 구조가 단순하고 저속 통신에 최적화되어 있습니다.
프로토콜의 가벼움: WiFi는 통신을 유지하기 위해 뒤에서 계속 패킷을 주고받아야 하지만, CC1101은 평소엔 완전히 잠들어 있다가 필요할 때만 찰나의 순간에 전기를 쓰고 다시 잠들 수 있습니다.
가장 큰 강점은 소프트웨어 설정만으로 내부 풀업 저항을 켤 수 있다는 점입니다. 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개 연결)
브레드보드에서 아래 핀들이 다 꽂혀 있는지 확인해보세요!
VDD: 3.3V
VSS(GND): GND
SCL: ESP32-C3의 1번 핀
SDA: ESP32-C3의 2번 핀
A0: GND (주소 결정)
A1: GND (주소 결정)
A2: GND (주소 결정)
RESET: 3.3V (작동 대기)
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.5V
1.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)
GND
GND
GND
0x20
32 (가장 기본)
GND
GND
3.3V
0x21
33
GND
3.3V
GND
0x22
34
…
…
…
…
…
3.3V
3.3V
3.3V
0x27
39
⚠️ 주의: 이 핀들을 아무 데도 연결하지 않고 공중에 띄워두면(Floating), 주변 노이즈에 따라 주소가 0x20이었다가 0x27이었다가 멋대로 변합니다. 그래서 반드시 GND나 VCC 중 한 곳에 고정해야 합니다.
2. 왜 이게 필요할까?
LED 32개를 제어하고 싶다면, MCP23017 칩 2개를 준비한 뒤 이렇게 하면 됩니다.
1번 칩: A0, A1, A2를 모두 GND에 연결 → 주소 0x20
2번 칩: A0만 3.3V에 연결, 나머지는 GND → 주소 0x21
코드:I2C(0x20)에 명령 보내고, 이어서 I2C(0x21)에 명령 보내면 끝!
3. 배선과 LED 테스트
붉은 부분 A0,A1,A2 3핀이 I2C 주소 지정부 0x20~0x27 노란 점퍼는 Reset 핀 HIGH 로 해놔야 노이즈로 인한 재부팅이 방지 됩니다.
PCF8575는 I2C 통신 단 2선(SDA, SCL)만으로 GPIO 핀을 16개나 늘려주는 모듈입니다. ESP32-C3처럼 핀 수가 적은 보드를 쓸 때 필요한 아이템이죠.
라이브러리 없이도 i2c.writeto()와 i2c.readfrom()만으로 제어가 가능합니다. PCF8575는 16비트(2바이트) 데이터를 주고받습니다.
메카넘 휠 RC카 제작 시 4개의 모터를 독립적으로 구동하려면 정방향, 역방향, 속도 조절(PWM)을 위해 모터당 3개씩 총 12개의 GPIO 핀이 필수적인데, 제가 주력으로 사용하는 ESP32-C3 미니 보드는 실제 가용 핀이 11개 내외인 데다 일부 핀은 부팅 시 설정(Strapping)이나 플래시 메모리 점유 등 하드웨어적 제약이 따라 12개의 핀을 온전히 확보하기가 매우 어렵습니다.
이러한 핀 부족 문제를 해결하기 위해 이전에 데이터 전송 시 3개의 핀이 필요하고 제어 로직이 상대적으로 복잡한 비트 시프트 방식(74HC595 등)을 사용해보기도 했지만, 단 2개의 I2C 통신 핀(SDA, SCL)만으로 최대 16개의 입출력 포트를 즉시 확장해주는 PCF8575 모듈을 활용하면 배선이 획기적으로 간결해질 뿐만 아니라, 모터 제어는 물론 향후 로봇 팔 구동이나 화려한 LED 점등 시스템 같은 추가 장치까지 제약 없이 유연하게 확장할 수 있겠습니다.
테스트는 공통저항 방식과 Sink 방식으로 구동하는 방법을 적용해서 테스트했습니다.
1. 공통저항 방식의 장점
모든 LED의 공통 단자(Common)에 저항 하나만 연결하는 방식은 개별 LED마다 저항을 달아야 하는 번거로운 배선 작업을 편하게 해 테스트할 때 좋습니다.
2. SINK(Active Low) 방식의 장점
부하의 마이너스(-) 극을 MCU 핀에 연결하여 전류를 빨아들이는 SINK 방식은 MCU가 직접 전류를 밀어내는 SOURCE 방식보다 전력 공급의 부담이 적어 회로를 더욱 안정적으로 보호할 수 있으며, 특히 PCF8575와 같은 확장 모듈이나 특정 MCU에서 훨씬 강력한 전류 구동 능력을 발휘함과 동시에 부팅 시 발생할 수 있는 원치 않는 LED 깜빡임(Glitch) 현상을 억제하는 데 유리합니다.
모듈에는 VDD, GND, SLC, SDA 만 ESP32-C3랑 연결하면 끝입니다.
추가로 PCF8575 모듈 양쪽에 VCC와 GND가 있는 이유는 I2C 장치들을 직렬로 계속 연결하기 편하게 하기 위해서입니다. 이를 데이지 체인(Daisy Chain) 방식이라고 하는데, 덕분에 빵판이 훨씬 깔끔해집니다. 또한 INT 핀을 활용하면 CPU 부하를 획기적으로 줄일 수 있는 저전력 설계를 할 수 있습니다.
보통 20mA 정도의 낮은 전류에서 작동하며, 기기의 전원 상태를 알리는 용도로 쓰입니다.
고휘도/파워 LED: 일반적으로 0.5W ~ 1W 이상부터를 의미합니다.
0.5W급: 약 150mA 정도 소모. (손전등, 실내 조명 보조용)
1W급: 약 300∼350mA 소모. (본격적인 조명의 시작점)
3W~10W 이상: 수 Amper(A) 단위의 전류가 필요하며, 매우 강력한 열이 발생합니다.
일반 LED는 저항 연결만으로 사용 (Created with Wokwi)
2. 왜 1W가 기준점이 될까?
회로 설계 입장에서 1W는 “단순 제어”에서 “전력 제어”로 넘어가는 경계선이기 때문입니다.
1W 미만: 적당한 저항기 하나로 전류를 제어할 수 있는 수준입니다.
1W 이상: 앞서 말씀하신 것처럼 **트랜지스터(MOSFET)**가 스위치 역할을 해줘야 하고, 저항기도 고출력용(시멘트 저항 등)을 써야 하며, 본격적인 방열 대책이 수반되어야 합니다.
3. MCU의 출력 전류 한계 (가장 중요한 이유)
MCU의 핀(GPIO)은 신호를 주고받기 위한 용도이지, 전력을 공급하기 위한 용도가 아닙니다.
ESP32-C3의 한계: 일반적으로 핀 하나당 허용되는 최대 전류는 약 20~40mA 내외입니다.
1W LED의 요구량: 전력 공식(P=VI)에 따라, 3.3V 전압에서 1W 고휘도 LED를 켜려면 최소 약 300mA 이상의 전류가 필요합니다.
결과: MCU 핀이 감당할 수 있는 수준보다 약 10배 이상의 전류가 흐르게 되며, 이 과정에서 MCU 내부 회로가 타버리거나 칩 전체가 손상될 수 있습니다.
4. 전압 레벨의 불일치
고휘도 LED: 백색 고휘도 LED의 경우 구동 전압(Forward Voltage)이 보통 3.2V~3.6V 사이입니다.
MCU 출력: ESP32-C3는 3.3V로 작동하지만, 전류를 많이 끌어다 쓰면 전압 강하가 일어나 LED가 제대로 밝기를 내지 못하거나 불안정해집니다. 트랜지스터를 사용하면 5V나 12V 같은 외부 전원을 별도로 끌어와 LED에 공급할 수 있습니다.
5. 발열 문제
전류가 많이 흐르면 열이 발생합니다. MCU의 작은 칩 내부에서 높은 전류를 소화하려고 하면 칩의 온도가 급격히 상승하여 시스템이 멈추거나 수명이 단축됩니다. 전력 제어 전용 부품인 트랜지스터는 이러한 열을 견디도록 설계되어 있습니다.
고휘도 1w이상 LED는 트랜지스터를 사용해서 연결 (Created with Wokwi)
그러면 고휘도 LED로 전원 공급을 하는 5v도 MCU 핀에 연결되어 있지 않냐 할 수 있는데 내부 반도체 로직을 통하지 않고 MCU 전원과 단지 내부 배선으로 연결되어 있어서 보다 안전하다 할 수 있다. 더 큰 전류가 흐른다면 아예 부하용 전원에 직접 연결하는게 제일 안전합니다.
그냥 연결시 5핀을 3.3v 으로 on 시키면 칩내 반도체의 허용전류이상으로 발열로 손상됩니다. 예외적 꼼수로 5번핀을 PWM 으로 설정하고 duty를 절반 이하로 낮게 해주어 평균 전압을 낮춰서 사용가능합니다. (Created with Wokwi)실제 RC카에 적용된 고휘도 LED, 밝기는 PWM duty로 조절 할 수 있어서 고휘도 LED에는 구지 저항을 달지 않았습니다. 소프트웨어적으로 duty를 항상 50% 이하로만 조절되도록 하면 됩니다.