Arduinoを使ったバッテリー放電器
コードレスフォンの子機の電池が空になりかけていることに気付きました。何しろ10年以上使っているので、電池がダメになってもおかしくはありません。電池はニッケル水素電池の単四を3個直列に束ねてコネクタが付いている物です。
さっさと新しい電池に交換すれば良いのですが、端子電圧を測定してみると 4.2Vくらいあります。この電圧を見る限り問題は無さそうな感じなのですが、コードレスフォンの子機の画面では電池の残量が最低表示(1/4表示)になっています。
なんだか釈然としないので、電池を完全放電させてリフレッシュしてみることにしました。どうせやるなら放電カーブを記録し、電池容量の測定もやってみることにしました。
そんなことで、Arduino を使って電池の放電器を作ってみました。
▼Arduino を使った電池の放電器

画面中央右下の緑色の物がニッケル水素電池(単四x3本)で、放電回路を経由して Arduino UNO に接続しています。
▼回路図

10Ω(5W) の負荷抵抗(RL) で電池を放電させるようになっていて、放電の ON/OFF はパワーFET (Q1) を D2 ピンから制御。電池電圧はアナログポート (A0) で測定。放電開始のタイミングをプログラムに知らせるためにスタートスイッチを用意、という回路になっています。なお、スタートスイッチはジャンパー線を手で持って GND(USBコネクタのシェルが便利) にちょんと触るだけなので、実際に部品としてのスイッチは使っていません。
▼実際の放電回路

たったこれだけです。負荷には5Wのセメント抵抗を使っています。
▼プログラム
回路は簡単ですが、プログラムにはできるだけ機能を詰め込みました。
最初に電池の開放電圧 (openV) を測定し、その電圧に対する比率 (dR) で放電終了(停止)電圧 (stopV) を自動的に決定する仕掛けになっています。
スタートさせれば終了電圧になるまで放電させ、一定の時間間隔(現在は10秒)で測定結果をシリアルに流すようになっています。終了電圧になったら放電は止めますが、電圧の測定は続けるので、電圧が回復していく様子も記録に残ります。
電圧の基準には Arduino の電源電圧を使っています。標準値は5Vですが実際には使った電源やArduino のボードによって微妙違った値になっていることがあります。そこで、Vcc の変数に実際の値を手入力することで補正出来るようにしておきました。細かいことを気にしなければ、デフォルトの 5.00 のままで使っても大丈夫です。
あと、負荷抵抗や測定間隔などの測定条件も変数の値として定義しているので、カストマイズは簡単に出来ると思います。
このプログラムは、出力をパソコンなどに表示することを前提とした作りになっています。もちろん Arduino のシリアルモニタを使っても大丈夫です。
以下は TeraTerm で記録したデーターの例です。行の先頭には TeraTerm が挿入するタイムスタンプの文字列が入っていますが、この文字列とデーターとの境目の検出が簡単に出来るように、行頭にカンマを出力するようにプログラムしてあります。
▼出力例
▼エクセルでグラフ化

綺麗な電池の放電カーブが取れました。
◆まとめ
ニッケル水素電池の放電器としては、簡単なアナログ回路だけで作った物を以前作りました。これはこれで便利なのですが、単セル電池用なので、今回のような組電池には使えません。そんなことで、作っておくと便利だと思います。使い終わったら、この記事を印刷したものと一緒にビニール袋にでも入れて保管しておけば、後で使う時にも便利かなと思います。
電池容量の値としては電流容量の値の mAh だけあれば大丈夫かも知れませんが、電力量である mWh の値も出力するようにしました。電池の内部抵抗が上がってくると端子電圧が下がるので、取り出せる電力量が少なくなります。この様子は電流容量の値にはあまり表れてこない場合もあるので、電力量も出力するようにしました。なお、この電力量は瞬時電力(10秒間隔)の積分で計算しているので、正確なエネルギー量になっているはずです。
この放電器を作るきっかけとなった、コードレスフォンの子機の電池ですが、結局はダイソーで単四のニッケル水素電池を買ってきて自作しました。そのあたりの話は別の記事で紹介したいと思います。
記事の中に書き漏らしたのですが、この回路で測定できる電池の電圧の上限は5Vまでです。(電源電圧が 3.3V の Arduino なら上限は3.3Vまで)になります。分圧回路を入れればもっと高い電圧まで使えるようになりますが、部品の数が増えて面倒なので今回はやってません。
さっさと新しい電池に交換すれば良いのですが、端子電圧を測定してみると 4.2Vくらいあります。この電圧を見る限り問題は無さそうな感じなのですが、コードレスフォンの子機の画面では電池の残量が最低表示(1/4表示)になっています。
なんだか釈然としないので、電池を完全放電させてリフレッシュしてみることにしました。どうせやるなら放電カーブを記録し、電池容量の測定もやってみることにしました。
そんなことで、Arduino を使って電池の放電器を作ってみました。
▼Arduino を使った電池の放電器

画面中央右下の緑色の物がニッケル水素電池(単四x3本)で、放電回路を経由して Arduino UNO に接続しています。
▼回路図

10Ω(5W) の負荷抵抗(RL) で電池を放電させるようになっていて、放電の ON/OFF はパワーFET (Q1) を D2 ピンから制御。電池電圧はアナログポート (A0) で測定。放電開始のタイミングをプログラムに知らせるためにスタートスイッチを用意、という回路になっています。なお、スタートスイッチはジャンパー線を手で持って GND(USBコネクタのシェルが便利) にちょんと触るだけなので、実際に部品としてのスイッチは使っていません。
▼実際の放電回路

たったこれだけです。負荷には5Wのセメント抵抗を使っています。
▼プログラム
回路は簡単ですが、プログラムにはできるだけ機能を詰め込みました。
/* バッテリー放電器
FETをONにして放電させ、放電終止電圧以上の間バッテリーを放電させる
放電終止電圧は無負荷時電圧に対する比率で自動設定
2020.1.4 ラジオペンチ http://radiopench.blog96.fc2.com/
*/
#include <MsTimer2.h> // 時間はMsTimer2割り込みで制御
unsigned long t; // 経過時間(秒)
float loadR = 10.0; // 負荷抵抗
float Vcc = 5.00; // 基準電圧(CPUの電源電圧の実測値を設定)
float dR = 0.6; // 放電電圧終了電圧計算比率
long recInt = 10000UL; // 記録インターバル(ms単位の値で指定)
float battV; // 現在のバッテリー電圧
float openV; // バッテリーの解放電圧
float mAh = 0; // 積算電流
float mWh = 0; // 積算電力
float stopV; // 放電停止電圧
boolean runFlag = true;
volatile boolean tUp = false; // time Up フラグ
void setup() {
Serial.begin(115200);
pinMode(2, OUTPUT); // 放電制御 HIGH で放電
pinMode(3, INPUT_PULLUP); // 測定開始ボタン
pinMode(13, OUTPUT); // 放電中表示LED
// openV = analogRead(0) * Vcc / 1023.0; // 無負荷電圧測定(これは間違いで、)
openV = analogRead(0) * Vcc / 1024.0; // 無負荷電圧測定(正しくはこの式)
// 解説:analogRead関数の戻り値は Vref = 1024(0x400) としてマップされている。
// しかし、1024は10ビットの範囲を超えているため、戻り値がこの値になることは無い。
// ちなみに、戻り値が最大である 1023(0x3FF) に対応する電圧は、Vref - 1LSB = Vref * (1 - 1/1024)。
stopV = openV * dR; // 無負荷時電圧に対する比率で放電終止電圧を決定
Serial.println(); // 各種情報を出力
Serial.println(" ,BATTERY DISCHARGER");
Serial.print(" ,load R = "); Serial.print(loadR); Serial.print("ohm, Vcc(5V5) = ");
Serial.print(Vcc); Serial.print("V"); Serial.print(" ,openVoltage = "); Serial.print(openV);
Serial.print("V, stopVoltage = "); Serial.print(stopV); Serial.println("V");
Serial.println(" ,waiting start. (connect pin3 to GND for start)");
while (digitalRead(3) == HIGH) { // D3がLOWになるまで待つ
}
Serial.println(" ,Discharge start!"); // 測定開始メッセージ
Serial.println(" , sec., voltage, mAh, mWh");
digitalWrite(2, HIGH); // 負荷ON(放電開始)
digitalWrite(13, HIGH); // 放電中表示
delay(1000); // 初回測定まで一寸待つ
logOut(0); // 初回の測定結果を記録
MsTimer2::set(recInt, timer2IRQ); // 指定時間毎に割り込みをセット
MsTimer2::start(); // 割り込み開始
}
void loop() {
while (tUp == false) { // MsTimer2の割り込みが入りまで待つ
}
tUp = false;
t += (recInt / 1000); // 積算時刻を更新
logOut(1); // 測定結果をログ出力
}
void logOut(int mode) { // 測定結果をログ出力 (mode=0 は初回)
Serial.print(" , "); // タイムスタンプ文字列との境目を入れる
Serial.print(t); Serial.print(", "); // 経過時間(秒)表示
// battV = analogRead(0) * Vcc / 1023.0; // バッテリー電圧測定(これは間違いで、)
battV = analogRead(0) * Vcc / 1024.0; // バッテリー電圧測定(正しくはこっち)
Serial.print(battV, 3); // 電圧の値を出力
if (runFlag == true) { // 放電中で
if (mode == 1) { // 初回でなければ
mAh += (1000.0 * battV / loadR) * (recInt / (3600.0 * 1000.0)); // 積算電流計算
mWh += 1000 * (battV * battV / loadR) * recInt / (3600.0 * 1000.0); // 積算電力計算
Serial.print(", "); Serial.print(mAh); // 積算電流値を出力
Serial.print(", "); Serial.print(mWh); // 積算電力値を出力
} else { // 初回だけは積算値はゼロ
Serial.print(", 0.00, 0.00");
}
if (battV < stopV) { // 放電停止電圧以下になっていたら、
digitalWrite(2, LOW); // 放電停止して
digitalWrite(13, LOW); // 放電中表示OFF
runFlag = false; // 次回このルーチンを実行しないようにフラグを消す
Serial.print(" ,End discharge"); // 放電終了表示
}
}
Serial.println(); // ログの行末の改行
}
void timer2IRQ() { // MsTimer2の割り込み処理ハンドラ
tUp = true;
}
最初に電池の開放電圧 (openV) を測定し、その電圧に対する比率 (dR) で放電終了(停止)電圧 (stopV) を自動的に決定する仕掛けになっています。
スタートさせれば終了電圧になるまで放電させ、一定の時間間隔(現在は10秒)で測定結果をシリアルに流すようになっています。終了電圧になったら放電は止めますが、電圧の測定は続けるので、電圧が回復していく様子も記録に残ります。
電圧の基準には Arduino の電源電圧を使っています。標準値は5Vですが実際には使った電源やArduino のボードによって微妙違った値になっていることがあります。そこで、Vcc の変数に実際の値を手入力することで補正出来るようにしておきました。細かいことを気にしなければ、デフォルトの 5.00 のままで使っても大丈夫です。
あと、負荷抵抗や測定間隔などの測定条件も変数の値として定義しているので、カストマイズは簡単に出来ると思います。
このプログラムは、出力をパソコンなどに表示することを前提とした作りになっています。もちろん Arduino のシリアルモニタを使っても大丈夫です。
以下は TeraTerm で記録したデーターの例です。行の先頭には TeraTerm が挿入するタイムスタンプの文字列が入っていますが、この文字列とデーターとの境目の検出が簡単に出来るように、行頭にカンマを出力するようにプログラムしてあります。
▼出力例
[2020-01-02 14:43:55.565] ,BATTERY DISCHARGER R = 10.00ohm, Vcc(5V5)= 4.91V7780秒の時点で放電停止となり、積算電流は751.81mAhとなっています。(この時点では積算電力(mWh)の値は出力していませんでした)
[2020-01-02 14:43:55.565] ,openVoltage = 4.22 ,stopVoltage = 2.53
[2020-01-02 14:43:55.565] ,waiting start (start when Pin3 connected to to GND)
[2020-01-02 14:44:05.612] ,Discharge start
[2020-01-02 14:44:05.612] , sec., voltage, mAh
[2020-01-02 14:44:06.610] , 0, 4.036, 0.00
[2020-01-02 14:44:16.610] , 10, 4.003, 1.11
[2020-01-02 14:44:26.609] , 20, 3.979, 2.22
[2020-01-02 14:44:36.609] , 30, 3.964, 3.32
[2020-01-02 14:44:46.640] , 40, 3.950, 4.42
・
・
[2020-01-02 16:53:45.036] , 7780, 2.520, 757.81 ,End discharge
[2020-01-02 16:53:55.035] , 7790, 3.019,
[2020-01-02 16:54:05.035] , 7800, 3.086,
▼エクセルでグラフ化

綺麗な電池の放電カーブが取れました。
◆まとめ
ニッケル水素電池の放電器としては、簡単なアナログ回路だけで作った物を以前作りました。これはこれで便利なのですが、単セル電池用なので、今回のような組電池には使えません。そんなことで、作っておくと便利だと思います。使い終わったら、この記事を印刷したものと一緒にビニール袋にでも入れて保管しておけば、後で使う時にも便利かなと思います。
電池容量の値としては電流容量の値の mAh だけあれば大丈夫かも知れませんが、電力量である mWh の値も出力するようにしました。電池の内部抵抗が上がってくると端子電圧が下がるので、取り出せる電力量が少なくなります。この様子は電流容量の値にはあまり表れてこない場合もあるので、電力量も出力するようにしました。なお、この電力量は瞬時電力(10秒間隔)の積分で計算しているので、正確なエネルギー量になっているはずです。
この放電器を作るきっかけとなった、コードレスフォンの子機の電池ですが、結局はダイソーで単四のニッケル水素電池を買ってきて自作しました。そのあたりの話は別の記事で紹介したいと思います。
記事の中に書き漏らしたのですが、この回路で測定できる電池の電圧の上限は5Vまでです。(電源電圧が 3.3V の Arduino なら上限は3.3Vまで)になります。分圧回路を入れればもっと高い電圧まで使えるようになりますが、部品の数が増えて面倒なので今回はやってません。
- 関連記事