今回作るのは、フォトカプラです。フォトカプラって何?ってところから紐解いてみましょう。
フォトカプラ(Photo-coupler)とは、電気信号を一旦光信号に変換して、それを再び電気信号に戻すことによって、デジタル信号を伝搬する素子を指します。
「フォト(photo-)」の代わりに「オプト(opto-)」、「カプラ(coupler)」の代わりに「アイソレータ(isolator)」に置き換えた呼び名が使われることがあります。オプトカプラとか、フォトアイソレータとか、ですね。
原理に戻ると、電気信号 → 光信号 → 電気信号と、最終的に電気信号として伝搬される信号を、何のためにわざわざ光信号に変換するの?ってことですが、やはり最大の目的は、「電気的に絶縁」すること、なのです。「電気的に絶縁」すると、何がうれしいかと言うと、ノイズの伝搬を抑止することができるのです。
MCUなどデジタル回路が動作すると、ものすごく沢山のノイズが発生しています。発生したノイズは、機器間を接続する信号線(ワイヤや基板上の配線)を通って、接続先の機器にも伝搬してしまいす。
そもそも、デジタル回路と言うのは、信号に多少ノイズが乗ったとしても誤動作しないように、LOWレベル(≒0V)と、HIGHレベル(≒5V)の二値で情報をやり取りし、その中央付近(5V+0V)/2=2.5V辺りに閾値を持って動作するので基本的にノイズを気にしません。
問題は、音声や音楽などのアナログ信号を取り扱う場合です。アナログ信号を生成する回路とMCU等のデジタル回路が電気的に接続されていると、どうしても配線を伝わってノイズがアナログ信号に乗っかってしまうのです。通常、音声や音楽などのアナログ信号はアンプを使って増幅してからスピーカなどで再生されるのですが、この時、ノイズ成分まで増幅されてしまうため音楽どころではなくなってしまいます……。
可能ならば、ノイズ源となるデジタル回路とアナログ回路の間を電気的に絶縁しておきたい理由がそこにあります。
その他、異電位システム間の信号のやり取り(レベルシフタみたいな使い方?)や、医療機器など人体に電極を接触して使う場合に、人体と機器の間を絶縁する目的(安全配慮)などで使用するみたいです🩺。
この節では、フォトカプラを工作して行きます。材料は、反射型赤外線センサTCRT5000L(下図)です。
この素子はIRエミッタ(IR LED)とIRディテクタ(IR photo-transistor)がセットになっていて、IRエミッタが発光した赤外線が、前方の障害物で反射して戻って来たところをIRディテクタで検知します。
※その他の用法については、「逆引き索引」から過去記事をご参照ください。
上の写真で丸く見えている物が、砲弾型のパッケージに収められたIRエミッタとIRディテクタです。プラスティックのケースでバラバラにならない様に固定されていますが、接着されているわけでは無いので、爪で上から押してあげると、するりと抜け落ちます。
写真からもわかる様に、IRディテクタは黒っぽく、IRエミッタは半透明の水色がかったパッケージになっています。バラした時には色で識別できます。問題は端子です。IRエミッタからはアノードとカソード端子、IRディテクタからはトランジスタのコレクタとエミッタ端子がそれぞれ出ているのですが、バラしてしまうと、どっちがどの端子かわからなくなってしまいます。
※今更ですが可視光LEDの場合、下図の様に足の短い方がカソードと決まっている(デファクト?)ので、足を切り落とすまでは、容易に見分けることができます。
そこで、後でわかるように油性ペンなどを使ってリードに印をつけた後で、プラスティックのケースから外します。
取り外した後でIRエミッタ、IRディテクタのサイズを計測したところ、以下図の様になっていました。
上図の様に、IRエミッタとIRディテクタを正対させて固定したいので、内径3mm程のパイプなどに挿入して固定します。
「内径3mmのパイプ」などと言う、都合の良いものが手元にあるかどうか?が一番の難関かも知れませんね(1^^;)。IRエミッタとIRディテクタの長さは3.5mm程なので、厚さ7〜8[mm](=3.5mm×2)程度のプラ板が有ったら、直径3mmのドリル(下図の様な)で穴を開けると、ピッタリサイズです。
柔らかい消しゴムなどを使って加工するなら、プラ板より更に工作の難易度を下げることができるでしょう。
筆者は、たまたま内径3mmのプラスティック製パイプが手元にありましたので、これを使います(下図)。
ブレッドボードに挿さるように足を90°折り曲げて完成です。
筆者が使ったプラスティック製のパイプは半透明なので、自然光に含まれる赤外線が外乱としてIRディテクタに入射するのを防ぐため、上から絶縁テープを巻いて遮光して使いました(上図は巻く前)。
手元にあった反射型赤外線センサ(TCRT5000L)を使いましたが、普通の可視光LEDとフォトトランジスタの組み合わせでも製作可能です。
使い方(回路等)は、以前反射型赤外線センサを使った時と似たようなものなのですが、改めて回路図を引いてみました(下図)。
以下、ポイントを解説します。
まず、基礎的な実験で特性を抑えておきたいと思います。前節の回路図で、入力Viの信号が出力Voにうまく伝搬するかどうか?を確かめておく必要があるので、Arduino UNOを入力側Viに接続し、STM32を出力側Voに接続して波形を観察します。
実験用の回路(ネットリスト)は以下の通りです。
Arduino UNO | 接続 | フォトカプラ | 接続 | STM32 |
5V | → | VCC | ||
GND | ⇔ | GND1 | ||
D3 | → | Vi | ||
VDD | ← | 3.3V | ||
GND2 | ⇔ | GND | ||
Vo | → | PA0 |
STM32のアナログ入力ポートを使って、Logiscopeのデジタルオシロスコープ機能を使います。よって、出力信号Voが3.3V以下となるようにVDD=3.3Vで使用します。いつもはUNOとSTM32のGND同士を接続して使うのですが、フォトカプラを使う場合は「電気的に絶縁」することが目的なので、GND同士を接続しません。
プログラムは、UNO、STM32共、Logiscopeを書き込んで使います。各々、logiscope.inoをコンパイル&書き込んでおいてください。
以下、実験中の様子です。
※上図では、確実に自然光中の赤外線を遮蔽するため、絶縁テープで巻いた後でアルミホイルを巻いてあります。アルミホイルは電気を通すので、ショートさせないように注意!
実験サンプル:【 】内はUNO側Logiscopeからの送信データ
【ana,3,128】
OK: analogWrite(3, 128)
UNOのLogiscopeで、Viに接続したI/OポートD3にデューティ50%のPWMを出力しました。PWM周波数は約490Hz、周期にして2,040μsです。
実験サンプル:【 】内はSTM32側Logiscopeからの送信データ
【osc,0,-4,3,1000】
STM32でアナログ波形を観測しました。観測結果は以下図の通りとなりました。
上から、IRディテクタに接続した直列抵抗の抵抗値をRc=10kΩ,2kΩ,330Ωに振った時の波形です。以下、測定結果と雑感をまとめておきます。
抵抗値Rc |
立ち上がり 時間[μs] |
HIGH幅 [μs] |
LOW幅 [μs] |
デューティ [%]※ |
HIGHレベル [V] |
LOWレベル [V] |
10kΩ | 466 | 635 | 1,024 | 38.3 | 3.0 | 0 |
2kΩ | 152 | 897 | 1,033 | 46.5 | 3.3 | 0.1 |
330Ω | 51 | 999 | 1,016 | 49.6 | 3.3 | 0.5 |
※デューティ=HIGH幅/(HIGH幅+LOW幅)で計算しました。
どうやら、Rc → 大とするとHIGHレベルが3.3Vより低下して立ち上がりが鈍る、Rc → 小ではLOWレベルが浮いて立ち上がりが急峻となる、様です。色々な特性を鑑みると、Rc=2kΩ程度に設定するのが良さそうです。
信号の通過方向を逆転して、Vi側にSTM32(3.3V)、Vo側にUNO(5V)とすると、信号のフルスイング電圧値が変わるので、多少は特性が変化して観測されるかもしれません。厳密に最適値を設定したい場合は、各自の条件で測定してパラメータを決定してください。
今回制作したのはフォトカプラ1チャンネル分だけです。実用的な応用例が思いつかないので、普通に非同期シリアル通信のTXD信号線にフォトカプラを挿入して、通信させてみたいと思います。
UNOのハードウェアシリアルはUSB⇔UART変換チップATmega16U2との通信に使われてしまっているので、拙作の高速ソフトウェアシリアルライブラリ(HsswSerial)を使います。こちらから、HsswSerialクラスライブラリをダウンロードしてインストールしておいてください。
HsswSerialクラスライブラリを使って、RXDに受信したテキストデータをTXDにエコーバックするプログラムを作ってUNOへ書き込んでおきます。
実験プログラム:test_photocpl.ino
PCからUARTにアクセスするため、USB⇔UART変換モジュール(例えばFTDI、下図)を使います。
Arduino UNO、FTDI、前の節で制作したフォトカプラを以下ネットリストに従って接続してください。
Arduino UNO | 接続 | フォトカプラ | 接続 | FTDI |
5V | → | VCC | ||
VDD | ← | VCC(3.3V) | ||
GND | ⇔ | GND1,GND2 | ⇔ | GND |
D9(TXD) | → | Vi | ||
Vo | → | RXD | ||
D8(RXD) | ← | TXD |
※FTDIの電圧ジャンパは3.3V側に設定。FTDI.TXD → UNO.RXDの接続でレベルが有っていないけど、十分実力で動くはず。正しくはL/S(または、逆向きのフォトカプラ)を通すべきだけど……、今回は目を瞑る。
本来、「電気的に絶縁」することが目的なので、GND1,2を分離すべきなのですが、今回はフォトカプラが1チャンネル分しか無くて、FTDI.TXD→UNO.RXDを接続するためにGNDを取る必要があるため、GNDを共通に接続していることに留意してください。
フォトカプラはUNOからの送信データ(TXD)側だけに挿入してあるので、受信データ(RXD)側:PC → FTDI → UNOへのデータ送信は、全く問題なく成功するはずです。よって、検証で着目すべきは、UNOからエコーバックされてきたデータが文字化けせずに受け取れるかどうか?となります。
以下、実験中の様子です。
FTDIをUSBでPCに接続したら、FTDIの通信ポートに対してシリアルモニタを開いてください。プログラム(test_photocpl.ino)のデフォルトでは、通信速度が300baudに設定されているので、シリアルモニタの通信速度を「300 bps」に設定してください。
実験サンプル:【 】内はシリアルモニタからの送信データ
【hello, how are you?】
hello, how are you?
PCから送信したテキストデータをそのままエコーバックしているので、適切な文字列を送信してみてください。送った文字列と同じ文字列が返って来たらOKです。何度か別な文字列で確かめてみてください。
実験サンプル:【 】内はシリアルモニタからの送信データ
【baud,1200】
OK: change baud rate to 1200
※HsswSerialでは、ダイナミックな通信速度変更を意識していなかったこともあり、切り換え直後にごみ(文字化け)が表示される場合があるみたいです。上メッセージの直後に出た文字化けは無視して、検証してみてください。
【baud】、【who】、【help】で始まる文字列に関しては、コマンドとして指定された動作を実行する様になっています。【baud】コマンドでは、カンマ(,)に続く数値を通信速度として設定します。上の【baud,1200】コマンドによって、通信速度が1,200baudに変更されたので、シリアルモニタの通信速度も「1200 bps」に変更してください。
実験サンプル:【 】内はシリアルモニタからの送信データ
【Do you hear me?】
Do you hear me?
別な文字列を送信してみました。ちゃんと送った文字列が返ってきましたか?文字化けせずに返って来たら、その通信速度での通信は成功したと判定します。さて、どこまで通信速度を上げられるか、上と同じ要領で通信速度を変えながら、試してみましょう。
Arduino IDE ver.1.8.11のシリアルモニタで設定可能な通信速度は、以下の通りでした。
300 bps,1200 bps,2400 bps,4800 bps,9600 bps,19200 bps,……
さっきの基礎実験で確認した波形では、Rc=2kΩの場合、信号の立ち上がり時間に152μsかかっていました。ここから逆算すると、シリアルの通信レートとしては、1/(152μs×2)≒3,289baud辺りが限界だと思われます。恐らく、2,400baudと4,800baudの間で、pass/failが切り替わるはずです。
筆者実験では、○1,200baud、○2,400baud、○4,800baud、×9,600baud、でした。実力では、4,800baudまで通信できたみたいです。さすがに、9,600baudでは文字化けして通信になりませんでした。
※LOWレベル → HIGHレベルの遷移時間が152μsだったのですが、LOWレベル → Vihレベルの遷移時間は4,800baudの通信に耐えられ得る時間であった、のだと考えています。
市販されているフォトカプラのデータシートなどを見る限り、市販品だと、もう少し高速に動くみたいです。より高速な信号線に使用したい場合には、市販品をお求めくださいm(1__)m。
正直、「作って見た」は、良いけれど、具体的な用途(応用例)が思いつかないので、この辺で止めておきますね。もっと高速な信号に適用するなど具体的な応用例に遭遇した時には、もう少し回路定数を調整可能だとは思います。Rc → 小とすると高速になるし、LOWレベルの浮きはフォトトランジスタのVce(SAT)辺りだと思われるので、Rf → 小とすると、抑えられる可能性もあると思われます。未確認ですけど……(1^−^;)。