公開日:2020/08/29
title.png

12th Season


#12-5 プログラマブルLDOレギュレータ

 前回作成したLDOレギュレータをプログラマブル(デジタル信号で電圧可変)にして、328duinoを駆動してみたいと思います。

プログラマブルにするには?

 前回回路(LDOレギュレータ)のおさらいです(↓)。

a124_schem.png

 上の回路では、オペアンプの非反転入力端子に入力したVrefと、出力電圧Vddの間にVdd=R2/(R1+R2)×Vrefの関係が成立しています。
 出力電圧Vddをプログラマブル(デジタル信号で可変)とするには、Vrefに所望の電圧を発生させてやれば良いだけです。そのような回路を既に承知していて、一般にはDA変換器と言います。今回は328duinoでLDOレギュレータを制御しようと思っていますので、「#7-6 DA変換器を作る」で作成した、手作りのDA変換器を使います(下図)。

ar76_dac4.jpg

 作り方や性能(変換精度)等については、「#7-6 DA変換器を作る」でご確認ください。この装置は4ビットのDA変換器ですので、16段階のデジタル値をアナログ電圧に変換して出力することが可能です。従って、LDOレギュレータの出力電圧Vddを16段階で制御することが可能となります。

 今回は、LDOレギュレータへの入力電圧Vin=5Vとします。以下図の様なUSB治工具などを使って、USBケーブルから電源端子(VBUS,GND)を引き出し、LDOレギュレータに供給します。

ar38_usbjig.jpg

 前回の検討通り、ドロップダウン電圧Vdo≒0.5V(MAX)程度ですので、Vdd=Vin−Vdo(MAX)=4.5V(MAX)です。従って、Vrefとしては、4.5/2[V]程度まで出力できれば十分です。2×Vref>Vin−Vdoとなってしまうと、無駄に大電流が流れてしまうので、そこにも注意を払います。

 328duinoの実験では、fcpu=8MHzまで落とすと1.8V程度まで動作することを確認していますが、せめてUNOと同程度のパフォーマンスで動作させたいので、fcpu=16MHzをターゲットとしてVcc=2.5V辺りを狙ってみたいと思います(下図、再掲)。

a105_vccmin.png

※ATmega328Pのスペック外ですし、個体差によって、fcpu=16MHz @Vcc=2.5Vで動かないMCUもあるかもしれないので、その場合は、fcpu=8MHz等、遅いクロックに差し替えて実験してみてください。

 以上の検討に少々マージンを取って、手作りの4ビットDA変換器から2.5/2[V]〜4.2/2[V]の電圧を出力して、Vrefに入力しようと思います。

プログラマブル基準電圧生成回路

 まず、以下の様な回路を作成しました。

a125_schem.png

 4ビットDA変換器は、220Ωの抵抗を16個直列接続して作っていますので、AGND端子〜VREF端子間の抵抗値は16×220[Ω]です。VccとVREF端子間にRf、AGND端子とGND間にRgと言う抵抗を挟んで、抵抗分圧によって出力AOUT=2.5/2[V]〜4.2/2[V]にできるよう、Pi ZeroWのMathematicaでRfとRgの必要値を計算させました(下図)。

a125_dacreg.png

 計算上、Rf=11.038kΩ、Rg=4.853kΩとなりましたが、手持ちの抵抗値で作成するため、Rf=11kΩ=10k+1k[Ω]、Rg=5kΩ=10k//10k[Ω]としました。結果、出力電圧範囲は、Vref≒1.28〜2.13[V]となり、LDOレギュレータの出力電圧範囲Vdd=2×Vref≒2.56〜4.25[V]となります。


 さて、今回はLDOレギュレータをプログラマブルにして、その出力電圧Vddで328duinoを駆動するだけに留まらず、そもそも、出力電圧の制御その物を328duino自身にやらせようと考えています。

  LDOレギュレータでVddが出力される →
  その電圧で328duinoの電源を供給する →
  328duinoでLDOレギュレータの電圧を可変制御する、……。

 ぱっと見、「鶏と卵」みたいになっていて、我ながら「電源投入時、ちゃんと起動するの?」って思ってしまいます。

  電源投入時の動作検討:

 上の様に、恐らく問題なかろうと思います。
 4ビットDA変換器が、単純に直列抵抗で分圧された電圧を出力するだけの回路で、Vccの供給だけで動作可能なこと。電源投入時、DIN3〜DIN0がどのような値であったとしても、出力範囲がVref=1.28〜2.13[V]に限定されていること。最低電圧のVref=1.28[V]、従ってVdd=2.56Vでも、328duinoにリセットがかかり起動すること。この辺りが必要条件ですので、1つたりとも条件を欠かない様に設計してください。

328duinoの準備

 「#9-5 ブレッドボードにArduinoっぽい物」の記事に従って、328duino(第一形態) @16MHzで動作可能な様に、ATmega328にUNO用のブートローダを書き込み、16MHzの水晶発振子を用意してください。

 UNO用ブートローダを書き込むと、ヒューズの中のBOD(Brown-Out Detection、低電圧検出機能)レベルが2.7V(TYP)に設定されてしまっているので、「#9-4 ATmega328のヒューズ書き込み」で作成したプログラム(ser_prog.ino)と結線を使って、ヒューズEに0xfeを書き込んでください。

  【wrfe,fe】
  OK? to write 0xFE to fuse.e? send 'y' or 'n' > Yes, go
    【y】 …… 確認して、OKの場合。
  OK: write fuse.e=0xfe

 ヒューズEに0xfeを書き込むと、BODレベルが1.8V(TYP)となりますので、328duinoの電源電圧を1.8V程度まで低下させて使うことが出来るようになります。

※この作業を端折ると、プログラマブルLDOレギュレータでVdd<2.7Vに降下させた時、ATmega328にBODリセットがかかってしまいます。

 その(↑)ATmega328を使って、以下図の様な回路を形成します。

a125_schem2.png


 この状態でArduino IDEからプログラムの書き込みが可能な様に、USB⇔UART変換モジュール(FTDI、下図)を接続したいと思います。

ar41_ftdi.jpg

 FTDIは3.3V/5Vのインターフェイスを選択可能なのですが、今回は、3.3Vでも5VでもないVdd=2.56〜4.25[V]を使いますので、L/Sを挿入する必要があります。以下回路を使ってFTDIと328duinoを接続し、Arduino IDEからの書き込みを可能とします。

a125_schem3.png

 Vcc>Vddである必要があり、Vdd=2.56〜4.25[V]ですので、FTDIの電圧ジャンパは必ず5V側で使用してください。FTDIとの接続は上図の信号線3本(TXD,RXD,DTR)とGNDだけです。

 シリアルモニタだけ使えれば良い場合は、DTRからリセット信号RSTを生成するD1とC3は不要です。ちゃんとArduino IDEからプログラムを書き込める様にリセット回路も作り込んでおきました。

実験くん

 本ページで示した全4枚のシート(回路)をブレッドボード等に構築して、5Vの電源だけを入力としてVccに供給します。あとは、328duinoを制御(書き込み、シリアルモニタなど)するためのFTDIを接続すれば準備完了です。

a125_expr.jpg

 回路規模が大きくなっていますので、一度に全体を接続するのではなく、ブロック毎に動作を確認しながら確認の取れたブロック同士をつなぎ合わせて行った方が無難です。上図の様に、ある程度ブロック毎にブレッドボードを分割できて、最後にくっつけて使えるのも170穴ミニブレッドボードの良きところ💗

 これで、入力電圧Vcc=5Vの電源から、プログラマブルに降圧(LDOレギュレータ)したVdd=2.56〜4.25[V]を使って、328duinoを動作させることが出来ます。328duino自分自身から、電源電圧Vddを制御できるかどうか、プログラムを書き込んでみましょう。

  実験用プログラム:calc_pi.ino

 プログラムは「#10-6 328duinoをクロックアップ(完結編)」で作成した、円周率πを計算させるためのプログラムです。ArduinoのMCUが正常動作していることを確かめるためのセルフテストプログラムとして開発した物です。
 今回、先頭付近に「#define USE_LDO_VDD」を追加してあります。上のリンクからダウンロードした状態だと、コメントしてあるので、コメントを外してからコンパイル&書き込みしてください。16MHz動作の328duinoはUNOと同じですので、コンパイル&書き込み時のターゲットは「Arduino UNO」を選択してください。

 USE_LDO_VDDを有効にしてコンパイル&書き込みすると、シリアルモニタから追加で以下のコマンドを実行できるようになっています。

 今回は比較的回路規模が大きいので、まず、この時点でうまく動作しない可能性もあります。回路の形成ミスはその時々ですので、アドバイスもできないのですが、動かなかった場合は単体テスト(ブロック毎のテスト)に立ち返って、1つ1つデバッグするのが基本です。

 書き込みに成功すると、プログラム(calc_pi.ino)はデフォルトで200桁の円周率πを計算して、期待値比較が一致する度にLED_BUILTINを点滅しています。ATmega328 @16MHzだと、約1秒間隔でLED_BUILTINが点滅するはずです。これが期待値。
 起動後setup()関数内では、4ビットDA変換器に対してDIN=15(最大値)を出力しているので、起動直後のVdd≒4.25Vとなっているはずです。

 別途、UNO+Logiscopeで【ina】コマンドを使い、Vddの電圧を確認しておきましょう。

  実験サンプル:【 】内はLogiscope (UNO)からの送信データ
  【ina,0】
  OK: analogRead(0)=890, 4.35V

 想定よりちょっと高めですが、まあ、こんな所でしょう。使用した抵抗の公差や、ブレッドボード上配線の接触抵抗など既成抵抗成分も誤差として見えてきていると思います。


 今度は328duino側でプログラマブルLDOレギュレータの出力電圧Vddを変更してみます。この時のVdd変化をUNO+Logiscopeから確認してみます。以下のコマンドを、Logiscopeの【osc】コマンドがタイムアウトしない内に、手早く送信してください。

  実験サンプル:【 】内はLogiscope (UNO)からの送信データ
  【osc,0,-4.9,7,0】 …… タイムアウトする前に、急いで↓

  実験サンプル:【 】内はシリアルモニタ(328duino+FTDI)からの送信データ
  【ldo,0】
  OK: ldo: daco=0

 これで、328duinoの電源電圧が約2.56Vになったハズ。Logiscopeで観測した波形は以下の通りです。

a125_15to0.png

 この測定結果より、4ビットDA変換器へDIN=15を出力した時のVdd≒4.32V、DIN=0を出力した時のVdd≒2.58Vと読めます。

 次は逆に、電源電圧Vddを上昇させてみます。

  実験サンプル:【 】内はLogiscope (UNO)からの送信データ
  【osc,0,4.9,7,0】 …… タイムアウトする前に、急いで↓

  実験サンプル:【 】内はシリアルモニタからの送信データ
  【ldo,15】
  OK: ldo: daco=15

a125_0to15.png

 安定時間にも差が見られました。電圧を下げる場合より、上げる場合の方が安定するまでの時間が短いことが見て取れます。LDOレギュレータの出力に出力電圧安定用の容量C1=100μFが付いているので、C1に溜まった電荷を引き抜いたり(電圧降下時)、C1に電荷を溜めたり(電圧上昇時)する必要があります。
 電圧を上昇させる時には、PNPトランジスタQ1(S8550)が電流(電荷)を供給するので速いのですが、電圧を降下させる場合には、負荷回路の消費電流頼みとなります。今回の負荷回路は328duino(=ほぼATmega328P単体)なため、消費電流が小さく、C1から電荷を引き抜くのに時間がかかったものと推定できます。

 また、電圧を上げる時も、下げる時も、オーバシュートおよびアンダシュートがあることには注意が必要です。降下する時は一瞬2.5Vを下回っていますし、上昇する時は5V近辺まで跳ね上がってから、設定した電圧に落ち着く様子がわかります。
 出力を0 → 15へ一気に上げるのではなく、0 → 1 → 時間待ち → 2 → 時間待ち → 3 → ……、等と階段状に制御すると、オーバ/アンダシュートを抑えることができます。

LDOレギュレータの回路改定

 当初、LDOレギュレータの出力に、出力電圧安定用の容量C1=10μFを接続していました。ところが、C1=10μFでは、【ldo,15】→【ldo,7】など、大きく電圧を変化させた時に発振してしまうケースがありました(下図)。

a125_osc10u.png

 発振が確認されたのは、電圧値を大きく変更しようとした時だけで、1〜2[LSB]毎に階段状に変更した場合は、問題ありませんでした。大きく変化させるケースも、C1=100μFにしたところ、前節の測定結果となっています。こちらの回路図は、Rev.2にて改定済みです。


 LDOレギュレータをプログラマブルにする、降圧したVddで328duinoを駆動する、その328duino自身がLDOレギュレータの出力電圧を制御する、と、いくつかのテーマを一気に実行してしまいました。一応「期待通りに動いた」と評価しますが、実用には色々と課題も山積みなようです……。


btn_arduino.png

btn_prev.png btn_next.png

home