Skip to content

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

✨ Learn with Quiz
|

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

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

작은 기어 모터를 아두이노 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배입니다.

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

Driving Motors, Relays, and Inductive Loads: Why You Should Never Power a Motor from GPIO

Introduction — The Board Reboots Every Time the Motor Spins

Connect a small gear motor to Arduino D9 and its other lead to GND. Call digitalWrite(9, HIGH).

The motor twitches ever so slightly. Then the serial monitor shows the boot message again. The program starts over from the beginning. Turn the motor on again. It reboots again.

Here's where most people go straight to the code. Is it a watchdog? A stack overflow? A library conflict? There's nothing wrong with the code.

The problem is one number. The current an Arduino pin can safely supply is 20mA, and the current that motor demands is 200mA. Ten times over.

This post covers where that factor of ten goes, what it burns, and what the correct way to do this actually is. Motors, relays, and solenoids are all inductive loads with a coil inside, and an inductive load carries one extra danger that a resistor or LED doesn't have.

The Current a Pin Can Supply, and the Current a Motor Demands

Let's start by putting two numbers side by side.

LoadNormal running currentStartup or stall peakDirect GPIO drive possible?
Single LED15mANoneYes
Buzzer (passive)30mANoneRisky on Arduino, no on Pi
SG90 servo motor120mA700mANo
Small DC gear motor (TT motor)150–250mA800mA–1.5ANo
1-channel relay module70mANoneNo
5V solenoid lock600mA1.2ANo
WS2812B LED, 30 pixels60mA each, 1.8A totalNoneNo
12V cooling fan150mA (on the 12V side)400mANo (different voltage too)

Here's where the board's own limits stand:

BoardRecommended per pinAbsolute max per pinTotal GPIO combined5V rail supply limit
Arduino Uno R320mA40mA200mA~450mA
Raspberry Pi 40-pin16mA16mA50mA~1000mA
ESP32 DevKit v112mA40mA120mA~500mA

In this table, the only row that permits driving anything directly from GPIO is the first one.

Now let's move to the physics. Connect a motor demanding 200mA to a pin that can only supply 20mA — what exactly happens?

The pin's output stage is a tiny pair of MOSFETs. Write HIGH and the upper MOSFET turns on, connecting the pin to 5V — but this MOSFET isn't a perfect switch, it has resistance. For the ATmega328P, that's roughly 25 ohms.

Say the motor's coil resistance is 5 ohms; the total circuit resistance is 30 ohms.

Current flowing = 5V / 30 ohm = 0.167A = 167mA

167mA passes through that tiny MOSFET. The power dissipated in the MOSFET is:

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

0.7W. This MOSFET was designed around 20mA, where the power dissipated is:

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

Seventy thousand times the design value. Put 0.7W into a sliver of silicon and the junction temperature climbs to hundreds of degrees on a millisecond timescale. The outcome is one of two things. Either the gate oxide loses its insulating property and the pin gets permanently stuck at HIGH or LOW, or the metal trace melts and the pin breaks off entirely.

And the reboot has a slightly different cause. When 167mA suddenly drains away, the 5V rail momentarily collapses. We'll cover that in detail in the last section.

Let's establish one principle here. A GPIO pin is a place that issues commands, not a place that supplies power. Power should always come directly from the supply, and the pin's only job is to open and close a switch that lets that power through.

External Power and Common Ground — What Happens If You Don't Tie the Grounds Together

Say you've decided to give the motor its own separate power supply. You get a 6V battery pack, connect the motor to it, and have the Arduino control a switching transistor.

There's one piece of wiring beginners almost always forget: the wire connecting the battery's minus terminal to the Arduino's GND.

Why it's needed becomes clear if you go back to the definition of voltage from the earlier post. Voltage is a difference between two points. When the Arduino says "I output 5V," that 5V is relative to the Arduino's own GND. The battery-side circuit sees its voltage relative to the battery's own minus terminal. If the two reference points aren't connected, there's no shared scale between the two circuits.

Take the MOSFET's gate as an example. The condition for a MOSFET to turn on is that the voltage between gate and source exceeds the threshold voltage. The gate comes from the Arduino, and the source sits on the battery-side GND. With the two GNDs floating apart, the voltage between gate and source is undefined. With an undefined value opening and closing the switch, the symptom becomes "it works sometimes and doesn't other times."

What you actually observe is stranger still. The two circuits aren't fully isolated — they're weakly coupled through stray capacitance. So the electrical noise generated as the motor spins shakes the Arduino side's reference potential through that coupling. Touch it with your hand and the behavior changes; connect an oscilloscope probe and it suddenly goes normal. The probe's ground lead tied the two circuits together.

The rule is simple: the GNDs of circuits running on separate power supplies must meet at one point. You can split up the positive rails, but the negatives are shared.

One more practical tip here: it's better to keep the wire that ties the GNDs together separate from the thick wire carrying the motor's current. The GND wire carrying motor current has resistance too, and that creates a voltage drop. A thin 20-centimeter jumper wire has roughly 0.05 ohms, and if 1A flows through it:

0.05 ohm × 1A = 0.05V

50 millivolts appears between the two circuits' reference points. That's not a big deal for a logic signal, but if you're also reading an analog sensor at the same time, the reading will wobble by that much. The rule is to route the motor's GND back to the supply with a short, thick wire, and route the logic's GND separately, meeting the supply at that same point.

Switching with Transistors and MOSFETs

To have the pin only issue commands while the current comes from the supply, you need a switch. There are two kinds of semiconductor switches, and the criteria for picking one are clear.

BJT — Controlled by Current

A bipolar transistor passes a collector current proportional to the current fed into its base. To use it as a switch, you need to drive it into saturation, meaning fully on — which means you have to supply generous base current.

Say you're switching a single relay module. The coil current is 70mA. Using a small-signal transistor like the 2N3904, and being conservative rather than trusting the datasheet's current gain figure, estimate the gain at 10.

Base current needed = 70mA / 10 = 7mA

The base resistor is the pin voltage minus the base-emitter voltage drop of 0.7V, divided by that current.

Base resistor = (5V - 0.7V) / 0.007A = 614 ohm

Here's an important point: the rounding direction is the opposite of the LED resistor. With an LED, insufficient current is safe, so you round up. A base resistor needs to round down — if base current is insufficient, the transistor only half-turns-on, dissipating power in itself and getting hot. Below 614 ohms on the E24 series is 560 ohms.

Actual base current = (5V - 0.7V) / 560 ohm = 0.0077A = 7.7mA

7.7mA, inside the 20mA pin limit. Safe.

Even fully on, a BJT still has about 0.2V left between collector and emitter. That's the saturation voltage, and at 70mA the loss is:

0.2V × 0.07A = 0.014W = 14mW

Negligible.

MOSFET — Controlled by Voltage

As current climbs, the BJT becomes a bad choice. Switching 200mA needs 20mA of base current, which is the Arduino pin's entire limit. At 500mA you'd need 50mA, which is impossible outright.

A MOSFET turns on with just a gate voltage. The gate is insulated, so essentially no current flows once it's in a steady state — meaning a small pin can control a large current.

Here's the decisive detail: you must pick a logic-level MOSFET. An ordinary MOSFET is designed to fully turn on only with 10V on the gate — the well-known IRF540N is like this. Apply just 5V and it only half turns on, leaving significant resistance, and that resistance generates heat. Push 1A through it with a resistance of 0.5 ohm:

P = 1² × 0.5 = 0.5W

0.5W turns to heat in the MOSFET. Without a heatsink, it gets hot.

A logic-level MOSFET is designed to fully turn on with just 4.5V on the gate. The IRLZ44N is a classic example; this part's on-resistance at 5V gate drive is 0.028 ohm.

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

An 18x difference. That's the difference between IRF and IRLZ in a part's name.

But on a 3.3V board, you need one more level of caution. Even the IRLZ44N's specs aren't guaranteed at a 3.3V gate. On a Raspberry Pi or ESP32, you need to pick a part with a gate threshold explicitly specified at 2.5V or below. The AO3400 and IRLML2502 are commonly used for exactly this purpose.

Gate Resistor and Pull-Down Resistor

A MOSFET circuit needs two resistors added.

The gate resistor sits in series between the pin and the gate. A MOSFET's gate is a capacitor, so the instant it turns on, a large surge current flows to charge that capacitor. With no resistor, the only thing limiting that current is the pin's own internal resistance. Put in 220 ohms and:

Peak instantaneous gate current = 5V / 220 ohm = 0.0227A = 22.7mA

22.7mA. The duration is tens of nanoseconds, so an Arduino tolerates it, but a Pi has no margin to spare. At 3.3V with 470 ohms:

3.3V / 470 ohm = 0.007A = 7mA

7mA, safe. Make the gate resistor too large and switching gets slow, leaving the MOSFET stuck in a middle state for longer and generating heat during that stretch, so a practical range is 100 to 470 ohms.

A pull-down resistor goes between the gate and GND, roughly 10 kilohms. The reason is the same as the floating input from the earlier post. While the board is booting, and during a reset, GPIO pins sit at high-impedance input state. During that stretch, the gate is connected to nothing, and if ambient noise pushes the voltage up, the MOSFET turns on. In other words, the motor twitches for an instant the moment power is applied. The pull-down resistor holds the gate at 0V during that window.

Skip this one resistor and you get the symptom "the motor jerks once every time you power it on" — and on a robot, that single jerk can be enough to break an arm.

Flyback Diodes — The Physics of Inductive Kickback

Get this far and the switching circuit looks complete. And yet after flipping a relay on and off a few times, the MOSFET dies. Current and voltage both have plenty of margin on paper, and it still dies.

The cause is the coil.

Why Thousands of Volts Show Up

An inductor's fundamental nature is that it opposes a change in current. In equation form:

V = L × (di / dt)

L is inductance, and di/dt is the rate of change of current over time. What this equation says is that the faster you try to change the current, the larger a voltage the inductor generates to resist you.

Say the relay coil's inductance is 100 millihenries and 70mA is flowing. The MOSFET takes roughly 1 microsecond to turn off.

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

7000 volts. That's the calculated value, and in reality it stops at a lower value due to air-gap breakdown or component failure, but it's real — anywhere from hundreds to thousands of volts.

The direction of this voltage matters. The coil wants to keep pushing the current it had flowing, so it pushes up the potential of whichever side just got cut off. In other words, the MOSFET's drain voltage spikes far above the supply voltage. The IRLZ44N's maximum drain-to-source rating is 55V. Hit it with hundreds of volts and breakdown occurs, and repeatedly absorbing that breakdown energy eventually kills the part.

It's worth calculating the size of the energy too, to get a feel for it.

E = 0.5 × L × I² = 0.5 × 0.1 × 0.07² = 0.000245J = 245 microjoules

245 microjoules doesn't look like much, but release it within 1 microsecond and the instantaneous power is:

0.000245J / 0.000001 second = 245W

245 watts. Very brief, but it repeats every single time.

What the Diode Does

The fix is to give that energy somewhere to go. Add a diode in parallel with the coil. Point it in the direction that doesn't conduct under normal conditions — that is, connect the cathode (the banded end) to the positive supply, and the anode to the MOSFET's drain side.

Under normal conditions, the diode is reverse-biased and does nothing. The moment the MOSFET turns off and the coil pushes the voltage up, once the drain voltage rises above the supply voltage by the diode's forward voltage, the diode starts conducting. Then the coil's current circulates back to the coil itself through the diode. With somewhere to go, there's no longer any reason for the voltage to keep climbing.

The drain's maximum voltage at that point is:

Supply voltage + diode forward voltage = 5V + 0.7V = 5.7V

7000V becomes 5.7V. For what a single component does, that's a dramatic difference.

The circulating current gets consumed as heat in the coil's own resistance and gradually dies down. That 245 microjoules quietly disappears over a few milliseconds.

Choosing a Diode, and the Side Effects

There are criteria for which diode to use.

The current rating needs to be at or above the coil current. At 70mA, a 1N4148's 200mA would work, but people often go with a 1A 1N4007 to leave margin.

The reverse-voltage rating needs generous margin above the supply voltage. The 1N4007 is rated 1000V, plenty for any low-voltage circuit.

Recovery speed matters in some cases. When you use PWM to control motor speed, you're switching thousands of times per second, and a general-purpose rectifier diode like the 1N4007 takes several microseconds to switch back to reverse-blocking, causing losses during that stretch. In that case, use a Schottky diode like the 1N5819 instead. Its forward voltage is also lower, at 0.3V, giving a lower clamp voltage too.

The side effects are worth knowing too. Adding the diode lengthens how long it takes the relay to release, because the coil current now dies down slowly. It's usually a few milliseconds, but if the contacts release later, the arc lasts longer, shortening contact life. In circuits where this matters, the diode gets a resistor or a zener diode added in series to raise the clamp voltage a bit, as a compromise.

And finally, when you buy a relay module or motor driver board as a finished product, this diode is often already built into the board. You only need to remember it when you're switching a coil with your own transistor directly. Still, it's safer to check by eye whether it's on the board or not.

Motor Driver ICs and the H-Bridge

Everything so far can only turn a motor on and off. To reverse direction, you have to flip the direction of current, and that takes four switches. This structure is called an H-bridge, because its shape resembles the letter H.

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

  Turn on S1 and S4 and current flows left to right,
  turn on S2 and S3 and it flows right to left.
  Turn on S1 and S3 at the same time and the supply shorts to GND.

That last line is exactly why you don't build an H-bridge yourself. If the top and bottom switch on the same side turn on at once, the supply shorts out — this is called shoot-through current. MOSFETs turn on and off at different speeds, so in the gap between turning one off and turning the other on, both can end up briefly on at the same time. Real designs handle this by inserting dead time, and getting that exactly right in software is risky.

So in practice, you use a driver IC.

PartChannelsCurrent per channelTypeNotes
L293D2600mABJTOld standard, large ~2V voltage drop
L298N22ABJTCommon module, ~2V voltage drop, needs a heatsink
DRV883321.5AMOSFETSmall voltage drop, good for compact robots
TB6612FNG21.2AMOSFETReplacement for the L298N, efficient
A4988 / DRV88251 stepper axis1–2AMOSFETStepper-dedicated, adjustable current

The L298N module is the most common, but there's something worth knowing. Because it's BJT-based internally, it drops roughly 1V per direction, nearly 2V combined. Off a 6V supply, what actually reaches the motor is 4V — a third gets lost as heat inside the driver. When using small motors in the 3V class, that loss is deadly, making the DRV8833 or TB6612FNG the better choice.

Relay Modules and Optocoupler Isolation

For loads that need to be fully electrically isolated from the microcontroller — household AC appliances, 12V lighting — a relay is the tool.

A relay works by running current through a coil to make an electromagnet, and using that force to move a mechanical contact. There's physical space between the contact and the coil, so the two are completely electrically separated. Even with 220V on the contact side, the coil side stays entirely within its own 5V world.

Off-the-shelf relay modules usually also include an optocoupler. This adds one more layer of isolation — inside is an LED facing a phototransistor. The signal is converted to light and carried across, so there's no electrical connection whatsoever between the two circuits.

There's something practically important here: a jumper on the module. Most relay modules have pins labeled VCC, GND, and JD-VCC, with a jumper bridging between them. With that jumper installed, the relay coil also draws its power from the microcontroller's 5V. Even with the optocoupler present, sharing the power supply erases the point of the isolation.

There's a practical problem too. The relay coil draws 70mA. On a 4-channel module, if all four turn on at once:

70mA × 4 = 280mA

280mA. That's a significant chunk of an Arduino 5V rail's 450mA limit, and the current swing as the relays turn on shakes the 5V rail, destabilizing the board.

Doing it right means pulling the jumper and connecting a separate 5V supply to JD-VCC. Then coil current comes from the separate supply, and the microcontroller only supplies a few milliamps to the optocoupler's LED. And in this case, the two supplies' GNDs must NOT be tied together, or isolation is lost. This is the one exception to the rule from earlier that GND must always be tied together — the reason being that the optocoupler transfers a signal without ever sharing a reference point.

One more thing: many relay modules are active-low. You have to give the IN pin a LOW for the relay to engage. So while the board is booting, if the pin is floating, the relay can briefly engage and then release. For a light, that just flickers; for a heater or motor, it's a real problem. The pull-up resistor from the earlier post comes back into play here.

Decoupling Capacitors and Brownout — This Isn't a Code Problem

Let's finally return to this post's opening paragraph: the board rebooting every time the motor turns on.

Even after building the switching circuit correctly and adding a separate power supply, this symptom often lingers. The cause is the resistance in the power wiring.

Every wire has resistance. A 1-meter USB cable's power line is roughly 0.2 ohms, breadboard contact resistance is 0.01 to 0.05 ohms per contact, and a jumper wire is around 0.05 ohms. Add it all up and you get roughly 0.3 ohms.

Say the current flowing when the motor starts up is 1.5A:

Voltage drop = 1.5A × 0.3 ohm = 0.45V

A 5.1V incoming supply becomes 4.65V by the time it reaches the board.

A Raspberry Pi throws an undervoltage warning once its 5V rail drops below 4.63V, and falls further and SD card access fails or it reboots. The Arduino's ATmega328P has a brownout detection circuit that forces a reset if the voltage drops below 2.7V under default settings. Feed a 5V regulator 4.65V and its output drops even lower, and a bigger startup current pushes it past that threshold.

This is exactly why the symptom looks like code. The reset happens while the code is running, and the boot message shows up on serial. It looks like a completely software problem.

What a Capacitor Can and Can't Do

The response happens on two layers.

Put a 100 nanofarad ceramic capacitor right next to each IC's power pin. This supplies fast current fluctuations on a nanosecond-to-microsecond timescale. When transistors inside a chip switch, they need a burst of current instantly, and pulling that from the supply is too slow because of wiring inductance. A tiny capacitor sitting right there fills in that instant.

Put a 470 microfarad electrolytic capacitor near the motor's power input. This smooths out larger swings on a millisecond timescale. Let's calculate how much it actually helps. To supply 1A of extra current for 100 microseconds while holding the voltage drop to 0.2V, the capacitance needed is:

C = I × Δt / ΔV = 1A × 0.0001 second / 0.2V = 0.0005F = 500 microfarads

500 microfarads. 470 microfarads is close enough.

But a motor's startup time isn't 100 microseconds — it's several milliseconds. Recalculate for 5 milliseconds:

C = 1A × 0.005 second / 0.2V = 0.025F = 25000 microfarads

25,000 microfarads. That's not a component you're plugging into a breadboard.

What this calculation tells you is clear. A capacitor smooths short spikes — it isn't a substitute for insufficient power. If brownouts keep happening, the fix isn't a bigger capacitor, it's changing the power source itself.

The Actual Order of Troubleshooting

When this symptom shows up, here's the order to check things.

First, check whether the motor's power supply and the logic power supply are separated. If both are being pulled from the same USB source, that's the cause.

Second, switch to thick, short wires. The power path through a breadboard accumulates contact resistance, so for high-current paths, solder directly or connect with thick wire instead.

Third, add capacitors. Put 100 nanofarads across the motor's terminals on both sides, and 470 microfarads at the motor's power input. The ceramic capacitor at the motor terminals also suppresses high-frequency noise coming from the brushes.

Fourth, add a soft start. Ramping speed up gradually with PWM lowers the peak startup current. This is the only mitigation you can implement purely in code.

// Drives a MOSFET gate with PWM to start a motor gradually.
// Wiring: D9 -> 220 ohm -> MOSFET gate, 10k pull-down between gate and GND
//         Motor on separate power supply, a 1N5819 flyback diode in parallel with the coil
//         The two supplies' GNDs meet at a single point

const int MOTOR_PWM_PIN = 9;
const int RAMP_STEP_MS = 12;     // Wait time between each step
const int TARGET_DUTY = 200;     // 0 to 255. Final speed

void setup() {
  pinMode(MOTOR_PWM_PIN, OUTPUT);
  analogWrite(MOTOR_PWM_PIN, 0);
  delay(500);                    // Wait for the supply to stabilize
}

void softStart() {
  // Ramps from 0 to the target over roughly 2.4 seconds.
  // Jump straight to 255 and the full startup current flows at once, collapsing the rail.
  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);
}

Don't mistake this code for the fundamental fix, though. Soft start only lowers the peak of the startup current, and once the motor hits a load and stalls, the stall current flows exactly as before. If the supply can't handle that current, the same symptom shows up again.

Once you've wired everything up and want to check whether your current budget adds up, drop your parts into this site's circuit wiring validator. For parts needing separate power, like servo motors or LED strips, it flags peak current and recommends a separate supply, and it also calculates whether the 5V rail total exceeds your board's supply limit.

Conclusion — The Pin Issues Commands, and Power Comes From the Supply

The accidents covered in this post look different on the surface: a pin burning up, a board rebooting, a MOSFET dying, a relay briefly engaging on boot.

But they all come from the same misunderstanding: treating a GPIO pin as if it were a power supply.

A pin is a signal line that opens and closes a switch. The switch that signal controls is what passes the large current from the supply to the load. Keep this structure intact and the magnitude of the current has nothing to do with the pin at all. Whether it's 1A or 10A, all the pin does is charge a gate with a few milliamps.

And an inductive load has one more thing added on top. A coil hates the instant its current gets cut off, and it expresses that displeasure with thousands of volts. Build that energy a path in advance with a diode, and it quiets down to 5.7V. The difference between forgetting one diode and including it is a factor of a thousand.

Everything covered across these five posts ultimately converges on three numbers: how many volts land on this component, how many milliamps flow through it, and what value can this pin actually handle. Nearly every mistake that quietly wrecks hardware in a circuit comes from not checking one of these three. Building the habit of writing these three numbers down on paper before connecting a component beats reading ten schematics.