プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

ArduinoとRaspberryPiで電池の容量を測る

f:id:s51517765:20210403222816j:plain

電池の容量を測りたい

我が家ではリモコンであったり、時計であったりに大量?のニッケル水素電池が稼働しています。
たまに、電池の寿命(容量)がやけに短い?と思うことがあります。
ニッケル水素といえど、充電池は劣化することで寿命が短くなることが知られています。

では、実際のところどれぐらい短くなっているのか測定してみることにしました。
我が家で使われている充電池は主に、Panasonicのこちらのもので容量は2000mAhです。
f:id:s51517765:20210403180321p:plain

電池の容量は、電流値を時間で積分すれば測定できます。
2000mAhとは2000mAで放電したとき1時間で無くなる、という意味です。
このような定義を知らなくても、書かれている容量の単位がmAhであることが分かれば容易に推定できます。

ニッケル水素電池は標準で1.2Vとされています。
充電直後は1.4Vぐらいある場合もありますが、ここでは1.2V以上を出力できるまでを電池容量とします。

2000mAhとは言いますが、電池は2000mAも出力することは出来ません。
感覚的には200mAぐらい(最大でも300mA)かな?と思いますが、試験回路としては、なるべく大きな電流を流したほうが測定時間は短くできますが部品の定格を考えて、1/4wの10Ω抵抗を2本直列にすることにしました。
f:id:s51517765:20210403181850p:plain

測定の効率を考えて(電池ボックスが2本直列のものしかなかったので)電池を2本直列(1.4 x 2 V)にし、抵抗の電力を1/4w以下、電流を200mA以下となるようにします。
最大の電流が流れるのは、充電直後でこの時抵抗1本あたり1.4V / 10Ω * 1.4V = 196mWで1/4w以下です。
また回路の電流は2.8V / 20Ω = 140mAで200mA以下です。

このような回路を使ってラズパイで電圧を記録していきます。
しかしながら、ラズパイにはアナログ入力がありません。
そこで、Arduinoのアナログ入力をラズパイに送って記録することにしました。

シリアル通信を作る

こちらのシリアル通信 ArduinoRaspberry Pi を参考にArduinoからラズパイにデータを送る仕組みを作ります。
shizenkarasuzon.hatenablog.com
ArduinoをUSBでラズパイに接続します。
ラズパイゼロはMicroUSBしかないので、変換ケーブルを使います。ラズパイ3や4ではそのまま接続できます。
認識されたかどうかはlsusbで確認できます。
f:id:s51517765:20210403224222j:plain

まずはサンプルコード(LED出力は削除)を試してみます。

// Arduinoで電圧の読み取りしSerialに出力
void setup(){
  Serial.begin(115200);
}

void loop(){
  Serial.println("LED ON");
  delay(1000);
  Serial.println("LED OFF");
  delay(1000); 
}
# ラズパイで PythonでSerial受信
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 115200)

while True:
    String_data = ser.read()
    print(String_data)
ser.close()

f:id:s51517765:20210402124835p:plain
1文字づつ出力されますがこれでは扱いにくいので、改行区切りになるように、改行しない限り文字列を結合するようにします。

import serial
import time
ser = serial.Serial('/dev/ttyACM0', 115200)

data = ""
while True:
    buf = ser.read()
    if buf != "\n":
        data += buf
    else:
        print(data)
        data = ""
ser.close()

f:id:s51517765:20210402125333p:plain

これで、シリアル通信は完成です。

電池の電圧を測定する。

電圧の読み取りはArduinoでanalogReadです。

  int val=analogRead(A2);
  Serial.println(val);

試しに電池の電圧を測定してみます。
f:id:s51517765:20210403222258p:plain
1.18V でAD240です。
5Vで1023なので 1.18 / 5 *1024 =241.4 なのでだいたい合ってそうです(誤差1%以下)。

これで、経過時間と電圧をカンマ区切りでprint()します。
実際に測定するときは、ラズパイでnohupにしてnohup.outに出力させます。

import serial
import time
from datetime import datetime as dt

ser = serial.Serial('/dev/ttyACM0', 115200)

start = dt.now()
print(start)
data = ""
prev = start
timer = 10
while True:
    try:
        buf = ser.read().decode('utf-8')
        if (dt.now() - prev).seconds < timer and buf == "\n":
            continue
        else:
            if buf != "\n":
                data += buf
            else:
                t = dt.now() - start
                prev = dt.now()
                print(str(t)+" , "+data)
                data = ""
    except:
        pass
ser.close()

ざっくり試算では2000mAhを140mAで、約14時間かかります。(2000mAh / 140mA = 14.2h)

結果発表

f:id:s51517765:20210403224956p:plain
約12時間で電圧が1.2Vを切りました。
抵抗は実測で21Ωでした。誤差は±1Ωとします。
これを寿命とし、区分求積法で時間 x 電流で容量を求めると、1386±66mAhとなりました。
定格の約70%です。思ったより多いです。

もう一組測定してばらつきをみてみます。
f:id:s51517765:20210404133922p:plain
同様に1.2Vを切るまでで電流容量を求めると1447±69mAhとなりました。
4%ほど多いです。また1.2Vを下回っても急激に電圧が落ちるまではもう少しあり、実際にはさらに10%ぐらい使えるかもしれません。

念のため重ねて比較してみます。
f:id:s51517765:20210404134715p:plain

まとめ

ニッケル水素電池の容量が減っている気がしたので実測してみました。
およそ70%程度にまで減っているといえそうです。
いつから使っているかはっきり覚えていませんが10年ぐらい使っています。
まだまだリモコンや時計などには使えます。