部品 · 読了まで14分

フォトカプラとは?PC817と4N35を使ったArduinoの絶縁

フォトカプラとは何か、どう動くのかを解説します。PC817と4N35のピン配置、CTRと抵抗の計算、12/24 V信号の読み取り、商用電源の検知(H11AA1)、リレーとMOC3021も紹介します。

フォトカプラ(オプトアイソレーター、光結合素子とも呼ばれます)は、2つの回路を電気的につなぐことなく、光だけで信号を伝える小さなICです。内部には赤外線LEDと、それに向き合うフォトトランジスタがあります。片側の回路がLEDを光らせると、反対側のトランジスタがオンになります。両側の間には1本の配線もないため、24 Vの産業用センサーや車の12 Vライン、モータードライバをArduinoにつないでも、電圧サージやノイズがマイコンまで届きません。

この記事では、フォトカプラの内部構造、ガルバニック絶縁が重要な理由、もっともよく使われる2つのモデルPC817と4N35のピンと定格、CTRの考え方と抵抗の計算をステップごとに学びます。続いて、Arduinoの出力を絶縁する方法、12/24 V信号を安全に読み取る方法、ESP32とRaspberry Pi Picoでの使い方、商用電源の検知(H11AA1)の安全ルール、リレーモジュールのフォトカプラ、MOC3021によるトライアックの駆動を紹介します。

フォトカプラとは?どのように動作する?

フォトカプラのパッケージの中には、向かい合った2つのチップがあります。入力側には、ふつうのLEDと同じように電流で光る赤外線LEDがあります。出力側には、ベースが光に反応するフォトトランジスタがあり、ベースに電流を流す代わりに光を当てます。2つのチップの間には、透明でありながら電気を通さないプラスチックの層があります。この層は数千ボルトに耐えるように設計されています。

  1. 入力側の回路が、抵抗を通してLEDに数mAの電流を流します。
  2. LEDが赤外線を出し、その光が絶縁層を通り抜けてフォトトランジスタに当たります。
  3. 光がフォトトランジスタのベース電流のように働き、コレクタとエミッタの間に電流が流れます。トランジスタがスイッチのように閉じます。
  4. LEDが消えると光が止まり、トランジスタは再び電流を遮断して出力回路が開きます。こうして信号は配線なしで、光だけで反対側に伝わります。

出力側に何があるかによって、フォトカプラにはいくつかの種類があります。ホビー用途ではフォトトランジスタ出力のモデルが主に使われますが、AC信号の検知、トライアックの点弧、高速なデータラインの絶縁には専用の種類が必要です。

種類代表的なモデル出力主な用途
フォトトランジスタ出力PC817, EL817, 4N35, 4N25NPNフォトトランジスタデジタル信号の絶縁、12/24 V入力の読み取り、リレーモジュール
ダーリントン出力4N33, H11B1ダーリントントランジスタごく小さなLED電流で大きな出力電流(ただし低速)
AC入力H11AA1, PC814逆並列の2個のLED+フォトトランジスタ商用電源の検知、ゼロクロス検出
トライアック出力MOC3021, MOC3041, MOC3063フォトトライアックトライアックの点弧、AC負荷の制御、SSR
高速ロジック6N137, 6N138フォトダイオード+論理ゲートまたはトランジスタMIDI、UART、高速なデジタルラインの絶縁

なぜガルバニック絶縁が必要?

ガルバニック絶縁とは、2つの回路の間に直接の導電経路がないことを意味します。共通のGNDも共通の配線もなく、エネルギーと情報は別の方法(光、磁界)で伝わります。Arduinoのピンが耐えられるのは最大5 V(ESP32とPicoでは3.3 V)です。産業用センサーの24 V、モーターのスイッチング時に出る数百ボルトの短いサージ、長いケーブルに誘導されるノイズは、共通のGNDを通ってマイコンに直接届くことがあります。フォトカプラはこの経路を物理的に断ち切ります。

  • 保護:高電圧側で故障が起きても、被害はフォトカプラで止まり、Arduinoもパソコンのusbポートも、そして自分自身も安全です。
  • ノイズとグラウンドループ:モーター、リレー、長いケーブルはGNDラインにノイズを生みます。グラウンドが分かれていれば、そのノイズは信号ラインに入りません。共通グラウンドについては「GNDと共通グラウンド」の記事でくわしく解説しています。
  • 異なる電圧レベル:出力トランジスタは外部から電源を受けるので、24 Vの信号を3.3 Vに、5 Vの信号を12 Vに簡単に変換できます。フォトカプラは、低速ですが丈夫なレベル変換素子でもあります。
  • 安全規格:商用電源につながる機器では、ユーザー側を商用電源から絶縁することが義務づけられています。PC817のような部品は5000 V rmsの絶縁試験に合格しています。
絶縁が機能するのは、両側のGNDが分かれたままのときだけです。「念のため」と24 V側のマイナスをArduinoのGNDにつなぐと、フォトカプラはただの高価な配線になり、保護はまったくなくなります。入力側はそれ自身の電源で、出力側はArduinoで動かしてください。

PC817と4N35のピン配置と定格

ピンPC817(DIP-4)4N35(DIP-6)
1アノード(LED +)アノード(LED +)
2カソード(LED −)カソード(LED −)
3エミッタ未接続
4コレクタエミッタ
5なしコレクタ
6なしベース(通常は未接続のまま)
項目PC8174N35
LEDの順方向電圧(VF)標準1.2 V、最大1.4 V(20 mA時)約1.2〜1.3 V
LEDの最大電流50 mA60 mA
LEDの逆方向電圧最大6 V最大6 V
CTR50〜600%(5 mA、5 V時、ランクによる)100%以上(10 mA、10 V時)
コレクタ-エミッタ間電圧(VCEO)35 V70 V
コレクタ電流最大50 mA最大50 mA
スイッチング時間標準3〜4 µs(小さい負荷抵抗の場合)約10 µs
絶縁耐圧5000 V rms5000 V rms

PC817では1番ピンに丸印が付いています。パッケージの「PC817」の後ろにあるA、B、C、Dの文字はCTRのランクを示します。EL817、LTV817、KP1010などはPC817とピン互換の互換品です。4N35は6本足なのでベースピンが外に出ています。通常は未接続のままにしますが、ノイズの多い環境では、ベースとエミッタの間に高抵抗(例:1 MΩ)を入れるとターンオフを速くできます。

CTRとは?抵抗はどう計算する?

CTR(Current Transfer Ratio、電流伝達率)は、出力トランジスタが流せるコレクタ電流とLED電流の比です:CTR = IC / IF × 100%。たとえばCTRが100%のフォトカプラなら、LEDに5 mA流すと出力から最大で約5 mAを引き出せます。CTRは温度で変化し、LEDの劣化によって年々下がり、同じモデルの部品の間でも大きくばらつきます。そのため、設計では必ずデータシートの最小値を基準にします。

PC817のランクCTRの範囲(IF = 5 mA)LED電流5 mA時の出力電流
PC817A80〜160%4〜8 mA
PC817B130〜260%6.5〜13 mA
PC817C200〜400%10〜20 mA
PC817D300〜600%15〜30 mA
文字なし50〜600%2.5〜30 mA(最悪の値を想定)

LEDの抵抗:入力側はLEDとまったく同じように計算します:R = (V電源 − VF) / IF。Arduino Unoの5 Vピンから10 mA流すには(5 − 1.2) / 0.010 = 380 Ωとなります。標準値の330 Ωなら約11.5 mA、390 Ωなら約9.7 mAです。ESP32では(3.3 − 1.2) / 0.010 = 210 Ωなので、220 Ωを使います。Raspberry Pi Picoのピンは初期設定で駆動能力4 mAになっています。ここでは470 Ωで約4.5 mAあれば十分です。手で計算したくなければ、「LED用抵抗」ツールを使ってください。

出力側(プルアップ)の抵抗:トランジスタが完全にオン(飽和)になるには、プルアップ抵抗が引き込む電流がCTRで許される電流より小さくなければなりません。5 Vにつないだ10 kΩのプルアップに必要なのはわずか0.5 mAです。文字なしのPC817では最悪のCTRが50%なので、0.5 mAならLEDに1 mA流せば足ります。5〜10 mA流せば、少なくとも5倍の余裕が生まれます。Arduinoの内部プルアップ(約20〜50 kΩ)もこの用途に最適です。プルアップを小さくすると信号は速くなりますが、必要な電流が増えます。大きくすると電流は減りますが、トランジスタのターンオフが遅くなります。

用途電源電圧目標のLED電流おすすめの抵抗抵抗の電力
Arduino Unoのピンから駆動5 V~10 mA330 Ω1/4 Wで十分
ESP32のピンから駆動3.3 V~10 mA220 Ω1/4 Wで十分
Raspberry Pi Picoのピンから駆動3.3 V~4.5 mA470 Ω1/4 Wで十分
12 V信号の読み取り12 V~5 mA2.2 kΩ1/4 W(消費は0.05 W)
24 V信号の読み取り24 V~5 mA4.7 kΩ1/4 W(消費は0.11 W)
同じ入力で12 Vと24 Vの両方を読む必要があるなら、4.7 kΩを選んでください。24 Vでは約4.8 mA、12 Vでは約2.3 mA流れます。CTRが50%でも、2.3 mAは内部プルアップに必要な0.1〜0.25 mAを大きく上回るので、同じ回路でどちらの電圧でも確実に動作します。

配線表:Arduino Uno、ESP32、Raspberry Pi Pico

PC817のピン役割Arduino UnoESP32Raspberry Pi Pico
1(アノード)、出力の絶縁ボードがLEDを駆動D9 → 330 Ω → ピン1GPIO 25 → 220 Ω → ピン1GP15 → 470 Ω → ピン1
2(カソード)、出力の絶縁LEDの戻りGNDGNDGND
4(コレクタ)、入力の読み取りボードが信号を読み取るD2(INPUT_PULLUP)GPIO 27(INPUT_PULLUP)GP14(PULL_UP)
3(エミッタ)、入力の読み取り読み取り側のGNDGNDGNDGND
1と2、入力の読み取り外部の信号(12/24 V)ボードではなく外部電源につなぐボードではなく外部電源につなぐボードではなく外部電源につなぐ
もっとも多い間違いは、LEDを抵抗なしでつなぐことです。1番と2番ピンに5 Vを直接かけると、LEDは数秒で焼損します。次に多いのが部品の逆挿しです。LEDの逆方向耐圧は6 Vしかないので、12 Vや24 Vを逆につなぐと壊れます。入力に1N4148ダイオードを逆向き(カソードをアノード側)に並列に入れれば、このリスクはなくなります。

Arduinoの出力を絶縁する

この使い方では、Arduinoがフォトカプラ内のLEDを光らせ、出力側のトランジスタがスイッチのように別の回路の入力を短絡します。たとえば12 V機器の「トリガー」入力、カメラのリモートシャッター入力、PLCの入力、別の電圧で動く別のマイコンなどを、この方法で安全に駆動できます。出力トランジスタは35 V・50 mAまでなので、リレーのコイルやモーター、LEDテープを直接は駆動できません。こうした負荷には、反対側にトランジスタやMOSFETを使います。

C++ (Arduino IDE)
1// PC817 ile yalıtılmış çıkış / Isolated output with a PC817
2// D9 -> 330 ohm -> PC817 pin 1 (anot / anode), pin 2 (katot / cathode) -> Arduino GND
3// Pin 4 ve 3 diğer devrenin girişini kısa devre eder (kuru kontak gibi)
4// Pins 4 and 3 short the other circuit's input (like a dry contact)
5const int OPTO_LED_PIN = 9;
6const unsigned long ON_MS = 2000;
7const unsigned long OFF_MS = 3000;
8
9bool isOn = false;
10unsigned long lastSwitch = 0;
11
12void setup() {
13  pinMode(OPTO_LED_PIN, OUTPUT);
14  digitalWrite(OPTO_LED_PIN, LOW);
15}
16
17void loop() {
18  unsigned long waitTime = isOn ? ON_MS : OFF_MS;
19  if (millis() - lastSwitch >= waitTime) {
20    lastSwitch = millis();
21    isOn = !isOn;
22    digitalWrite(OPTO_LED_PIN, isOn ? HIGH : LOW);   // HIGH: optokuplör iletir / HIGH: optocoupler conducts
23  }
24}

出力側では、コレクタ(4番ピン)を相手の回路のプラス側または入力に、エミッタ(3番ピン)をその回路のGNDにつなぎます。極性が逆だとトランジスタは導通しません。PC817はオン・オフに数µsから数十µsかかるため、通したPWM信号は数kHzを超えると波形がくずれ始めます。高速な信号(UART、MIDI、高周波のPWM)には、6N137のような高速フォトカプラやデジタルアイソレーターICが選ばれます。

12/24 V信号を安全に読み取る

産業用の近接センサー(誘導型)、PLCの出力、ドアの接点、車のイグニッションスイッチ、12 Vの玄関チャイムのボタンなどから来る信号は、Arduinoのピンに直接はつなげません。解決策は、信号をフォトカプラのLEDに通すことです。24 VならLEDに直列に4.7 kΩ、12 Vなら2.2 kΩの抵抗を入れ、出力トランジスタはArduinoの内部プルアップで動かします。電圧がかかるとLEDが光り、トランジスタが導通してArduinoのピンはLOWを読みます。つまり論理が反転するので、コードでそれを考慮します。

  1. 24 V電源のプラスを、4.7 kΩの抵抗を通してPC817の1番ピン(アノード)につなぎます。
  2. 信号源のマイナス(24 VのGND)を2番ピン(カソード)につなぎます。このGNDはArduinoにつながないでください。
  3. 必要に応じて、1番と2番ピンの間に1N4148ダイオードを逆向きに入れます(カソードを1番ピン側)。逆接続から保護できます。
  4. PC817の4番ピン(コレクタ)をArduinoのD2ピンに、3番ピン(エミッタ)をArduinoのGNDにつなぎます。
  5. 下のコードを書き込み、シリアルモニタを9600ボーで開きます。24 Vをかけると「24V VAR / present」(VARはトルコ語で「ある」)と表示されるはずです。
C++ (Arduino IDE)
1// PC817 ile 12/24 V sinyal okuma / Reading a 12/24 V signal with a PC817
2// PC817 pin 4 (kolektör / collector) -> D2, pin 3 (emetör / emitter) -> Arduino GND
3const int OPTO_PIN = 2;
4const unsigned long DEBOUNCE_MS = 20;    // kontak sıçramasına karşı / against contact bounce
5
6int lastReading = HIGH;
7int stableState = HIGH;
8unsigned long lastChange = 0;
9unsigned long pulseCount = 0;
10
11void setup() {
12  Serial.begin(9600);
13  pinMode(OPTO_PIN, INPUT_PULLUP);       // dahili pull-up yeterli / internal pull-up is enough
14}
15
16void loop() {
17  int reading = digitalRead(OPTO_PIN);
18  if (reading != lastReading) {          // değişim var, zamanı başlat / change seen, start the timer
19    lastChange = millis();
20    lastReading = reading;
21  }
22  if (millis() - lastChange > DEBOUNCE_MS && reading != stableState) {
23    stableState = reading;
24    // Mantık ters: 24 V varsa LED yanar, transistör iletir, pin LOW olur
25    // Inverted logic: with 24 V present the LED is on, the transistor conducts, the pin reads LOW
26    if (stableState == LOW) {
27      pulseCount++;
28      Serial.print("24V VAR / present, sayac / count: ");
29      Serial.println(pulseCount);
30    } else {
31      Serial.println("24V YOK / absent");
32    }
33  }
34}

このコードには、20 msの間変化しなかった読み取り値だけを受け付ける簡単なチャタリング対策が入っています。機械式の接点やリレーからの信号では必須です。delay()ではなくmillis()で読み取っているので、その間にArduinoは別の処理もできます。車の電装系では、エンジン稼働中に12 Vラインが14.4 Vまで上がり、短い高電圧のサージも発生します。ここでは抵抗を3.3 kΩに上げ、入力にTVSダイオードを追加しておくと安心です。

ESP32とRaspberry Pi Picoでのフォトカプラ

ESP32とPicoは3.3 Vで動くので、5 Vの信号でさえ直接つないではいけません。ここでフォトカプラの良さが生きます。出力トランジスタはオープンコレクタなので、出力電圧はプルアップをつないだ電圧だけで決まります。内部プルアップを使えば出力は自動的に3.3 Vにとどまり、入力側が24 VでもESP32に届くのは最大3.3 Vです。下のESP32のコードは、24 Vの近接センサーや流量計からのパルスを割り込みで数えます。

C++ (Arduino IDE)
1// ESP32: 24 V endüstriyel sensörden darbe sayma / counting pulses from a 24 V industrial sensor
2// PC817 pin 4 -> GPIO 27, pin 3 -> ESP32 GND
3const int OPTO_PIN = 27;
4
5volatile unsigned long pulseCount = 0;
6volatile unsigned long lastPulseUs = 0;
7
8void IRAM_ATTR onPulse() {
9  unsigned long now = micros();
10  if (now - lastPulseUs > 2000) {        // 2 ms'den kısa parazitleri yok say / ignore glitches shorter than 2 ms
11    pulseCount++;
12    lastPulseUs = now;
13  }
14}
15
16void setup() {
17  Serial.begin(115200);
18  pinMode(OPTO_PIN, INPUT_PULLUP);
19  attachInterrupt(digitalPinToInterrupt(OPTO_PIN), onPulse, FALLING);   // 24 V gelince pin düşer / pin falls when 24 V arrives
20}
21
22void loop() {
23  static unsigned long lastPrint = 0;
24  if (millis() - lastPrint >= 1000) {
25    lastPrint = millis();
26    noInterrupts();
27    unsigned long count = pulseCount;
28    pulseCount = 0;
29    interrupts();
30    Serial.printf("Saniyedeki darbe / Pulses per second: %lu\n", count);
31  }
32}

割り込み関数の前にあるIRAM_ATTRは、コードを高速なメモリに配置します。ESP32の割り込み関数ではこれを付けることが推奨されています。2 msのフィルタは、フォトカプラのゆっくりしたターンオフやケーブルのノイズによる偽のパルスを取り除きます。割り込みについては「Arduinoの割り込み」の記事も見てください。Raspberry Pi PicoではMicroPythonで同じことを次のように行います。この例は入力を読みながら、2個目のPC817で反対側に絶縁された信号も送ります。

MicroPython
1# Raspberry Pi Pico: PC817 ile yalıtılmış giriş / isolated input with a PC817
2# PC817 pin 4 -> GP14, pin 3 -> Pico GND, LED sürme / LED drive: GP15 -> 470 ohm -> pin 1
3from machine import Pin
4import time
5
6opto_in = Pin(14, Pin.IN, Pin.PULL_UP)     # dahili pull-up / internal pull-up
7opto_out = Pin(15, Pin.OUT)                # ikinci PC817'nin LED'i / LED of a second PC817
8
9last_state = opto_in.value()
10while True:
11    state = opto_in.value()
12    if state != last_state:
13        time.sleep_ms(20)                  # sıçramayı bekle / wait out the bounce
14        state = opto_in.value()
15        if state != last_state:
16            last_state = state
17            if state == 0:                 # ters mantık: 0 = gerilim var / inverted: 0 = voltage present
18                print("24V VAR / present")
19                opto_out.value(1)          # karşı tarafa yalıtılmış sinyal / isolated signal to the other side
20            else:
21                print("24V YOK / absent")
22                opto_out.value(0)
23    time.sleep_ms(5)

商用電源の検知:H11AA1と安全

230 Vの商用電源は命にかかわります(日本の商用電源は100V(50/60Hz)です)。経験がなければ、商用電源につながる回路を自作しないでください。市販の、ケースに収められた認証済みのAC検知モジュールを使いましょう。商用電源側を絶対にブレッドボードに挿さないこと、通電中はどこにも触れないこと、回路全体をヒューズとともに絶縁ケースに収めることを守ってください。

コンセントや照明のラインに電圧が来ているか、または商用電源のゼロクロスのタイミングを検出するには、H11AA1のようなAC入力のフォトカプラを使います。内部には逆並列につながった2個のLEDがあるので、交流の両方の半波で光り、逆電圧の問題もありません。230 V rmsの場合、入力に47 kΩの抵抗を2本直列に入れます。合計94 kΩに約2.4 mA rms(ピークで3.5 mA)流れ、抵抗1本あたり約0.28 Wを消費します。そのため最低でも0.5 W、できれば1 Wの抵抗を選びます。抵抗を2本にすると、1本あたりにかかる電圧も半分になります。出力側は5 Vにつないだ10 kΩのプルアップで、電圧がある間トランジスタはほとんど導通しています。ゼロクロス付近でLEDが消えたときだけ、短いHIGHパルスが現れます。50 Hzの商用電源では、1秒に約100個のパルスが見えます(西日本の60 Hzなら約120個です)。

C++ (Arduino IDE)
1// H11AA1 ile şebeke gerilimi var mı? / Is mains voltage present? (H11AA1)
2// H11AA1 pin 5 (kolektör / collector) -> D2, pin 4 (emetör / emitter) -> GND, 10k pull-up -> 5V
3const int AC_PIN = 2;
4const unsigned long TIMEOUT_MS = 40;     // 50 Hz'de 2 tam periyot / 2 full cycles at 50 Hz
5
6volatile unsigned long pulses = 0;
7unsigned long lastLowSeen = 0;
8unsigned long lastReport = 0;
9
10void onZeroCross() {
11  pulses++;                              // her sıfır geçişinde bir darbe / one pulse per zero crossing
12}
13
14void setup() {
15  Serial.begin(9600);
16  pinMode(AC_PIN, INPUT);                // harici 10k pull-up kullanılıyor / external 10k pull-up in use
17  attachInterrupt(digitalPinToInterrupt(AC_PIN), onZeroCross, RISING);
18}
19
20void loop() {
21  if (digitalRead(AC_PIN) == LOW) {
22    lastLowSeen = millis();              // gerilim varken çıkış çoğunlukla LOW / output is mostly LOW while voltage is present
23  }
24  bool mainsOn = (millis() - lastLowSeen) < TIMEOUT_MS;
25
26  if (millis() - lastReport >= 1000) {   // saniyede bir rapor / report once per second
27    lastReport = millis();
28    noInterrupts();
29    unsigned long count = pulses;
30    pulses = 0;
31    interrupts();
32    Serial.print(mainsOn ? "Sebeke VAR / Mains ON" : "Sebeke YOK / Mains OFF");
33    Serial.print("  sifir gecisi / zero crossings: ");
34    Serial.print(count);                 // 50 Hz'de yaklaşık 100 / about 100 at 50 Hz
35    Serial.print("  frekans / frequency: ");
36    Serial.print(count / 2);
37    Serial.println(" Hz");
38  }
39}

このコードは2つの情報を返します。直近40 msの間に出力が一度でもLOWになれば、商用電源は通電しています。また、割り込みで数えたパルス数の半分が商用電源の周波数になります。市販のモジュールでも自作の基板でも注意すべき点は次のとおりです。商用電源側のパターンと低電圧側の間に少なくとも6〜8 mmの距離(沿面距離)を取ること、商用電源の入力にヒューズを入れること、フォトカプラの両側の間には一切パターンを通さないこと、回路は閉じたケースの中で使うことです。

リレーモジュールのフォトカプラとJD-VCCジャンパー

フォトカプラ入力のリレーモジュール
多くのリレーモジュールは入力側にPC817のフォトカプラを搭載しています。完全に絶縁するにはJD-VCCジャンパーを外す必要があります。

市販の1、2、4、8チャンネルのリレーモジュールの多くは、各チャンネルの入力にPC817を備えています。VCCピンからの電流は抵抗と表示用LEDを通ってフォトカプラのLEDへ流れ、INピンをLOWにすると回路が完成してリレーがオンになります。そのため、こうしたモジュールはたいていアクティブLOWで動作します。ただし出荷時はJD-VCCジャンパーが付いていて、リレーのコイルも同じVCCとGNDから給電されます。フォトカプラはあっても、絶縁はされていません。リレーモジュールの基本は「リレーモジュールとは?」の記事で紹介しています。

設定配線絶縁
JD-VCCジャンパーありArduinoの5V → VCC、GND → GND、ピン → INなし。リレーコイルのノイズがArduinoの電源に入る
ジャンパーを外した状態Arduinoの5V → VCC、ピン → IN。ArduinoのGNDはつながない。別の5 V電源 → JD-VCCとGND完全。両側が共有するのはフォトカプラ内部の光だけ

MOC3021でトライアックを駆動するときの注意

リレーの代わりに、静かで火花の出ないACスイッチがほしい場合は、トライアック(例:BT136)と、それを駆動するトライアック出力のフォトカプラを使います。MOC3021はランダム位相型で、LEDが光った瞬間にトライアックを点弧します。そのため、ゼロクロス検出回路と組み合わせて調光器(明るさ調整)を作るのに向いています。MOC3041とMOC3063はゼロクロス回路内蔵のモデルで、電圧がゼロを通過するときだけ点弧します。オン・オフ用途ではノイズが少なくなりますが、調光には使えません。MOC3021のLEDは点弧に最大15 mAを必要とする場合があります。5 Vなら220 Ω(約17 mA)が適した値で、330 Ωでは部品によって足りないことがあります。データシートのとおり、トライアックのゲートとMOC3021の間には約360 Ωの抵抗を入れ、モーターのような誘導性負荷ではトライアックの両端にRCスナバを追加します。市販のSSR(ソリッドステートリレー)モジュールの中身も、まさにこの構成です。

フォトカプラを使ったプロジェクトのアイデア

  • 産業用センサーの読み取り:24 Vの誘導型近接センサーでコンベア上の製品を数え、LCDに表示します。
  • 車のイグニッション検出:イグニッションがオンになったらESP32を起こし、車載カメラやロガーを起動します。
  • 停電アラーム:市販のAC検知モジュールを使い、商用電源が切れたらブザーを鳴らしたり、スマホに通知を送ったりします。
  • 玄関チャイムのキャッチャー:既存の12 Vのチャイムのラインを絶縁して読み取り、鳴ったら通知を送ります。
  • 絶縁されたリレーボード:JD-VCCジャンパーを外し、別の電源で給電したリレーモジュールで230 Vのランプを制御します。
  • MIDI入力:6N138を使い、電子楽器からのMIDIノートをArduinoで読み取ります。

よくある間違いと対処法

症状考えられる原因対処法
出力がまったく変化しないLEDが逆につながっている、または抵抗なしでつないで焼損した1番ピンが丸印の位置か確認し、テスターのダイオードレンジでLEDを測る
論理が反転して動く電圧がかかるとピンがLOWになる。これは正常コードでLOWを「あり」として扱う
出力が完全にLOWにならない(1〜2 Vのまま)LED電流が小さい、CTRが足りない、またはプルアップが小さすぎるLEDの抵抗を小さくするか、プルアップを大きくする(例:10 kΩ)
PWM信号の波形がくずれるPC817は数kHzを超えると遅すぎるプルアップを小さくするか、6N137のような高速フォトカプラを使う
絶縁しているのにArduinoがリセットする両側のGNDがつながっている入力側のGNDをArduinoから切り離す。リレーモジュールではJD-VCCジャンパーを外す
ランダムに誤動作する長いケーブル、ノイズ、接点のチャタリングソフトでチャタリング対策をする、ケーブルを短くする、LEDの両端に100 nFのコンデンサを入れる
フォトカプラのいちばん簡単なテスト方法は、LED側に330 Ωを通して5 Vを与え、テスターを抵抗レンジにしてコレクタとエミッタの間につなぐことです。LEDが点灯中は低い抵抗、消灯中はとても高い抵抗が見えるはずです。この簡単なテストで、不良品を回路に組み込む前に見つけられます。

フォトカプラは、Arduinoのプロジェクトを机の上から実世界へ持ち出し、12 V、24 V、230 Vの信号と安全にやり取りさせるための、もっとも安い方法です。数十円の部品が、ボードとパソコンを高電圧から切り離してくれます。BlueGraysアプリでは、リレーで230 Vの電球を制御するプロジェクト、スマート照明、水やりのプロジェクトを、回路図とコード付きでステップごとに紹介しています。

よくある質問

フォトカプラは何に使いますか?

フォトカプラは、2つの回路の間で電気的な接続なしに、光で信号を伝えます。これにより、高電圧の回路やノイズの多い回路を、Arduinoのような繊細なマイコンから絶縁できます。産業用センサーの読み取り、リレーモジュール、商用電源の検知回路などで使われます。

PC817のピン配置は?

PC817は4本足です。丸印のある角の1番ピンがLEDのアノード、2番ピンがカソードです。反対側の3番ピンがフォトトランジスタのエミッタ、4番ピンがコレクタです。

フォトカプラには何Ωの抵抗を使えばいいですか?

抵抗はR = (電源電圧 − 1.2 V) / LED電流で求めます。Arduinoの5 Vピンなら330 Ω、ESP32なら220 Ω、12 V信号なら2.2 kΩ、24 V信号なら4.7 kΩが、最初に試すのによい値です。

フォトカプラのCTRとは何ですか?

CTR(電流伝達率)は、出力トランジスタが流せる電流とLED電流の比です。CTRが100%のフォトカプラでは、LEDに5 mA流すと出力から最大で約5 mAを引き出せます。設計では必ずデータシートの最小のCTRを基準にしてください。

PC817と4N35の違いは何ですか?

どちらもフォトトランジスタ出力のフォトカプラです。PC817は4本足で安く、CTRはランクによって50〜600%です。4N35は6本足でベースピンが外に出ており、最大70 Vのコレクタ電圧に耐えます。

フォトカプラで230 Vの商用電源を検知できますか?

はい、H11AA1のようなAC入力のフォトカプラと、適切な電力定格の直列抵抗を使えば、商用電源の電圧とゼロクロスを検知できます。ただし商用電源は命にかかわるので、経験がなければ市販の、ケースに収められたAC検知モジュールを使ってください。

全プロジェクトを見る
ボタンを押している間だけ220V電球を点灯
#19上級
プレミアム

ボタンを押している間だけ220V電球を点灯

ボタンを押している間は実際の220ボルトの電球が点灯し、離すとすぐに消灯します。Arduinoの小さな信号では電球を直接点灯できないため、電気で動くスイッチであるリレーを間に入れ、電球の回路を開閉します。ボードで家庭の照明を操作するための第一歩です。家庭用電源を扱う際は十分に注意し、不安がある場合は詳しい人に手伝ってもらってください。

4.4(30)
38
ボタンを押すたびに220V電球の点灯・消灯を切り替え
#20上級
プレミアム

ボタンを押すたびに220V電球の点灯・消灯を切り替え

小さなボタンで、家庭の電球を点灯・消灯してみませんか?ボタンを押すとArduinoがリレーを切り替えて電球を点灯させ、もう一度押すと消灯させます。リレーは、ボードの弱い信号で家庭用電源を安全に切り替える仲介役です。220ボルトを扱う際は、必ず大人に手伝ってもらってください。

4.5(33)
44
リモコンで220V電球を点灯・消灯
#21上級
プレミアム

リモコンで220V電球を点灯・消灯

ソファに座ったまま、テレビのリモコンで家庭の電球を点灯・消灯します。Arduinoがリモコンから届く目に見えない光の信号を読み取り、電源ボタンを押すとリレーを動かして電球を点灯させ、消音ボタンを押すと消灯させます。家庭用電源を扱うため、配線は大人と一緒に、必ずプラグを抜いた状態で行ってください。

4.4(22)
30
階段・廊下のスマート照明
#82中級
プレミアム

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

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

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

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

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

4.3(6)
11
スマート水やりステーション
#83上級
プレミアム

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

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

5.0(42)
57
ESP32 PIR人感センサーによる自動照明
#121中級
プレミアム

ESP32 PIR人感センサーによる自動照明

このプロジェクトでは、HC-SR501 PIR人感センサーで部屋に入った人を検知し、LEDを自動で点灯させます。millis()で点灯時間を管理します。センサーの値がHIGHの間は最後に動きを検知した時刻を更新し、最後にHIGHを読み取ってから少なくとも10秒後にLEDを消灯します。現在のコードは各ループでdelay(50)により50 ms待機するため、完全にノンブロッキングではありません。階段や廊下、浴室、戸棚内の照明などに応用できます。

4.4(24)
38