公開日:2019/12/21
title.png

8th Season


#8-9 発振器でLEDを自動点滅する

 シュミットトリガ入力インバータ(オペアンプ)と遅延回路を使って、発振器を作り、その出力でLEDを自動的に点滅させてみようと思います。

シュミットトリガ入力インバータで作る発振器

 「#8-3 シュミットトリガ入力バッファを設計する」で実験したシュミットトリガ入力インバータを使います。シュミットトリガ入力インバータには、入力をLOW→HIGHと見なす閾値電圧Vtpと、HIGH→LOWと見なす閾値電圧Vtmがあって、この差分をヒステリシスΔVt=Vtp−Vtmと言うのでしたね。
 シュミットトリガ入力インバータのヒステリシス特性があるお陰で、この回路と適切な遅延回路を組み合わせることで発振器を作ることができます。

 遅延回路が必要ですが、アナログ遅延回路が必要なので、コンデンサCと抵抗Rで作る、CR回路を使います。例えば、0VからVcc=5Vまで充電しようとする時、Vccの63.2%まで充電するのに要する時間を時定数(tc)と呼び、CとRの積で求められます:tc=C×R[s]。この時間を使って、アナログ的な遅延時間を確保します。

 シュミットトリガ入力インバータのシンボルを使って簡単に引いてみると、回路図は以下図の様になります。

ar89_schem3.png

 この回路の動作を下の図で説明します。縦軸に電圧、横軸に時間の経過を表しています。

ar89_wave3.png

 電源レール(Vcc〜GND)の間に、シュミットトリガ入力インバータ(LM358を使って作ります)の出力HIGH電圧Voh、LOW電圧Volが青破線で引いてあります。更にその内側に、シュミットトリガ入力インバータの入力閾値電圧Vtp,Vtmをオレンジ破線で示しています。
 赤い曲線は、CR回路の充放電電圧波形、緑色の矩形波形はシュミットトリガ入力インバータの出力電圧です。以下、時間軸に沿って、動作を説明します。

 この時、発振器が出力する矩形波は、HIGH幅Kp×C×R、LOW幅Kn×C×R、周期(Kp+Kn)×C×RのPWM波形となります。

回路定数を決定する

 前節で実施した動作原理の説明で、お解りかと思いますが、大雑把に言うと、CR回路の時定数C×Rが発振周波数を決め、シュミットトリガ入力インバータのVtp,Vtmが発振波形のデューティを決定するパラメータとなります。
 この節では、発振回路の回路定数を決めるための代数計算を実施します。

  CR回路(アナログ遅延回路)の挙動:

 次に、ちょっと厄介なのは、シュミットトリガ入力インバータのVtp,Vtmの決め方です。数式を立てて行くと、普通に求められるのですが、ちょっと、複雑な変形(難しくはないけど、面倒な計算)が必要になります。

  解くべき方程式:

 この時点で未知数はVtp,Vtmなので、Mathematicaを使って連立方程式を解きます。全体をキャプチャするのが大変だったので、結果だけ以下に示します。

ar89_math.png

 上の式で、tc=63.2%(=0.632)です、C×Rではありません。紛らわしくてゴメンなさい。ちょっと、手計算するのは嫌になるような式でした、Mathematica様様(1^o^;)。結果としては、シュミットトリガ入力インバータ(LM358)の出力電圧Voh,Volと、デューティ値Dtyをパラメータとして、閾値電圧Vtp,Vtmが決まる式となりました。

 Vtp,Vtmが求められたら、「#8-3 シュミットトリガ入力バッファを設計する」で計算した式に従って、シュミットトリガ入力インバータの回路定数R1,R2,R3を求めることができます(以下再掲)。

ar85_math6.png
ar85_math7.png

 ここで、f=1Hz,Dty=1/3,C=100μF,Voh=3.64V,Vol=0.69Vと置いて、回路定数を決定します。

  CR回路:
    R=1/(f×C)=10kΩ
    Vtp≒2.013V
    Vtm=1.369V
  シュミットトリガ入力インバータ:
    R1≒223kΩ → 100k+100k+(100k//100k)=250kΩ (手持ちの抵抗値で構成)
    R2=100k+100k=200kΩ (基準)
    R3≒91kΩ → 100kΩ (手持ちの抵抗値で構成)

※Voh,Volの設定値が、何だか妙に生々しいことに気が付きましたか?当たり🎯です。回路を組んで、実際に測定した結果よりフィードバックしてあります。……これでは「鶏と卵」ですね。

 発振器の周波数(周期)はCR回路の定数C,Rで決まり、デューティはシュミットトリガ入力インバータのVtp,Vtmで決まります。
 この回路のパラメータには、Voh,Volなど、実チップ(LM358)の特性に依存するものや、抵抗値など、実在の抵抗を組み合わせて実現するしかないものも含まれ、色々な所に誤差が蓄積するため、水晶発振子の様にピシっと狙った周波数(とデューティ)で発振させることは困難です。ある程度の誤差が許容できる用途でしか使用できません。

LTspiceでシミュレーションしてみる

 「#8-3 シュミットトリガ入力バッファを設計する」で作ったシュミットトリガ入力インバータの回路図も取り込んで、以下の様な回路でシミュレーションします。

ar89_schem.png

 Voを出力しているのがシュミットトリガ入力インバータ、Vsを出力しているのがCR回路(アナログ遅延回路)です。ArduinoのI/O出力Enbを受けて、Vs点をGNDに引き抜く回路で、発振を停止することができるようにしておきました。

※Q1がONした時、Vs点の電位がVtmを下回るような回路定数に設計する必要があります。Q1がONすると、Vo→R4→(Vs→)R5→Q1→GNDのパスで電流が流れるので、オームの法則を使ってVsの電位を調整します。また、C1に充電されていた電圧がQ1を通ってGNDに流れるので、NPNトランジスタのIce(MAX)を超えない様な抵抗R5にする必要があります。

 シミュレーション波形を以下図に示します。

ar89_wave.png

 ほぼ狙い通り(デューティ1/3、周波数1Hz)の波形となりました。「#8-3 シュミットトリガ入力バッファを設計する」の「後日のアップデート」でレポートした通り、このシュミットトリガ入力インバータのシミュレーションでは、TI社が提供するLM358のspiceモデル(LM358_TI)を使わないと、実物とシミュレーションが一致しないことがわかっています。しかし、LM358_TIは、LTspiceとの相性が良くないのか、ものすごくナーバスなモデルで、ちょっと回路を追加したり、パラメータを変更しただけで、シミュレーションが動かなくなってしまいます。
 上のシミュレーション結果は、何とかダマシダマシ取得しました。

 先ほど図で説明した通り、CR回路の電圧Vs(緑線)が、シュミットトリガ入力インバータのVtp,Vtmの間で充放電を繰り返しながら、一定の間隔で発振(Vo、青線)していることが見て取れます。また、Enb端子(赤線)にHIGHが入力されると、発振が停止しています。

※もっと速い周波数で発振させてみたところ、〜1kHzくらいまでは何とか発振しそうです(シミュレーションで確認)。LM358だと、それより速く発振させるのは無理みたいです(動作速度の限界)。

発振器でLEDを自動点滅させる

 シュミットトリガ入力インバータで作った発振器を使って、LEDを自動点滅させてみましょう。
 先ほどの発振器の回路と共に、以下図のLEDドライブ回路をブレッドボードなどに構成しておきます。

ar89_schem2.png

 発振器の回路定数に影響を与えないよう、2個目のLM358をボルテージフォロア(U2)にして、Voを引き込みます。
 前節のシミュレーションで確認できたように、Enb端子をHIGHにすると、発振器出力VoがHIGHレベルで停止する回路なので、逆に、発振器出力VoがLOWの期間にLEDが光るように、NPNトランジスタ(手持ちのS8050を使用)で論理NOTゲートを作りました。R11,Q11,R12がNOTゲートです。
 なお、シュミットトリガ入力インバータのLOW出力が0.7〜0.8[V]程度まで浮いてしまうので、そのままQ11のベースに繋いでしまうと、常にQ11がONしてしまいました。対策として、Q11のVbeをかさ上げする目的で、ダイオードD11(手持ちの1N4007を使用)を挿入しました。

ar89_diode.jpgar27_npntr.jpg

 前の節で述べた通り、LM358_TIのモデルはとてもナーバスで、発振回路とLEDドライブ回路を1つの回路にまとめてしまうと、シミュレーションが動きませんでしたm(1x_x)m。なので、別々に回路をエントリするしかありませんでした。LEDドライブ回路の方は、VoのLOW出力期間にLED(D12)が発光する(LEDに電流が流れる)だけの話なので、シミュレーションは省略します。

実際の回路で確認しておこう

 前の節で示した回路(発振回路と、LEDドライブ回路、両方共)をブレッドボードなどに構築して、Arduino UNOでLogiscopeを起動してください。以下、実験中の様子です。

ar89_expr.jpg

 今回の実験は、Enb端子にHIGHまたはLOWを出力するだけですので、Logiscopeで十分です。以下の通り実験を進める場合には、Enb端子をArduinoのD4端子に接続してください。あと、忘れずに電源VccとGNDも繋ぎます。

  実験サンプル:【 】内はLogiscopeからの送信データ
  【out,4,1】
   …… LEDが消灯します。

※初期状態でEnb=D4=HIGH-Zの間はベースに電流が流れず、トランジスタがOFFするので、電源投入直後はLEDが点滅しています。電源投入時に消灯させたい場合は、D4(Enb)端子をプルアップしてください。

  【out,4,0】
   …… LEDが自動的に点滅します。周期は約1s、デューティは2/3です。

 一応、発振波形を確認しておきましょう。回路図のVo点から信号を引き出して、Arduinoのアナログ入力A0端子に接続して実験を続けます。

  実験サンプル:【 】内はLogiscopeからの送信データ
  【osc,0,-8.9,7,0】 …… Voの立ち下がりからキャプチャして、Volを確認。
   …… 結果、Vol≒0.69Vでした。

  【osc,0,8.9,7,0】 …… Voの立ち上がりからキャプチャして、Vohを確認。
   …… 結果、Voh≒3.64Vでした。

 取得したタイミング図は省略しますが、発振周期が1sと長いため、Logiscopeの【osc】コマンド(デジタルオシロスコープ)では、1周期分の波形を取得するのは無理でした……。

※Vol,Vohは測定出来たので、この結果からVtp,Vtm → シュミットトリガ入力インバータの回路定数(R1,R2,R3)を再計算して、回路に反映してあります。

 発振波形は、デジタル信号として確認しておきましょう。今度は、Vo点から引き出した信号線をD2端子に接続して、以下コマンドを実行します。

  実験サンプル:【 】内はLogiscopeからの送信データ
  【trg,2,r,5000000】 …… "0"の数に注意。5s=5,000,000μsを指定します。

ar89_wave2.png

※この波形取得に伴い、Logiscopeのバグを修正しました。最新版でお試しください。

 取得した波形から、HIGH幅≒370ms、周期≒1,027ms、デューティ≒36%≒1/2.78と、読み取ることができます。設計値は、周期=1s、デューティ=1/3なので、多少誤差がありますが、実在の抵抗値で近似していたり、LM358の特性による誤差なども蓄積するので、許容範囲、「設計通りに動作した」と、考えられます。

 尚、LEDは、VoのLOW期間で光らせているので、点滅のデューティは、点灯2/3⇔消灯1/3です。
 Arduino単体でLEDを点滅させるには、Arduinoのプログラムで時間を計測しながら、I/OポートをLOW/HIGHに制御(トグル)してLEDを点滅させる必要がありました。ずっと、プログラムでケアし続けてやらないと点滅を続けられないし、何か重たい処理を始めてしまって、点滅処理を実行できなくなってしまうと、その間点滅が一時停止してしまったり、周期が揺れたりしてしまいます。
 今回の回路では、外部発振器で点滅波形を作り出しているので、Arduinoからは、点滅/消灯を制御するI/OポートにHIGHまたはLOWレベルを出力し続けるだけで済みます。
 また、発振器を停止すると、HIGHで停止する回路なので、HIGH期間に点灯する回路にすると、常時点灯しておいて、ユーザの注意を惹きたい時に発振させて点滅させる使い方(自動ブリンク)にも対応可能だと思われます。


 周期の長い(〜1s)波形を取得したお陰で、Logiscopeのバグを発見してしまいました。デバッグできていた「つもり」になっていた様です(情けない……)。修正しておきましたm(1__)m。


btn_arduino.png

btn_prev.png btn_next.png

home