9VバッテリーチャージャーをArduinoで作る
最近あまり使われない9Vバッテリーですが、自分はこれをchumby用で使用してます。これの急速充電器を作ってみようか…と思い、Arduinoを使って製作しました。
Arduinoを使うほどのものか?
当初、オペアンプ等を使用し、ほぼ定電流で充電し、バッテリーの電圧が一定値になったら充電完了と見なして充電を停止…という回路を作成していたのですが、いろいろ組んでいるうちにどんどん部品が増えてしまう。これだったらいっそのことマイコン制御にしてしまったほうが簡単なのではないか…だったらArduinoだ、ということでやってみました。
いざ作ってみると、複雑な制御の割には部品点数を大幅に減らすことができました。しかもそれがほんとに簡単にできてしまう。Arduinoにぴったり…という感じです。
ハード
ハードはシンプルです。
まず電源としては12Vを前提としています。基本的には、この12Vにバッテリーを接続します。バッテリーのマイナス端子がまずJ3を経由していますが、これは充電電流を計測するためのプローブを接続する端子で、通常はショートしておきます。さらにその下に直列にFET(TR1)を接続し、これで充電電流を制御しています。FETは小型で駆動電圧が低く、ドレイン電流を制御しやすそうなものという事で2SK2691を選択しました。
FETのドレインの電圧が抵抗を介してCPUに戻ってますが、ここの電圧をANALOG IN 0端子でチェックし、バッテリー両端の電圧をチェックしています。FETのソースは2Ωの抵抗(R3)を経由してGNDに接続していますが、この部分の電圧をANALOG IN 1端子でチェックし、充電電流を調べてます。つまり、充電時はこの点の電圧が一定になるように、FETのゲート電圧を制御します。
そのFETのゲートの電圧はATMega168の5ピン、Arduinoで言うDIGITAL 3端子のPWM出力を、R1,C3でアナログ電圧に平滑した電圧を供給しています。さらにそれをR2とR8,9で分圧していますが、これはゲート電圧の変化に対するドレイン電流の変化が大きいため、少しでも細かく制御できるようにするためです。R8,9はひとつの抵抗でも構いませんが、たまたま手持ちの抵抗で適当な値を得るためだけの事です。
ATMega168の11ピン、ArduinoでのDIGITAL 5端子に1kΩの抵抗を経由してLEDを接続しています。このLEDの点滅パターンで充電状況がわかるようにしています。普通にLEDを点灯させるだけであればArduinoなら最初からLEDがマウントされている13番を使うのが定番ですが、アナログ的に点滅させるのも面白いかな…と思い、PWM出力が可能な端子に接続しています。
J4は、モニタリングやプログラミングを行うための端子です。ここに秋月電子のUSB-シリアル変換基板の各信号を接続することで、ArduinoのIDEで普通にシリアル信号のモニタリングやプログラムの書き換えをできるようにしてあります。
ソフト
ソフトにて、以下のような制御を行うようにしました。
- バッテリーのマイナス端子の電圧をチェック。バッテリーが無ければこの端子はゼロになるが(R7でプルダウンしているので)、ここに電圧がかかったら、バッテリーが接続されたと認識する。
- バッテリーが接続されたら、FETのソース電圧(R3の電圧、つまりバッテリーを流れる電流)が特定の値になるまでFETのゲート電圧を上げる。
- FETのソース電圧が一定になったら、この電圧が一定になるように(ある範囲内に収まるように)FETのゲート電圧を調整する。これによってバテリーは定電流で充電される。
- バッテリーのマイナス端子の電圧を常時チェック。これがピーク値から下がったら充電完了とみなす。
- 充電完了になったらFETのゲート電圧を下げトリクル充電を行う。ソース電圧が特定の値になるよう(バッテリーに、トリクル充電のための電流が流れるよう)FETのゲート電圧を調整する。
- バッテリーのマイナス端子の電圧がゼロになったら、バッテリーが外されたとみなし、最初に戻る。
上記は基本処理であり、実際にはこの処理の途中に例外処理(例えば充電中にバッテリーが外された時の検出とか)も入れてます。
急速充電時の電圧の変化
充電電流の調整にしても、あまり頻繁に調整するといわゆる「発振」を起こします。そうならないよう、ある程度の慣性を持たせるような工夫も必要でした。結構面倒ですが、それはそれでまた面白いです。
簡単かな…とは思ってたけど、誤検出をしないように…つまり、まだ充電完了でないにもかかわらず充電完了とみなしたり、逆に充電が完了しているのにそれを検出できずに過充電になったり…なんてことが無いように確実な検出を行うのは結構面倒でした。
作って、出来た。
ブレッドボード上に組んで動作テスト。
この頃はFETが別のもので、でかい。
右下のコイル状のものは、ここで電流をチェックするためのもの。
最初は、ATMega168以外の部分をブレッドボード上で組んで動作チェック。これで充電電流が適切に制御できること、そのための各ポイントの電圧が確実に測定できること(0〜5V以内に収まっていること)をチェックしました。そしてArduino Duemilanoveの各端子とブレッドボードを接続し、実際にソフトを走らせてチェック。ここで重要なのが、バッテリーに最適な充電電流が流れている時の、ANALOG IN 1端子のA/D変換の値です。急速充電時、およびトリクル充電時にこの値がどの範囲であれば良いか、これは実際に電流計を接続し、カットアンドトライで設定しました。急速充電時で150mA程度、トリクル充電で10〜20mA程度流れている時の値にします。そしてその時のANALOG IN 0端子の値、およびFETのゲート電圧になるDIGITAL 3端子(PWM出力)の値が飽和していないか確認しました。結果、OK。
次にArduino基板からATMega168を抜き取り、これをブレッドボードに載せ、スタンドアロンで動作チェック。この状態で12Vから5Vを作るための3端子レギュレーター等も載せます。ここで最終的に各回路のチェック。ソフトなら完成してから書き換えるのは簡単ですが、ハードは面倒ですからね。
様々なチェック後、これの各部品をブレッドボードから万能基板に載せ変え…そして完成。
コンパクトに収まりました。
やはり、Arduino純正の基板ではなく、そしてブレッドボード上で動いているのでもなく、1枚の基板上でスタンドアロンで動いているというのはなかなか嬉しいものがあります。
普通にマイコンで組もうと思うと、メインルーチンを動かす前に各種動作モードを設定するための制御レジスタを設定したり、そしてROM化のための知識が必要だったり等、「マイコン上で自分のプログラムを動かすために」考えなければならない事があります。しかしArduinoはそれらはほとんど不要、純粋に「こう動いてほしい」という事だけをプログラムに書けば、それをそのままスタンドアロンで 使うことができます。うーん、良く出来てます。面白いぞ、Arduino。