部品 · 読了まで19分

Arduino MOSFETガイド:12VのLEDテープ、モーター、ポンプを制御する

ArduinoでMOSFETを使う方法を解説します。ロジックレベルのIRLZ44NとIRF520の違い、ゲート抵抗とプルダウン抵抗、フライバックダイオード、12VのLEDテープ・モーター・ポンプ用のPWMコードまで。

Arduino MOSFET回路は、20 mA程度しか流せないArduinoのピンで、12 VのLEDテープ、DCモーター、水ポンプ、ソレノイドロックのように数アンペアを消費する負荷をオン・オフする最も効率のよい方法です。MOSFETは電圧で制御する電子スイッチです。ゲートに5 Vを加えるとドレインとソースの間はほぼ抵抗ゼロの導線のようになり、0 Vでは完全に遮断されます。適切に選んだロジックレベルMOSFETなら、ヒートシンクなしで3 Aの負荷を流しても少し温かくなる程度です。

このガイドでは、MOSFETの仕組み、すべてのMOSFETがArduinoに向いているわけではない理由(IRLZ44NとIRF520の違い)、ゲート抵抗・プルダウン抵抗・フライバックダイオードの役割、PWMで速度や明るさを調整する方法を学びます。さらに後半には、12 VのLEDテープ、DCモーター、ポンプ、ソレノイド用のすぐに使えるコード、ESP32とRaspberry Pi Picoの例、発熱とヒートシンクの計算、MOSFET・トランジスタ・リレーの比較表があります。

MOSFETとは?仕組みを解説

MOSFET(Metal-Oxide-Semiconductor Field-Effect Transistor、金属酸化膜半導体電界効果トランジスタ)は、ゲート、ドレイン、ソースの3本の足を持つ電界効果トランジスタです。ゲートは薄い酸化膜で素子のほかの部分から絶縁されているため、定常的な電流は流れ込まず、小さなコンデンサのようにふるまいます。ゲートとソースの間の電圧(VGS)が一定のしきい値を超えると、ドレインとソースの間に導電性のチャネルができ、負荷電流がそこを流れます。従来のBJTトランジスタはベース電流で駆動しますが、MOSFETは電圧で駆動します。Arduinoのピンが電流を供給するのは、ゲートを充放電する数マイクロ秒の間だけです。

Arduinoのプロジェクトでは、ほぼ必ずNチャネルMOSFETを負荷のマイナス(GND)側に置きます。これをローサイドスイッチングといいます。負荷のプラス側の線は外部電源のプラス端子に直接つなぎ、マイナス側の線はMOSFETのドレインに、ソースはGNDにつなぎます。こうすると、ゲート・ソース間の電圧はそのままArduinoのピンの電圧になります。データシートで確認すべき値は次のとおりです。

パラメーター意味IRLZ44Nの値
VDSドレイン・ソース間が耐えられる最大電圧。電源電圧の少なくとも1.5〜2倍は欲しい55 V
ID連続ドレイン電流。ケースを25 °Cに保った場合だけの値で、実際にははるかに少ない電流で使う47 A(VGS = 10 V)
VGS(th)チャネルが導通し始めるゲート電圧(流れるのはわずか250 µA)。完全にオンになる電圧ではない1.0〜2.0 V
RDS(on)完全にオンのときのドレイン・ソース間抵抗。発熱を決める値で、測定時のVGSが非常に重要22 mΩ(10 V)、25 mΩ(5 V)、35 mΩ(4 V)
VGS(最大)ゲートに加えてよい最大電圧。超えると酸化膜が破壊される±16 V
Qgゲートを完全にオンにするのに必要な電荷。大きいほどスイッチングが遅くなる48 nC
ボディダイオード構造上、ソースからドレインに向かって内蔵されているダイオード。誘導性負荷の保護にはならないあり(すべてのパワーMOSFETにある)

ロジックレベルMOSFET:IRLZ44N、IRF520など

最もよくある間違いは、VGS(th)を見て「しきい値は4 V、Arduinoは5 Vを出すから動くはず」と考えることです。しきい値は、チャネルがわずか250 µAを流す点にすぎません。MOSFETが低い抵抗で数アンペアを流すには、ゲート電圧がしきい値を十分に上回っている必要があります。正しい問いは「データシートはどのVGSでRDS(on)を保証しているか?」です。4.5 Vか5 Vで規定されていれば、そのMOSFETは5 VのArduinoで完全にオンになり、ロジックレベルMOSFETと呼ばれます。10 Vでしか規定されていなければ標準MOSFETで、Arduinoのピンでは半分しかオンになりません。International Rectifier(現在のInfineon)の命名では、IRLで始まる部品(IRLZ44N、IRLB8721、IRL540N)がロジックレベルで、IRFZ44N、IRF520、IRF540Nは標準品です。

型番(パッケージ)VDS連続IDRDS(on)(測定条件)VGS(th)Arduino Uno(5 V)ESP32 / Pico(3.3 V)
IRLZ44N(TO-220)55 V47 A25 mΩ(VGS = 5 V)1.0〜2.0 V非常に良い。ヒートシンクなしで3 Aまで通常は2〜3 Aまでだが保証はない
IRLB8721(TO-220)30 V62 A16 mΩ(VGS = 4.5 V)1.35〜2.35 V非常に良い通常は2〜3 Aまでだが保証はない
AO3400A(SOT-23、SMD)30 V5.7 A48 mΩ(VGS = 2.5 V)0.65〜1.45 V良い。小さな負荷向け(約2 A)非常に良い。2.5 Vでも保証あり
IRFZ44N(TO-220)55 V49 A17.5 mΩ(VGS = 10 Vのみ)2.0〜4.0 V不向き。半分しかオンにならない使用不可
IRF520とそのモジュール(TO-220)100 V9.2 A0.27 Ω(VGS = 10 Vのみ)2.0〜4.0 V約1 Aまで使用不可
IRF540N(TO-220)100 V33 A44 mΩ(VGS = 10 Vのみ)2.0〜4.0 V不向き。半分しかオンにならない使用不可

表から導けるルールは単純です。Uno、Nano、Megaのような5 Vのボードでは、RDS(on)が4.5 Vか5 Vで規定されているMOSFETを選びます。ESP32やPicoのような3.3 Vのボードでは少し難しくなります。IRLZ44NやIRLB8721のような定番のTO-220 MOSFETのデータシートは、3.3 Vでの値を何も保証していないからです。これについてはESP32の節で改めて説明します。パッケージで選ぶのもやめましょう。IRLZ44NとIRFZ44Nは同じパッケージで刻印もほとんど同じですが、たった1文字(L)の違いがArduinoにとってはすべてを変えます。ピンの並びはトランジスタのピン配置一覧ツールで確認できます。TO-220のMOSFETでは、印字面を手前に向けたとき左からゲート、ドレイン、ソースの順で、金属のタブはドレインにつながっています。

Arduino MOSFETの配線:ゲート抵抗、プルダウン、GNDの共通化

基本回路の部品は5つです。MOSFET、ゲート抵抗、プルダウン抵抗、誘導性負荷用のフライバックダイオード、そして外部電源です。下の表は3種類のボードでの配線を示しています。負荷の例は12 VのLEDテープまたはモーターです。この記事のコードはすべてこのピンを使います。

接続Arduino UnoESP32Raspberry Pi Pico
制御ピン → ゲート抵抗 → ゲートD9(PWM)、220 ΩGPIO 25、100 ΩGP15、100 Ω
ゲートとGNDの間のプルダウン10 kΩ10 kΩ10 kΩ
ソースGNDGNDGND
ドレイン負荷のマイナス(−)側の線負荷のマイナス(−)側の線負荷のマイナス(−)側の線
負荷のプラス(+)側の線12 Vアダプターのプラス12 Vアダプターのプラス12 Vアダプターのプラス
12 Vアダプターのマイナス(−)ArduinoのGND(共通GND)ESP32のGND(共通GND)PicoのGND(共通GND)
推奨MOSFETIRLZ44NIRLZ44N(2〜3 Aまで)またはAO3400AIRLZ44N(2〜3 Aまで)またはAO3400A

ゲート抵抗(100〜220 Ω)は、ゲート容量が充電される間にピンから流れる瞬間的な電流を制限します。IRLZ44Nの入力容量は約1700 pFで、抵抗がないと、切り替わるたびにピンは一瞬ショートに近い状態になり、ゲートのラインにリンギングが起き始めます。220 Ωなら、ピーク電流は最大でも5 / 220 ≈ 23 mAで、それでもゲートは数マイクロ秒以内に充電されます。プルダウン抵抗(10 kΩ)は、ピンが入力状態のとき、つまりArduinoの起動中、リセット中、新しいスケッチの書き込み中に、ゲートが浮いた状態になるのを防ぎます。浮いたゲートはノイズを拾って中途半端に充電されることがあり、するとMOSFETは半分オンの状態になって、モーターが勝手に回り、すぐに過熱します。プルダウン抵抗はゲート抵抗のMOSFET側、つまりゲートとソースの間に直接入れてください。そうすれば制御線が外れてもMOSFETはオフのままです。2つの抵抗は小さな分圧回路になりますが、影響は無視できる程度です。ゲートに届くのは5 × 10000 / 10220 ≈ 4.89 Vです。

GNDの共通化を忘れずに:12 VアダプターのマイナスがArduinoのGNDにつながっていないと、ゲート電圧にはソースに対する基準がなく、MOSFETはオンになりません。負荷をArduinoの5Vピンから給電するのは絶対にやめましょう。モーターやLEDテープには専用の電源が必要です(詳しくはGNDとグラウンドの共通化)。ドレインとソースを逆につなぐとMOSFETのボディダイオードが導通し、ピンの状態に関係なく負荷が動き続けます。

フライバックダイオード:モーター、ポンプ、ソレノイドに必要な理由

1N4007タイプのフライバックダイオード
1N4007タイプの整流用ダイオード:誘導性負荷と並列に逆向きにつなぎます。本体の帯がカソードを示し、電源のプラス(+)側につなぎます。

モーター、ポンプ、ソレノイド、リレーのコイル、ファンのような誘導性負荷は、電流が急に止まることに逆らいます。MOSFETがオフになった瞬間、コイルに蓄えられた磁気エネルギーが、ドレインに電源電圧をはるかに超える電圧スパイクとして放出されます(V = L × di/dt)。このスパイクがMOSFETのVDS定格を超えて素子を壊したり、Arduinoをリセットさせるノイズを生んだりします。対策は、負荷と並列に逆向きにダイオードをつなぐことです。カソード(帯のある側)を電源のプラスに、アノードをドレインにつなぎます。通常動作ではダイオードには逆バイアスがかかり、電流は流れません。MOSFETがオフになると、コイルの電流はダイオードを通って循環し、穏やかに減衰します。MOSFETのボディダイオードは負荷と並列ではなく、ソースとドレインの間にあるので、この役目は果たせません。詳しくはダイオードとは?を参照してください。

負荷と駆動方法推奨ダイオード理由
ソレノイド、リレーのコイル(オン・オフのみ)1N4007(1 A、1000 V)遅いダイオードだが、ときどき切り替える程度なら十分
PWMで駆動する小型ポンプやモーター(1 Aまで)1N5819ショットキー(1 A、40 V)高速。PWMの周期ごとに導通する
PWMで駆動する大きめのモーター(1〜3 A)1N5822またはSS34ショットキー(3 A、40 V)PWMがオフの間、ダイオードにモーターの全電流が流れる
12 VのLEDテープ、抵抗式ヒーター不要コイルがないので電圧スパイクも出ない

ステップごとに解説:Arduinoで12 VのLEDテープを調光する

  1. 部品をそろえる:Arduino Uno、IRLZ44N、220 Ωと10 kΩの抵抗、10 kΩのポテンショメーター、12 VのLEDテープ、そしてテープの電流をまかなえる12 Vアダプターを用意します。
  2. テープの電流を計算する:1 mあたり60個のLEDが付いた5050テープは1メートルあたり約14.4 Wを消費し、12 Vでは1.2 Aになります。2メートルなら2.4 Aが必要なので、20%の余裕を見てアダプターを選びます(3 A以上)。
  3. MOSFETを配置する:IRLZ44NのソースをGNDのラインに、ゲートを220 Ωを介してD9につなぎ、ゲートとGNDの間に10 kΩを入れます。
  4. 負荷をつなぐ:テープの+12Vの線はアダプターのプラスに、マイナスの線はMOSFETのドレインにつなぎます。ブレッドボードの接点が扱えるのは1 A程度です。それ以上の電流なら、ネジ端子を使うか負荷の線をはんだ付けしてください。
  5. ポテンショメーターをつなぐ:両端の足を5VとGNDに、中央の足をA0につなぎます。
  6. GNDをつないでテストする:アダプターのマイナスをArduinoのGNDにつなぎ、コードを書き込んでから、アダプターを接続します。
C++ (Arduino IDE)
1// IRLZ44N ile 12 V LED şerit parlaklık kontrolü / 12 V LED strip dimming with an IRLZ44N
2const int STRIP_PIN = 9;    // PWM pini, 220 Ω ile gate'e / PWM pin, to the gate via 220 Ω
3const int POT_PIN = A0;     // potansiyometre orta ucu / potentiometer wiper
4
5void setup() {
6  pinMode(STRIP_PIN, OUTPUT);
7  digitalWrite(STRIP_PIN, LOW);             // açılışta kapalı / off at startup
8  Serial.begin(9600);
9}
10
11void loop() {
12  int pot = analogRead(POT_PIN);            // 0–1023
13  float x = pot / 1023.0;                   // 0.0–1.0
14  int duty = (int)(x * x * 255.0 + 0.5);    // basit gama düzeltmesi / simple gamma correction
15  analogWrite(STRIP_PIN, duty);             // D9'da 490 Hz PWM / 490 Hz PWM on D9
16  Serial.print("Parlaklik / Brightness: %");
17  Serial.println(duty * 100 / 255);
18  delay(50);
19}

analogWrite()は9番ピンに、1秒間に約490回オン・オフを繰り返すPWM信号を出力します。0は完全にオフ、255は完全にオンです。UnoのPWMピンは3、5、6、9、10、11で、5番と6番ピンは約980 Hzで動作します。目は明るさを直線的には感じないので、ポテンショメーターの値を2乗する(簡単なガンマ補正)と、暗い領域でずっとなめらかに調整できます。PWMの詳細はPWMとは?にあります。発熱も確認しておきましょう。2.4 AのときIRLZ44Nが消費する電力はP = I² × RDS(on) = 2.4² × 0.025 ≈ 0.14 Wなので、触ってもぬるい程度です。一方、LEDテープ自体は28.8 Wを使うので、MOSFETでの損失は全体の1%未満です。

PWMによるDCモーターとポンプの速度制御

6 Vのミニ水中ポンプ
6 Vのミニ水中ポンプ:内部に小さなDCモーターが入っているので、MOSFETで駆動するときは必ず端子間にフライバックダイオードを付けてください。

モーターやポンプの駆動もLEDテープと同じ回路を使います。違いは、負荷と並列にフライバックダイオードを追加することだけです。モーターには突入電流もあります。止まっているモーターは、回り始めの瞬間に動作中の電流の3〜8倍を流すことがあります。そのため、MOSFETと電源はモーターのストール電流に合わせて選び、0からいきなり255にせずソフトスタートを使ってください。ミニ水中ポンプは3〜6 Vで約0.1〜0.3 A、12 Vのダイヤフラムポンプは通常0.5〜1 Aを消費します。IRLZ44Nはどちらも十分な余裕をもって扱えます。ただし、ミニポンプは12 Vアダプターからではなく、ポンプ自体の電圧(5〜6 V)の電源から給電してください。MOSFETの回路は同じです。ポンプの選び方や水やりの詳細はミニ水ポンプを参照してください。

C++ (Arduino IDE)
1// IRLZ44N ile motor/pompa hız kontrolü ve yumuşak kalkış / Motor or pump speed control with soft start (IRLZ44N)
2const int MOTOR_PIN = 9;     // 220 Ω ile gate'e / to the gate via 220 Ω
3const int POT_PIN = A0;      // hız ayarı / speed setting
4const int MIN_DUTY = 60;     // bunun altında motor yalnızca vızıldar / below this the motor only hums
5
6int current = 0;             // şu anki PWM değeri / current PWM value
7
8void setup() {
9  pinMode(MOTOR_PIN, OUTPUT);
10  digitalWrite(MOTOR_PIN, LOW);
11  // TCCR1B = (TCCR1B & 0b11111000) | 0x02;   // isteğe bağlı: D9/D10 PWM ≈3,9 kHz / optional: D9/D10 PWM ≈3.9 kHz
12}
13
14void loop() {
15  int target = map(analogRead(POT_PIN), 0, 1023, 0, 255);
16  if (target < MIN_DUTY) target = 0;         // çok düşük hızda tamamen durdur / stop completely at very low speed
17
18  if (current < target) current++;           // yavaşça hızlan / speed up gently
19  else if (current > target) current--;      // yavaşça yavaşla / slow down gently
20
21  analogWrite(MOTOR_PIN, current);
22  delay(8);                                  // 0→255 yaklaşık 2 s / 0→255 takes about 2 s
23}

このコードは、ポテンショメーターから読んだ目標速度に向かって8 msごとに1段階ずつ近づくので、モーターは約2秒で0から最高速度に達し、突入電流で電源の電圧が下がることもありません。MIN_DUTYはモーターが回り始める最小のPWM値です。手元のモーターで試して見つけてください。490 HzのPWMでは、モーターから耳に聞こえる「キーン」という音が出ます。コメントアウトされたTCCR1Bの行は、D9とD10の周波数を約3.9 kHzに上げます。ServoライブラリもTimer1を使うので、2つを同時に使わないでください。周波数をさらに上げたくなりますが、Arduinoのピンは切り替わるたびに大きなMOSFETのゲートを充電するのに数マイクロ秒かかるため、スイッチング損失は周波数とともに増えます。20 kHz前後では、2 Aのモーターでも、MOSFETに1 W以上の損失が生じることがあります。こうした周波数ではTC4427のようなゲートドライバを使います。

ソレノイドロックと短時間だけ動かす負荷

12 Vのソレノイドドアロックは0.5〜1 Aを消費し、多くは連続通電を前提に設計されていません。長時間オンのままにするとコイルが熱くなります。そのため、コードではロックを数秒間だけ開けておくようにします。ソレノイドはPWMで駆動せずオン・オフするだけなので、フライバックダイオードは1N4007で十分です。下の例では、D2のボタンを押すとロックが3秒間開き、その後はボタンを押し続けていても閉じます。RFIDカードリーダーやキーパッドでロックを動かすには、if文の条件を変えるだけです。ロックの種類や停電時の動作についてはソレノイドロックを参照してください。

C++ (Arduino IDE)
1// Butonla 3 saniyelik solenoid kilit açma / Open a solenoid lock for 3 seconds with a button
2const int LOCK_PIN = 9;                 // 220 Ω ile IRLZ44N gate'ine / to the IRLZ44N gate via 220 Ω
3const int BUTTON_PIN = 2;               // buton D2 ile GND arasında / button between D2 and GND
4const unsigned long OPEN_MS = 3000;     // kilidin açık kalma süresi / how long the lock stays open
5
6void setup() {
7  pinMode(LOCK_PIN, OUTPUT);
8  digitalWrite(LOCK_PIN, LOW);          // kilit kapalı / locked
9  pinMode(BUTTON_PIN, INPUT_PULLUP);    // basılınca LOW / LOW when pressed
10}
11
12void loop() {
13  if (digitalRead(BUTTON_PIN) == LOW) {
14    digitalWrite(LOCK_PIN, HIGH);       // solenoid çeker, kilit açılır / solenoid pulls in, lock opens
15    delay(OPEN_MS);
16    digitalWrite(LOCK_PIN, LOW);        // bobini soğumaya bırak / let the coil cool down
17    while (digitalRead(BUTTON_PIN) == LOW) {}   // buton bırakılana kadar bekle / wait until released
18    delay(50);                          // buton zıplamasını süz / debounce
19  }
20}

IRF520モジュールが5 Vで力不足な理由

スターターキットによく入っているIRF520 MOSFETモジュールは、ネジ端子付きの小さな基板で、「24 V、5 A」のような定格で売られています。MOSFETの横に抵抗がいくつかと表示用のLEDが載っており、ほとんどのバージョンにはフライバックダイオードがありません。問題はMOSFETそのものです。IRF520はしきい値2〜4 Vの標準MOSFETで、0.27 ΩというRDS(on)はVGS = 10 Vでしか保証されていません。データシートの代表特性カーブによると、ゲート電圧5 VではIRF520は2 A前後で電流を制限し始めます。しきい値が高い個体だと、この限界は1 Aを下回ります。こうなるとMOSFETはスイッチではなく、可変抵抗のようにふるまいます。

例を挙げましょう。2 Aを消費する12 VのモーターをIRF520モジュールで駆動するとします。MOSFETで1.5 Vの電圧降下があれば、消費電力はP = 1.5 × 2 = 3 Wです。ヒートシンクなしのTO-220パッケージの熱抵抗は62 °C/Wなので、周囲温度より約186 °C高くなります。MOSFETはすぐに過熱して壊れるか、よくてもモーターがゆっくり回るだけです。モジュールのラベルにある5 Aは、ゲートに10 Vを加えた場合にしか当てはまりません。モジュールの端子とつなぎ方は次のとおりです。

モジュールの端子接続先備考
SIGArduinoのPWMピン(例:D9)ゲート信号。3.3 Vのボードではほとんどオンにならない
VCCArduinoの5Vほとんどのバージョンではどこにもつながっていない。負荷電流はここを流れない
GND(ピンヘッダー)ArduinoのGNDGNDの共通化に必要
VINとGND(ネジ端子)外部電源の+と−負荷用の電源。モジュールは24 Vまで対応として売られている
V+とV−(ネジ端子)負荷の+と−モーターやポンプでは、V+とV−の間にダイオードを追加する(カソードをV+側に)
  • MOSFETを交換する:モジュールからIRF520のはんだを外し、同じピン配置(G-D-S)のIRLZ44Nをはんだ付けします。基板はまったく同じように動作しますが、今度は5 Vで完全にオンになります。
  • ロジックレベルのモジュールを使う:AOD4184A(D4184)MOSFETを使った既製モジュールは、4.5 VでのRDS(on)が最大9.5 mΩで、5 VのArduinoで余裕をもって動作します。
  • より高い電圧でゲートを駆動する:12 Vで動かすTC4427のようなゲートドライバを使うと、Arduinoの5 Vや3.3 Vの信号がゲートでは12 Vになり、IRF520が本来の性能を発揮できます。ゲート電圧は制限内に収めてください。IRF520は±20 V、IRLZ44Nは±16 Vです。
  • 小さな負荷ならそのまま使う:1 A未満(短いLEDテープ、ミニポンプ)なら、IRF520モジュールは5 Vでも許容できる発熱で動作します。MOSFETが触れないほど熱くなったら負荷を減らしてください。

ESP32とRaspberry Pi PicoでMOSFETを使う(3.3 V)

ESP32とPicoのピンは3.3 Vを出力するので、MOSFET選びはさらに重要になります。IRLZ44NのデータシートはRDS(on)を4 Vまでしか規定していません。代表特性カーブでは3 V前後でも数アンペアを余裕で流せますが、しきい値が高い個体ではそれが保証されません。実用的なルールはこうです。3.3 Vのボードでは、2〜3 AまでならIRLZ44NかIRLB8721を使い、負荷を動かしながらテスターでドレイン・ソース間の電圧を測って、P = VDS × Iで消費電力を計算します。ヒートシンクなしのTO-220なら1 W未満に抑えてください。それより大きな電流にはゲートを5〜12 Vに引き上げるドライバを、小さな負荷にはRDS(on)が2.5 Vで保証されているAO3400Aを使います。ESP32では、MOSFET用にGPIO 25、26、27、32、33のようなピンを選びましょう。GPIO 0、2、5、12、15はストラッピングピンで、GPIO 1、3、5、14、15は起動時に一瞬HIGHになったりPWMを出力したりすることがあります。これらのピンでは、起動時に負荷が予期せずオンになったり、プルダウン抵抗が起動を妨げたりすることがあります。

下のESP32のコードは、土壌水分センサーが乾燥を検出すると、MOSFETを通してポンプをソフトスタートで動かし、5秒間水やりをしてから穏やかに止めます。PWMにはESP32 Arduinoコア3.xのledcAttach()とledcWrite()関数を使います。古い2.xではledcSetup()とledcAttachPin()を代わりに使い、ledcWrite()はピンではなくチャンネル番号を受け取っていました。コード内の#ifの行がインストールされているコアに合った呼び出しを選ぶので、どちらのバージョンでもコンパイルできます。ゲートは100 Ωを介して3.3 Vで駆動するため、スイッチング損失を無視できる程度に抑えるよう、周波数は1 kHzにしています。土壌水分センサーの記事のように、自分の土で乾燥時と湿潤時のセンサーの値を測り、それに合わせてDRY_LEVELのしきい値を設定してください。

C++ (Arduino IDE)
1// ESP32 + MOSFET ile otomatik sulama pompası / Automatic watering pump with ESP32 + MOSFET
2const int PUMP_PIN = 25;                 // 100 Ω ile gate'e, gate–GND 10 kΩ / to the gate via 100 Ω, 10 kΩ gate–GND
3const int SOIL_PIN = 34;                 // toprak nem sensörü, ADC1 / soil moisture sensor, ADC1
4const int DRY_LEVEL = 2800;              // üstü kuru sayılır, kalibre et / above this counts as dry, calibrate
5const unsigned long WATER_MS = 5000;     // sulama süresi / watering time
6
7void pumpWrite(int duty) {               // 0–255 PWM, iki çekirdek sürümünde / on both core versions
8#if ESP_ARDUINO_VERSION_MAJOR >= 3
9  ledcWrite(PUMP_PIN, duty);             // 3.x: pin numarasıyla / 3.x: by pin number
10#else
11  ledcWrite(0, duty);                    // 2.x: kanal 0 ile / 2.x: by channel 0
12#endif
13}
14
15void pumpRamp(int from, int to) {        // yumuşak hız değişimi / smooth speed change
16  int step = (to > from) ? 5 : -5;
17  for (int d = from; d != to; d += step) {
18    pumpWrite(d);
19    delay(20);
20  }
21  pumpWrite(to);
22}
23
24void setup() {
25  Serial.begin(115200);
26#if ESP_ARDUINO_VERSION_MAJOR >= 3
27  ledcAttach(PUMP_PIN, 1000, 8);         // 1 kHz, 8 bit (0–255); çekirdek 3.x / core 3.x
28#else
29  ledcSetup(0, 1000, 8);                 // çekirdek 2.x: kanal 0 / core 2.x: channel 0
30  ledcAttachPin(PUMP_PIN, 0);
31#endif
32  pumpWrite(0);                          // pompa kapalı / pump off
33}
34
35void loop() {
36  int soil = analogRead(SOIL_PIN);       // 0–4095
37  Serial.printf("Toprak / Soil: %d\n", soil);
38  if (soil > DRY_LEVEL) {
39    pumpRamp(0, 255);                    // yaklaşık 1 s'de tam hıza / full speed in about 1 s
40    delay(WATER_MS);
41    pumpRamp(255, 0);                    // yumuşakça dur / stop gently
42    delay(60000);                        // suyun toprağa yayılmasını bekle / let the water soak in
43  }
44  delay(1000);
45}

Raspberry Pi Picoでは、MicroPythonでPWMを出すのにmachine.PWMクラスだけで十分です。duty_u16()は0〜65535の値を受け取ります。下のコードは、GP15のMOSFETにつないだ12 VのLEDテープに、なめらかな「呼吸」エフェクトを付けます。Arduinoの例と同じく値を2乗して簡単なガンマ補正をしているので、暗い状態から明るい状態への変化が自然に見えます。Picoのピンも3.3 Vを出力するので、ESP32で説明したMOSFETのルールがここでも当てはまります。

MicroPython
1# Pico + MOSFET ile 12 V LED şerit nefes efekti / 12 V LED strip breathing effect with Pico + MOSFET
2from machine import Pin, PWM
3import time
4
5strip = PWM(Pin(15))          # 100 Ω ile gate'e, gate–GND 10 kΩ / to the gate via 100 Ω, 10 kΩ gate–GND
6strip.freq(1000)              # 1 kHz: titreme görünmez / 1 kHz: no visible flicker
7
8def set_level(x):             # x: 0.0–1.0
9    strip.duty_u16(int(x * x * 65535))   # basit gama düzeltmesi / simple gamma correction
10
11while True:
12    for i in range(101):                 # yavaşça aydınlan / fade in
13        set_level(i / 100)
14        time.sleep_ms(20)
15    for i in range(100, -1, -1):         # yavaşça sön / fade out
16        set_level(i / 100)
17        time.sleep_ms(20)
18    time.sleep_ms(500)

発熱、電力の計算、ヒートシンクの選び方

完全にオンになったMOSFETの発熱は、P = I² × RDS(on)という1つの式で決まります。注意点は2つです。1つ目に、RDS(on)は温度とともに上昇します。IRLZ44Nでは100 °Cのとき25 °Cの値の約1.5倍になるので、計算には25 mΩではなく38 mΩを使うほうが現実的です。2つ目に、パッケージが空気中に逃がせる熱には限りがあります。ヒートシンクなしのTO-220の熱抵抗(RθJA)は62 °C/Wで、1 Wごとにチップの温度が周囲より62 °C上がるということです。下の表は、ゲート電圧5 V、ヒートシンクなしでIRLZ44Nがどれだけ熱くなるかを示しています。

負荷電流消費電力(38 mΩで計算)温度上昇(ヒートシンクなし)推奨
1 A0.04 W≈ 2 °Cヒートシンク不要
3 A0.34 W≈ 21 °Cヒートシンク不要、温かくなる
5 A0.95 W≈ 59 °Cぎりぎり。小型のヒートシンクを付ける
8 A2.4 W≈ 150 °Cヒートシンク必須
10 A3.8 W≈ 236 °Cフィン付きヒートシンクと放熱グリスが必須

ヒートシンクの選定も同じ考え方です。Tj = Tambient + P × (RθJC + RθCS + RθSA)。10 Aで3.8 Wを消費し、室温30 °Cでチップを100 °Cに保ちたいなら、熱抵抗の合計は(100 − 30) / 3.8 ≈ 18 °C/Wを超えてはいけません。IRLZ44Nのジャンクション・ケース間の熱抵抗は1.4 °C/W、放熱グリスを塗った接触面は約0.5 °C/Wなので、ヒートシンク自体は16 °C/W以下である必要があります。これは小型でもフィン付きのTO-220用ヒートシンクに相当します。MOSFETの金属タブはドレインにつながっているので、複数のMOSFETを同じヒートシンクに取り付ける場合は、マイカかシリコンの絶縁シートとプラスチックのネジ用ブッシュを使ってください。PWMでのもう1つの発熱源はスイッチング損失です。490 Hzでは無視できますが、周波数が上がるにつれて大きくなります。

MOSFETが完全にオンになっているかを確かめる最も簡単な方法は、負荷を動かしながらドレイン・ソース間の電圧を測ることです。IRLZ44Nなら3 Aで約0.1 Vのはずです。1 V以上あれば、MOSFETは半分しかオンになっておらず、ゲート電圧が低すぎます(標準MOSFET、3.3 Vのボード、ゲートの接続不良など)。消費電力はP = VDS × Iで計算でき、数値はオームの法則計算ツールで確認できます。

MOSFET、トランジスタ、リレーの比較

項目ロジックレベルMOSFET(IRLZ44N)BJTトランジスタ(2N2222A / TIP120)リレー(5 Vモジュール)
制御方法電圧で制御。ゲート電流は定常的には流れない電流で制御。ベース電流が常に流れる(2〜10 mA)コイル電流(約70 mA)で制御。モジュールのトランジスタが駆動する
オン時の損失I² × RDS(on):3 Aで約0.2〜0.3 WVCE(sat) × I:TIP120は3 Aで最大2 V、約6 W接点間ではほぼゼロ
電流容量数十アンペア(ヒートシンク使用時)2N2222Aは0.6 A、TIP120は5 A通常10 A(接点定格)
PWMによる速度・明るさの調整可能。kHz帯でも使える可能不可。オン・オフのみ
AC・商用電源不可。DCのみ不可。DCのみ可能。電気的に絶縁される
騒音と寿命無音で摩耗しない無音で摩耗しないカチッと音がする。接点寿命は約100,000回
最適な用途LEDテープ、モーター、ポンプ、ソレノイド(1〜10 AのDC)小さな負荷(1 Aまで)、リレーのコイル、ブザー照明、コンセント、AC機器

まとめると、DC負荷を高速に、静かに、PWMで制御したいならMOSFETを使い、商用電源の照明やコンセントをオン・オフするならリレーモジュールを使います。数百ミリアンペアの小さな負荷なら安価なBJTでも十分です。ベース抵抗の計算はトランジスタとは?にあります。同じモーターを両方向に回す必要がある場合、MOSFET 1個では足りません。4つのスイッチを持つHブリッジが必要なので、L298NモータードライバかMOSFETのHブリッジモジュールを使ってください。

MOSFETを使ったプロジェクトのアイデア

  • 自動で点く収納灯や階段灯:PIRセンサーが動きを検出したら、12 VのLEDテープをPWMでふわっと点灯させ、しばらくしたら消します。
  • 夕暮れランプ:LDRを使い、部屋が暗くなるにつれてテープの明るさを段階的に上げます。
  • スマートファン:DHT11で測った温度が上がるにつれて、12 VのPCファンの回転を速くします。
  • 植物の自動水やり:土壌水分センサーとMOSFETで駆動するポンプで、鉢に自動で水をやります。ポンプごとに別々のMOSFETを使ってください。
  • カードで開くドアロック:RFID RC522が正しいカードを読み取ったら、12 Vのソレノイドロックを3秒間開きます。
  • スマート温室:ファン、ポンプ、ヒーターをそれぞれ別のMOSFETで制御するスマート温室を作ります。

よくある失敗と対処法

症状考えられる原因対処
負荷がまったく動かないGNDが共通になっていない、またはG-D-Sの順番が違うアダプターのマイナスをArduinoのGNDにつなぎ、ピンの順番を確認する
負荷が動きっぱなしでオフにならないドレインとソースが逆(ボディダイオードが導通している)、またはMOSFETがショート故障している配線を直す。ドレイン・ソース間がどちらの向きでもショートと測定されるならMOSFETを交換する
MOSFETがとても熱くなり、負荷の力が弱い標準MOSFET(IRF520、IRFZ44N)が5 Vや3.3 Vで半分しかオンになっていないIRLZ44NのようなロジックレベルMOSFETか、ゲートドライバを使う
電源投入時や書き込み中にモーターが勝手に回るゲートが浮いている。プルダウン抵抗がないゲートとGNDの間に10 kΩを入れる
モーターが止まるとArduinoがリセットされるフライバックダイオードがない、またはモーターとArduinoが非力な電源を共有しているモーターと並列にショットキーダイオードを逆向きに追加し、モーターは別の電源から給電する
PWMでモーターから大きな「キーン」音がする490 HzのPWM周波数が可聴域にある3.9 kHzに上げる。20 kHzを超えるならゲートドライバを使う
NチャネルMOSFETをプラス側に置くと負荷の力が弱い負荷とともにソースの電位が上がり、VGSが小さくなるNチャネルはGND側に置く。ハイサイドスイッチングにはNPNのドライバとPチャネルMOSFETを使う
初めて回路を組むときは、負荷を小さくしておきましょう。12 VのLEDテープの前に1 kΩの抵抗付きのLEDで、ポンプの前に小さなモーターで試してください。Arduinoが何度もリセットされる場合、原因はたいてい電圧降下とノイズです。ステップごとの原因の切り分けはArduinoが何度もリセットされるときを参照してください。12 VアダプターからArduino用の5 Vを作りたい場合は、LM2596降圧モジュールが使えます。

MOSFETは、Arduinoを現実世界の大きな負荷につなぐ最もすっきりした方法です。適切に選んだロジックレベルの部品、ゲート抵抗、プルダウン抵抗、そして誘導性負荷用のダイオードがあれば、LEDテープからポンプまで、あらゆるDC負荷を静かに効率よく制御できます。BlueGraysアプリには、PWMによるLEDのフェード、ポテンショメーターでの明るさ調整、スマート水やりステーション、スマート照明といったプロジェクトがあり、ステップごとの回路図とコード付きなので、ここで学んだMOSFET回路をすぐに実際のプロジェクトにできます。

よくある質問

ArduinoにはどのMOSFETを使えばいいですか?

5 VのArduino Uno、Nano、Megaなら、RDS(on)が4.5 Vか5 Vで保証されているロジックレベルのNチャネルMOSFETを選びます。最も定番なのはIRLZ44Nで、55 Vに耐え、ゲート電圧5 Vでの抵抗はわずか25 mΩです。IRLB8721もよい選択ですが、IRFZ44N、IRF520、IRF540Nのような標準MOSFETは、完全にオンにするのに10 Vが必要です。

IRF520モジュールはArduinoで使えますか?

使えますが、制限があります。IRF520は標準MOSFETで、ゲート電圧5 Vでは通常2 A前後で電流を制限し始めるため、1 Aを超える負荷ではすぐに熱くなります。小さな負荷なら問題ありませんが、それ以上ならモジュールのMOSFETをIRLZ44Nに交換するか、ロジックレベルのモジュールを使ってください。

MOSFETのゲート抵抗はどのくらいの値にすればいいですか?

Arduinoなら100〜220 Ωのゲート抵抗が適しています。220 Ωなら、5 Vのときピンから流れる瞬間的な電流は約23 mAに制限されます。さらにゲートとGNDの間に10 kΩのプルダウン抵抗を入れると、電源投入時や書き込み中にMOSFETが勝手にオンになるのを防げます。

MOSFETで商用電源のAC電圧をオン・オフできますか?

Arduinoのプロジェクトでは、MOSFETはDC負荷にだけ使ってください。商用電源のACは1個のNチャネルMOSFETでは安全にオン・オフできず、そのような回路には絶縁がないため危険です。商用電源の照明やコンセントには、リレーモジュール、ソリッドステートリレー(SSR)、またはフォトカプラで駆動するトライアック回路を使ってください。

ESP32でMOSFETを駆動するにはどうすればいいですか?

ESP32のピンは3.3 Vを出力するので、低いゲート電圧でもしっかりオンになるMOSFETを選びます。IRLZ44Nは3.3 Vでも通常2〜3 Aまでならよく動作します。小さな負荷には2.5 Vで保証されたAO3400Aを、大電流にはゲートを12 Vに引き上げるドライバを使うほうが安全です。PWMにはledcAttach()とledcWrite()を使い、GPIO 25、26、27、32、33のように起動時に信号が出ないピンを選んでください。

MOSFETが熱くなるのはなぜですか?

完全にオンになったMOSFETの発熱はP = I² × RDS(on)で、IRLZ44Nなら3 Aでもわずか0.2〜0.3 Wです。MOSFETがとても熱くなる場合は、たいていゲート電圧が低すぎて半分しかオンになっていません。標準MOSFETを使っている、3.3 Vのボードで駆動している、PWMの周波数が高すぎる、といったことが最も多い原因です。ヒートシンクなしのTO-220で1 Wを超える電力を消費する場合は、ヒートシンクを付けてください。

全プロジェクトを見る
LDRで作る常夜灯
#12初級

LDRで作る常夜灯

暗くなると自動で点灯し、朝になると消灯する小さな常夜灯です。光センサーが部屋の明るさを測定し、Arduinoが十分に暗くなったらLEDを点灯させ、明るくなったら消灯させます。街灯が夕方になると自動で点灯する仕組みも理解できます。

4.8(102)
205
ESP32のPWMでLEDをフェード
#110初級

ESP32のPWMでLEDをフェード

LEDの明るさを0から最大へ、最大から0へと滑らかに変化させます。Arduinoと同じようにanalogWrite()でPWMを制御します。ESP32 Arduino Core 3.0+では同じ構文がそのまま使えます。ピンの定義とpinMode、analogWriteだけで実現できます。

4.8(36)
54
ESP32と可変抵抗でLEDの明るさを制御(アナログ→PWM)
#115中級
プレミアム

ESP32と可変抵抗でLEDの明るさを制御(アナログ→PWM)

可変抵抗を使ってLEDの明るさをアナログ操作で調整します。ESP32のADCピンで可変抵抗からの0-3.3Vの電圧を読み取り、PWM(パルス幅変調)信号に変換してLEDに出力します。可変抵抗を回すと、LEDが徐々に明るくなったり暗くなったりします。Arduino Core 3.0+ではanalogWrite()を直接使えます。ESP32-S2/S3ではADCの分解能を12ビットに固定します。

4.5(19)
32
Raspberry Pi PicoのPWMでLEDをフェード(呼吸のような明滅)
#160初級

Raspberry Pi PicoのPWMでLEDをフェード(呼吸のような明滅)

LEDを単に点滅させるだけでなく、呼吸するように明滅させます!Raspberry Pi PicoのPWM(パルス幅変調)を使い、スリープ中のMacBookのランプのように、明るさをゆっくり上げてからゆっくり下げます。machine.PWMクラス、duty_u16()(0–65535の16ビットの明るさ)、PWM周波数(freq(1000)で1秒間に1000回オン・オフし、ちらつきを感じさせない)、range()による段階的なループ(増加と減少)、デジタルピンからのアナログのような出力を学びます。PWMはRGBの混色やモーターなどに使われる、組み込み開発の基本技術です。

0.0(0)
4
スマート水やりステーション
#83上級
プレミアム

スマート水やりステーション

旅行中も植物が枯れないよう、自動で水やりをするシステムです。土壌水分センサーで土の湿り具合を測定し、乾燥するとArduinoが給水ポンプを数秒間動かして、青いライトを点灯させます。水分が適切なときは緑のライトが点灯します。土がひどく乾燥すると、赤いライトが点滅し、ブザーが鳴って知らせます。

5.0(42)
57
ESP32スマート照明(PIR + LDR + リレー + OLED)
#141上級
プレミアム

ESP32スマート照明(PIR + LDR + リレー + OLED)

ESP32で廊下やトイレ、食品庫の照明をスマート化します!PIRモーションセンサー、LDR光センサー、リレーモジュールを使い、「暗い場所で動きを検知すると点灯する」定番の仕組みを作ります。周囲が明るければ動きを検知しても点灯しないため、日中の無駄な電力消費を抑えられます。照明は30秒間点灯し、動きが続くとタイマーがリセットされて点灯時間が延びます。SSD1306 OLEDには大きな文字で状態(ON / DAYTIME / WAITING)とカウントダウンを表示します。

4.3(6)
11
階段・廊下のスマート照明
#82中級
プレミアム

階段・廊下のスマート照明

階段や廊下に足を踏み入れると、進む方向に沿って照明が1段ずつ点灯します。両端に距離センサーがあり、どちらの前を通っても、その端から8個のLEDが0.5秒間隔で順番に点灯し、その後、同じ方向に順番に消灯します。夜の暗がりで足元を照らす、おしゃれなホームオートメーションのアイデアです。

5.0(35)
51