Skip to content

필사 모드: 모터와 릴레이, 유도성 부하 다루기 — GPIO로 모터를 돌리면 안 되는 이유

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

들어가며 — 모터가 돌 때마다 보드가 재부팅됩니다

작은 기어 모터를 아두이노 D9에 연결하고 GND에 반대쪽을 물립니다. digitalWrite(9, HIGH)를 씁니다.

모터가 아주 살짝 떨립니다. 그리고 시리얼 모니터에 부팅 메시지가 다시 뜹니다. 프로그램이 처음부터 시작합니다. 또 모터를 켭니다. 또 재부팅됩니다.

여기서 대부분의 사람이 코드를 봅니다. 워치독인가, 스택 오버플로인가, 라이브러리 충돌인가. 코드에는 아무 문제가 없습니다.

문제는 숫자 하나입니다. 아두이노 핀 하나가 안전하게 낼 수 있는 전류는 20mA이고, 그 모터가 요구하는 전류는 200mA입니다. 열 배입니다.

이 글에서는 그 열 배가 어디로 가는지, 무엇을 태우는지, 그리고 제대로 하는 방법이 무엇인지를 다룹니다. 모터와 릴레이와 솔레노이드는 전부 코일이 들어 있는 유도성 부하이고, 유도성 부하에는 저항이나 LED에 없는 위험이 하나 더 있습니다.

핀이 낼 수 있는 전류와 모터가 요구하는 전류

먼저 두 숫자를 나란히 놓겠습니다.

부하정상 운전 전류기동 또는 구속 시 피크GPIO 직결 가능 여부
LED 하나15mA없음가능
부저 (수동형)30mA없음아두이노는 위험, 파이는 불가
SG90 서보모터120mA700mA불가
소형 DC 기어 모터 (TT 모터)150 ~ 250mA800mA ~ 1.5A불가
릴레이 모듈 1채널70mA없음불가
5V 솔레노이드 잠금장치600mA1.2A불가
WS2812B LED 30알알당 60mA, 합계 1.8A없음불가
12V 냉각 팬150mA (12V 쪽)400mA불가 (전압도 다름)

보드 쪽 한계는 이렇습니다.

보드핀 하나당 권장핀 하나당 절대 최대전체 GPIO 합계5V 레일 공급 한계
아두이노 우노 R320mA40mA200mA약 450mA
라즈베리파이 40핀16mA16mA50mA약 1000mA
ESP32 DevKit v112mA40mA120mA약 500mA

표에서 GPIO 직결이 가능한 줄은 첫 번째뿐입니다.

이제 물리로 넘어가겠습니다. 200mA를 요구하는 모터를 20mA짜리 핀에 물리면 정확히 무엇이 일어날까요.

핀의 출력단은 아주 작은 MOSFET 한 쌍입니다. HIGH를 쓰면 위쪽 MOSFET이 켜져 핀을 5V에 연결하는데, 이 MOSFET은 완벽한 스위치가 아니라 저항을 가집니다. ATmega328P의 경우 대략 25옴입니다.

모터의 코일 저항이 5옴이라고 하면 회로 전체 저항은 30옴입니다.

흐르는 전류 = 5V / 30옴 = 0.167A = 167mA

167mA가 그 작은 MOSFET을 통과합니다. MOSFET에서 소비되는 전력은,

P = I² × R = 0.167² × 25 = 0.028 × 25 = 0.70W

0.7W입니다. 이 MOSFET은 20mA 기준으로 설계되었고, 그때의 소비 전력은,

P = 0.02² × 25 = 0.00001 W = 0.01mW

설계값의 7만 배입니다. 실리콘 조각 하나에 0.7W가 들어가면 접합 온도가 밀리초 단위로 수백 도까지 올라갑니다. 결과는 두 가지 중 하나입니다. 게이트 산화막이 절연을 잃어 핀이 영구히 HIGH나 LOW에 고정되거나, 금속 배선이 녹아 핀이 아예 끊어집니다.

그리고 재부팅의 원인은 조금 다릅니다. 167mA가 갑자기 빠져나가면 5V 레일이 순간적으로 무너집니다. 그 이야기는 마지막 절에서 자세히 하겠습니다.

여기서 원칙 하나를 세우고 가겠습니다. GPIO 핀은 전력을 공급하는 곳이 아니라 명령을 내리는 곳입니다. 전력은 언제나 전원에서 직접 와야 하고, 핀은 그 전력을 통과시킬 스위치를 여닫는 역할만 합니다.

외부 전원과 공통 그라운드 — 접지를 묶지 않으면

모터에 별도 전원을 붙이기로 했다고 하겠습니다. 6V 배터리 팩을 준비하고, 모터를 거기에 연결하고, 스위칭용 트랜지스터를 아두이노가 제어합니다.

여기서 초보자가 거의 반드시 빠뜨리는 배선이 하나 있습니다. 배터리의 마이너스와 아두이노의 GND를 연결하는 선입니다.

왜 필요한지는 앞 글에서 본 전압의 정의로 돌아가면 명확합니다. 전압은 두 지점 사이의 차이입니다. 아두이노가 "5V를 출력했다"고 할 때 그 5V는 아두이노의 GND를 기준으로 한 값입니다. 배터리 쪽 회로는 배터리의 마이너스를 기준으로 전압을 봅니다. 두 기준점이 연결되어 있지 않으면 두 회로 사이에 공통의 눈금이 없습니다.

MOSFET의 게이트를 예로 들면, MOSFET이 켜지는 조건은 게이트와 소스 사이의 전압이 문턱 전압을 넘는 것입니다. 게이트는 아두이노에서 오고 소스는 배터리 쪽 GND에 있습니다. 두 GND가 떨어져 있으면 게이트와 소스 사이의 전압이 얼마인지 정의되지 않습니다. 정의되지 않은 값으로 스위치가 열리고 닫히므로, 증상은 "가끔 되고 가끔 안 된다"가 됩니다.

실제로 관찰되는 현상은 더 기괴합니다. 두 회로는 완전히 분리되어 있는 것이 아니라 부유 용량으로 아주 약하게 결합되어 있습니다. 그래서 모터가 돌 때 생기는 전기적 잡음이 그 결합을 통해 아두이노 쪽 기준 전위를 흔듭니다. 손을 대면 동작이 바뀌고, 오실로스코프 프로브를 연결하면 갑자기 정상이 됩니다. 프로브의 접지선이 두 회로를 묶어 주었기 때문입니다.

규칙은 간단합니다. 별도 전원을 쓰는 회로들의 GND는 반드시 한 점에서 만나야 합니다. 플러스는 나눠도 되지만 마이너스는 공유합니다.

여기에 실무 요령을 하나 덧붙이면, GND를 묶는 선은 모터 전류가 지나는 굵은 선과 별도로 잡는 것이 좋습니다. 모터 전류가 흐르는 GND 선에도 저항이 있어서 전압 강하가 생기기 때문입니다. 얇은 점퍼선 20센티미터의 저항이 대략 0.05옴이고, 여기에 1A가 흐르면,

0.05옴 × 1A = 0.05V

50밀리볼트가 두 회로의 기준점 사이에 생깁니다. 로직 신호에는 큰 문제가 아니지만 아날로그 센서를 함께 읽고 있다면 측정값이 그만큼 흔들립니다. 모터의 GND는 전원으로 굵고 짧게 돌려보내고, 로직의 GND는 별도 경로로 전원의 같은 지점에 모으는 것이 원칙입니다.

트랜지스터와 MOSFET으로 스위칭하기

핀이 명령만 내리고 전류는 전원에서 오게 하려면 스위치가 필요합니다. 반도체 스위치는 두 종류가 있고, 고르는 기준이 명확합니다.

BJT — 전류로 제어합니다

바이폴러 트랜지스터는 베이스에 흘려 넣는 전류에 비례해 컬렉터 전류를 통과시킵니다. 스위치로 쓸 때는 완전히 켜지는 포화 영역에서 동작시켜야 하고, 그러려면 베이스 전류를 넉넉하게 줘야 합니다.

릴레이 모듈 하나를 켠다고 하겠습니다. 코일 전류가 70mA입니다. 2N3904 같은 소신호 트랜지스터를 쓰고, 포화를 확실히 하기 위해 전류 증폭률을 데이터시트 값이 아니라 보수적으로 10으로 잡습니다.

필요한 베이스 전류 = 70mA / 10 = 7mA

베이스 저항은 핀 전압에서 베이스와 이미터 사이의 전압 강하 0.7V를 뺀 값을 이 전류로 나눕니다.

베이스 저항 = (5V - 0.7V) / 0.007A = 614옴

여기서 반올림 방향이 LED 저항과 반대라는 점이 중요합니다. LED에서는 전류가 적어야 안전하므로 위로 올렸습니다. 베이스 저항은 전류가 모자라면 트랜지스터가 반쯤만 켜져서 자기 몸에서 전력을 소모하고 뜨거워지므로, 아래로 내려야 합니다. E24에서 614옴 아래는 560옴입니다.

실제 베이스 전류 = (5V - 0.7V) / 560옴 = 0.0077A = 7.7mA

7.7mA로 핀 한계 20mA 안쪽입니다. 안전합니다.

BJT가 완전히 켜져도 컬렉터와 이미터 사이에는 약 0.2V가 남습니다. 이것이 포화 전압이고, 70mA에서의 손실은,

0.2V × 0.07A = 0.014W = 14mW

무시할 수 있습니다.

MOSFET — 전압으로 제어합니다

전류가 커지면 BJT는 불리해집니다. 200mA를 스위칭하려면 베이스 전류가 20mA 필요한데, 이것은 아두이노 핀 한계 그 자체입니다. 500mA면 50mA가 필요해서 아예 불가능합니다.

MOSFET은 게이트에 전압만 걸면 켜집니다. 게이트는 절연되어 있어서 정상 상태에서 전류가 거의 흐르지 않습니다. 그래서 큰 전류를 작은 핀으로 제어할 수 있습니다.

여기서 결정적으로 중요한 것이 로직 레벨 MOSFET을 골라야 한다는 점입니다. 일반 MOSFET은 게이트에 10V를 걸어야 완전히 켜지도록 설계되어 있습니다. 유명한 IRF540N이 그렇습니다. 5V만 걸면 반쯤만 켜져서 저항이 크게 남고, 그 저항에서 열이 납니다. 1A를 흘릴 때 저항이 0.5옴이면,

P = 1² × 0.5 = 0.5W

0.5W가 MOSFET에서 열로 나옵니다. 방열판 없이는 뜨거워집니다.

로직 레벨 MOSFET은 게이트에 4.5V만 걸어도 완전히 켜지도록 만들어져 있습니다. IRLZ44N이 대표적이고, 이 부품의 온 저항은 게이트 5V에서 0.028옴입니다.

P = 1² × 0.028 = 0.028W = 28mW

18배 차이입니다. 부품 이름에서 IRF와 IRLZ의 차이가 이것입니다.

그런데 3.3V 보드라면 한 단계 더 주의해야 합니다. IRLZ44N도 게이트 3.3V에서는 규격이 보장되지 않습니다. 라즈베리파이나 ESP32에서는 게이트 문턱이 2.5V 이하로 명시된 부품을 골라야 합니다. AO3400이나 IRLML2502가 이 용도로 흔히 쓰입니다.

게이트 저항과 풀다운 저항

MOSFET 회로에는 저항 두 개를 함께 넣습니다.

게이트 저항은 핀과 게이트 사이에 직렬로 들어갑니다. MOSFET의 게이트는 커패시터라서, 켜지는 순간 그 커패시터를 충전하는 큰 순간 전류가 흐릅니다. 저항이 없으면 이 전류를 제한하는 것이 핀의 내부 저항뿐입니다. 220옴을 넣으면,

최대 순간 게이트 전류 = 5V / 220옴 = 0.0227A = 22.7mA

22.7mA입니다. 지속 시간이 수십 나노초라 아두이노는 견디지만, 파이라면 여유가 없습니다. 3.3V에 470옴이면,

3.3V / 470옴 = 0.007A = 7mA

7mA로 안전합니다. 게이트 저항을 너무 키우면 스위칭이 느려지고 그동안 MOSFET이 중간 상태에 머물러 열이 나므로, 100옴에서 470옴 사이가 실용적인 범위입니다.

풀다운 저항은 게이트와 GND 사이에 10킬로옴 정도로 넣습니다. 이유는 앞 글의 플로팅 입력과 같습니다. 보드가 부팅되는 동안, 그리고 리셋 중에는 GPIO 핀이 입력 상태의 고임피던스가 됩니다. 그동안 게이트는 아무 데도 연결되지 않은 상태가 되고, 주변 잡음으로 전압이 오르면 MOSFET이 켜집니다. 즉 전원을 넣는 순간 모터가 잠깐 돕니다. 풀다운 저항이 그 사이 게이트를 0V로 잡아 줍니다.

이 저항 하나를 빼먹으면 "전원을 켤 때마다 모터가 한 번 움찔한다"는 증상이 나오고, 로봇이라면 그 움찔 한 번이 팔을 부러뜨릴 수도 있습니다.

플라이백 다이오드 — 유도성 킥백의 물리

여기까지 하면 스위칭 회로는 완성된 것처럼 보입니다. 그런데 릴레이를 몇 번 켜고 끄면 MOSFET이 죽습니다. 계산상 전류도 전압도 여유가 충분한데 죽습니다.

원인은 코일입니다.

왜 수천 볼트가 생기는가

인덕터의 근본 성질은 전류의 변화를 거스른다는 것입니다. 수식으로는 이렇습니다.

V = L × (di / dt)

L은 인덕턴스, di/dt는 전류의 시간 변화율입니다. 이 식이 말하는 바는 전류를 빨리 바꾸려 할수록 인덕터가 더 큰 전압을 만들어 반대한다는 것입니다.

릴레이 코일의 인덕턴스가 100밀리헨리이고 70mA가 흐르고 있었다고 하겠습니다. MOSFET이 꺼지는 데 걸리는 시간은 대략 1마이크로초입니다.

V = 0.1H × (0.07A / 0.000001초)
  = 0.1 × 70000
  = 7000V

7000볼트입니다. 계산상의 값이고 실제로는 공기 절연 파괴나 부품 항복으로 더 낮은 값에서 멈추지만, 수백 볼트에서 수천 볼트에 이르는 것은 사실입니다.

이 전압의 방향이 중요합니다. 코일은 흐르던 전류를 계속 흘리려고 하므로, 전류가 끊긴 쪽의 전위를 밀어 올립니다. 즉 MOSFET의 드레인 전압이 전원 전압을 훨씬 넘어 치솟습니다. IRLZ44N의 드레인과 소스 사이 최대 정격은 55V입니다. 수백 볼트가 걸리면 항복이 일어나고, 그 항복 에너지를 반복해서 흡수하면 부품이 죽습니다.

에너지의 크기도 계산해 두면 감이 잡힙니다.

E = 0.5 × L × I² = 0.5 × 0.1 × 0.07² = 0.000245J = 245마이크로줄

245마이크로줄은 크지 않아 보이지만, 이것이 1마이크로초 안에 방출되면 순간 전력은,

0.000245J / 0.000001초 = 245W

245와트입니다. 아주 짧지만 매번 반복됩니다.

다이오드가 하는 일

해법은 그 에너지가 갈 길을 만들어 주는 것입니다. 코일과 병렬로 다이오드를 하나 붙입니다. 방향은 평소에는 도통하지 않는 방향, 즉 캐소드(띠가 그려진 쪽)를 플러스 전원에, 애노드를 MOSFET의 드레인 쪽에 연결합니다.

평상시에는 다이오드가 역방향이라 아무 일도 하지 않습니다. MOSFET이 꺼지고 코일이 전압을 밀어 올리는 순간, 드레인 전압이 전원 전압보다 다이오드의 순방향 전압만큼 높아지면 다이오드가 도통합니다. 그러면 코일의 전류가 다이오드를 통해 코일 자신에게로 순환합니다. 갈 곳이 생겼으므로 전압이 더 올라갈 이유가 없어집니다.

이때 드레인의 최대 전압은,

전원 전압 + 다이오드 순방향 전압 = 5V + 0.7V = 5.7V

7000V가 5.7V가 됩니다. 부품 하나가 만드는 차이치고는 극적입니다.

순환하는 전류는 코일의 저항에서 열로 소모되며 서서히 줄어듭니다. 245마이크로줄이 수 밀리초에 걸쳐 조용히 사라집니다.

다이오드 고르기와 부작용

어떤 다이오드를 쓸지에는 기준이 있습니다.

전류 정격은 코일 전류 이상이어야 합니다. 70mA라면 1N4148의 200mA로도 되지만, 여유를 두어 1A짜리 1N4007을 쓰는 경우가 많습니다.

역전압 정격은 전원 전압보다 넉넉해야 합니다. 1N4007은 1000V이므로 어떤 저전압 회로에도 충분합니다.

복구 속도가 중요한 경우도 있습니다. PWM으로 모터 속도를 제어하면 초당 수천 번 껐다 켜는데, 1N4007 같은 일반 정류 다이오드는 역방향으로 돌아가는 데 수 마이크로초가 걸려서 그 사이 손실이 발생합니다. 이때는 1N5819 같은 쇼트키 다이오드를 씁니다. 순방향 전압도 0.3V로 낮아 클램프 전압이 더 낮습니다.

부작용도 알아 둘 필요가 있습니다. 다이오드를 달면 릴레이가 떨어지는 시간이 길어집니다. 코일 전류가 천천히 줄어들기 때문입니다. 보통 몇 밀리초 정도인데, 접점이 늦게 떨어지면 아크가 더 오래 지속되어 접점 수명이 줄어듭니다. 이것이 문제가 되는 회로에서는 다이오드에 저항이나 제너 다이오드를 직렬로 넣어 클램프 전압을 조금 높이는 방식으로 절충합니다.

그리고 마지막으로, 릴레이 모듈이나 모터 드라이버 보드를 완제품으로 사면 이 다이오드가 이미 기판에 들어 있는 경우가 많습니다. 직접 트랜지스터로 코일을 스위칭할 때만 챙기면 됩니다. 다만 기판에 있는지 없는지는 눈으로 확인하는 편이 안전합니다.

모터 드라이버 IC와 H 브리지

지금까지의 회로는 모터를 켜고 끄는 것만 할 수 있습니다. 방향을 바꾸려면 전류의 방향을 뒤집어야 하고, 그러려면 스위치 네 개가 필요합니다. 이 구조를 H 브리지라고 부릅니다. 모양이 알파벳 H를 닮아서입니다.

      +V                +V
       │                 │
     [S1]              [S2]
       │                 │
       ├──── 모터 ────────┤
       │                 │
     [S3]              [S4]
       │                 │
      GND               GND

  S1과 S4를 켜면 왼쪽에서 오른쪽으로,
  S2와 S3을 켜면 오른쪽에서 왼쪽으로 흐릅니다.
  S1과 S3을 동시에 켜면 전원과 GND가 단락됩니다.

마지막 줄이 H 브리지를 직접 만들지 않는 이유입니다. 같은 쪽의 위아래 스위치가 동시에 켜지면 전원이 단락되고, 이것을 관통 전류라고 부릅니다. MOSFET은 켜지는 속도와 꺼지는 속도가 달라서, 한쪽을 끄고 다른 쪽을 켜는 사이에 아주 짧게 둘 다 켜지는 순간이 생길 수 있습니다. 그래서 실제 설계에서는 데드타임을 넣어야 하는데, 이것을 소프트웨어로 정확히 맞추는 것은 위험합니다.

그래서 실무에서는 드라이버 IC를 씁니다.

부품채널채널당 전류방식특징
L293D2600mABJT오래된 표준, 전압 강하 약 2V로 큼
L298N22ABJT흔한 모듈, 전압 강하 약 2V, 방열판 필요
DRV883321.5AMOSFET전압 강하 작음, 소형 로봇에 적합
TB6612FNG21.2AMOSFETL298N 대체용, 효율 좋음
A4988 / DRV8825스테퍼 1축1 ~ 2AMOSFET스테퍼 전용, 전류 조절 가능

L298N 모듈이 가장 흔하지만 알아 둘 점이 있습니다. 내부가 BJT라 각 방향으로 약 1V씩, 합쳐서 2V 가까이 떨어집니다. 6V 전원으로 모터에 실제로 전달되는 것은 4V입니다. 3분의 1이 드라이버에서 열로 사라집니다. 3V 계열의 작은 모터를 쓸 때는 이 손실이 치명적이라 DRV8833이나 TB6612FNG가 더 나은 선택입니다.

릴레이 모듈과 옵토커플러 절연

가정용 교류 기기나 12V 조명처럼 마이크로컨트롤러와 전기적으로 완전히 분리해야 하는 부하에는 릴레이를 씁니다.

릴레이는 코일에 전류를 흘려 전자석을 만들고, 그 힘으로 기계적 접점을 움직이는 부품입니다. 접점과 코일 사이에는 물리적 공간이 있어서 전기적으로 완전히 분리됩니다. 접점 쪽에 220V가 있어도 코일 쪽은 5V 세상 그대로입니다.

시중의 릴레이 모듈에는 대개 옵토커플러가 하나 더 들어 있습니다. 이것은 절연을 한 겹 더 두는 부품으로, 안에 LED와 광트랜지스터가 마주 보고 들어 있습니다. 신호를 빛으로 바꿔 건너보내므로 두 회로 사이에 전기적 연결이 전혀 없습니다.

여기서 실무적으로 중요한 것이 모듈 위의 점퍼입니다. 대부분의 릴레이 모듈에는 VCC, GND, JD-VCC라고 표시된 핀과 그 사이를 잇는 점퍼가 있습니다. 이 점퍼가 꽂혀 있으면 릴레이 코일도 마이크로컨트롤러의 5V에서 전원을 받습니다. 옵토커플러가 있어도 전원이 공유되므로 절연의 의미가 사라집니다.

그리고 실용적인 문제도 있습니다. 릴레이 코일이 70mA를 씁니다. 4채널 모듈에서 네 개가 동시에 켜지면,

70mA × 4 = 280mA

280mA입니다. 아두이노 5V 레일의 한계 450mA에 상당한 부담이고, 릴레이가 켜지는 순간의 전류 변화가 5V 레일을 흔들어 보드를 불안정하게 만듭니다.

제대로 하려면 점퍼를 빼고 JD-VCC에 별도 5V 전원을 연결합니다. 그러면 코일 전류는 별도 전원에서 오고 마이크로컨트롤러는 옵토커플러의 LED에 몇 밀리암페어만 공급합니다. 이때 두 전원의 GND는 묶지 않아야 절연이 유지됩니다. 앞에서 GND를 반드시 묶으라고 했던 원칙의 유일한 예외이고, 이유는 옵토커플러가 기준점을 공유하지 않고도 신호를 전달하기 때문입니다.

또 하나, 많은 릴레이 모듈이 액티브 로우입니다. IN 핀에 LOW를 줘야 릴레이가 붙습니다. 그래서 보드가 부팅되는 동안 핀이 플로팅이면 릴레이가 잠깐 붙었다 떨어지는 일이 생깁니다. 조명이라면 깜빡이는 정도지만 히터나 모터라면 문제가 됩니다. 앞 글의 풀업 저항이 여기서 다시 쓰입니다.

디커플링 커패시터와 브라운아웃 — 코드 문제가 아닙니다

마지막으로 이 글의 첫 문단으로 돌아가겠습니다. 모터를 켤 때마다 보드가 재부팅되는 현상입니다.

스위칭 회로를 제대로 만들고 별도 전원까지 붙였는데도 이 증상이 남는 경우가 많습니다. 원인은 전원 배선의 저항입니다.

모든 전선에는 저항이 있습니다. USB 케이블 1미터의 전원선 저항은 대략 0.2옴, 브레드보드의 접촉 저항이 접점당 0.01옴에서 0.05옴, 점퍼선이 0.05옴 정도입니다. 다 합치면 0.3옴 안팎이 나옵니다.

모터가 기동할 때 흐르는 전류를 1.5A라고 하면,

전압 강하 = 1.5A × 0.3옴 = 0.45V

5.1V로 들어오던 전원이 보드 입장에서는 4.65V가 됩니다.

라즈베리파이는 5V 레일이 4.63V 아래로 떨어지면 저전압 경고를 띄우고, 더 떨어지면 SD 카드 접근이 실패하거나 재부팅됩니다. 아두이노의 ATmega328P에는 브라운아웃 감지 회로가 있어서 기본 설정에서 2.7V 아래로 떨어지면 강제로 리셋합니다. 5V 레귤레이터에 4.65V가 들어오면 출력은 그보다 낮아지고, 기동 전류가 더 크면 그 임계값을 넘습니다.

증상이 코드처럼 보이는 이유가 이것입니다. 리셋은 코드가 실행되던 중에 일어나고, 시리얼에는 부팅 메시지가 뜹니다. 완벽하게 소프트웨어 문제로 보입니다.

커패시터가 할 수 있는 일과 없는 일

대응은 두 층입니다.

100나노패럿 세라믹 커패시터를 각 IC의 전원 핀 바로 옆에 붙입니다. 이것은 나노초에서 마이크로초 단위의 빠른 전류 변동을 공급합니다. 칩 내부의 트랜지스터가 스위칭할 때 순간적으로 필요한 전류를 전원에서 끌어오려면 배선의 인덕턴스 때문에 늦습니다. 바로 옆의 작은 커패시터가 그 순간을 메웁니다.

470마이크로패럿 전해 커패시터를 모터 전원 근처에 붙입니다. 이것은 밀리초 단위의 큰 변동을 완화합니다. 얼마나 도움이 되는지 계산해 보겠습니다. 1A의 추가 전류를 100마이크로초 동안 공급하면서 전압 강하를 0.2V로 억제하려면 필요한 용량은,

C = I × Δt / ΔV = 1A × 0.0001초 / 0.2V = 0.0005F = 500마이크로패럿

500마이크로패럿입니다. 470마이크로패럿이면 거의 맞습니다.

그런데 모터의 기동 시간은 100마이크로초가 아니라 수 밀리초입니다. 5밀리초로 다시 계산하면,

C = 1A × 0.005초 / 0.2V = 0.025F = 25000마이크로패럿

25000마이크로패럿입니다. 브레드보드에 꽂을 수 있는 부품이 아닙니다.

이 계산이 알려 주는 것은 명확합니다. 커패시터는 짧은 스파이크를 다듬는 부품이지 부족한 전원을 대신하는 부품이 아닙니다. 브라운아웃이 계속된다면 커패시터를 더 키우는 것이 아니라 전원 자체를 바꿔야 합니다.

실제 해결 순서

증상이 나왔을 때 확인할 순서는 이렇습니다.

첫째, 모터 전원과 로직 전원이 분리되어 있는지 봅니다. 같은 USB에서 둘 다 뽑고 있다면 이것이 원인입니다.

둘째, 전선을 굵고 짧게 바꿉니다. 브레드보드를 거치는 전원 경로는 접촉 저항이 누적되므로, 전류가 큰 경로는 직접 납땜하거나 굵은 선으로 직결합니다.

셋째, 커패시터를 붙입니다. 모터 단자 양쪽에 100나노패럿, 모터 전원 입력에 470마이크로패럿을 놓습니다. 모터 단자의 세라믹 커패시터는 브러시에서 발생하는 고주파 잡음을 억제하는 역할도 합니다.

넷째, 소프트 스타트를 넣습니다. PWM으로 속도를 서서히 올리면 기동 전류의 피크가 낮아집니다. 이것은 코드로 할 수 있는 유일한 완화책입니다.

// MOSFET 게이트를 PWM으로 구동해 모터를 서서히 기동합니다.
// 배선: D9 -> 220옴 -> MOSFET 게이트, 게이트와 GND 사이에 10k 풀다운
//       모터는 별도 전원, 코일과 병렬로 1N5819 환류 다이오드
//       두 전원의 GND는 한 점에서 연결

const int MOTOR_PWM_PIN = 9;
const int RAMP_STEP_MS = 12;     // 한 단계마다 기다리는 시간
const int TARGET_DUTY = 200;     // 0에서 255. 최종 속도

void setup() {
  pinMode(MOTOR_PWM_PIN, OUTPUT);
  analogWrite(MOTOR_PWM_PIN, 0);
  delay(500);                    // 전원이 안정될 때까지 기다립니다
}

void softStart() {
  // 0에서 목표까지 약 2.4초에 걸쳐 올립니다.
  // 갑자기 255를 쓰면 기동 전류가 그대로 흐르고 레일이 무너집니다.
  for (int duty = 0; duty <= TARGET_DUTY; duty++) {
    analogWrite(MOTOR_PWM_PIN, duty);
    delay(RAMP_STEP_MS);
  }
}

void softStop() {
  for (int duty = TARGET_DUTY; duty >= 0; duty--) {
    analogWrite(MOTOR_PWM_PIN, duty);
    delay(RAMP_STEP_MS);
  }
}

void loop() {
  softStart();
  delay(3000);
  softStop();
  delay(2000);
}

다만 이 코드를 근본 해결책으로 오해하면 안 됩니다. 소프트 스타트는 기동 전류의 피크를 낮출 뿐이고, 모터가 부하를 만나 구속되면 여전히 구속 전류가 흐릅니다. 전원이 그 전류를 감당하지 못하면 같은 증상이 다시 나옵니다.

배선을 다 짜고 나서 전류 예산이 맞는지 확인하고 싶다면 배선 검증 도구에 부품을 올려 보십시오. 서보모터나 LED 스트립처럼 별도 전원이 필요한 부품에는 피크 전류와 함께 별도 공급을 권하는 안내가 나오고, 5V 레일 합계가 보드의 공급 한계를 넘는지도 계산해 줍니다.

마치며 — 핀은 명령을 내리고, 전력은 전원에서 옵니다

이 글에서 다룬 사고들은 표면적으로 서로 달라 보입니다. 핀이 타는 것, 보드가 재부팅되는 것, MOSFET이 죽는 것, 릴레이가 부팅할 때 잠깐 붙는 것.

그런데 전부 같은 오해에서 나옵니다. GPIO 핀을 전원처럼 다룬 것입니다.

핀은 스위치를 여닫는 신호선입니다. 그 신호가 제어하는 스위치가 전원에서 부하로 가는 큰 전류를 통과시킵니다. 이 구조를 지키면 전류의 크기는 핀과 아무 상관이 없어집니다. 1A를 흘리든 10A를 흘리든 핀이 하는 일은 게이트를 몇 밀리암페어로 충전하는 것뿐입니다.

그리고 유도성 부하에는 한 가지가 더 붙습니다. 코일은 전류를 끊는 순간을 싫어하고, 그 불만을 수천 볼트로 표현합니다. 그 에너지가 갈 길을 다이오드로 미리 만들어 두면 5.7V로 조용해집니다. 다이오드 하나를 빼먹는 것과 넣는 것의 차이가 1000배입니다.

지금까지 다섯 편에 걸쳐 다룬 내용은 결국 세 개의 숫자로 수렴합니다. 이 부품에 몇 볼트가 걸리는가, 몇 밀리암페어가 흐르는가, 그리고 이 핀이 감당할 수 있는 값은 얼마인가. 회로에서 조용히 하드웨어를 망가뜨리는 실수는 거의 전부 이 셋 중 하나를 확인하지 않은 데서 나옵니다. 부품을 연결하기 전에 이 세 숫자를 종이에 적어 보는 습관이 회로도를 열 장 읽는 것보다 낫습니다.

현재 단락 (1/193)

작은 기어 모터를 아두이노 D9에 연결하고 GND에 반대쪽을 물립니다. `digitalWrite(9, HIGH)`를 씁니다.

작성 글자: 0원문 글자: 10,355작성 단락: 0/193