JF1DIR業務日誌(はてなblog版)

アマチュア無線局JF1DIRのアクティビティをつづっています。

バッテリーの充放電特性の測定

久々に運用でないネタです^^;
移動運用などでバッテリーを使用していると、バッテリーの調子や寿命が気になるところです。バッテリーが完全にダメになっているときは、満充電時放電直後の電圧がおかしかったり(瞬時に電圧が低下する)やいつまで経っても満充電されないなどの症状が出るので判明しやすいのですが、そうでないときはなかなか分かりません。シールドバッテリーだと電解液の様子がまるで分かりません。バッテリーの診断方法はいろいろあるようですが、充放電特性を計測してみるのが基本だと思いますので、やってみました。

任意の電流値でバッテリーを定電流放電させて、バッテリーの端子間電圧の時間経過を測定すればよいということです。定電流負荷は電子負荷を使えば簡単です。自作の電子負荷装置を活用してみました。電圧の測定はなんでも良いのですが、手持ちのDMM(Keithley 2000)をシリアル通信によってロギングすることにしました。プログラミングもせっかくなのでLinux上のpythonでやってみます。Linuxでシリアル通信は初めての試みなので、備忘録代わりに設定から書いてみます^^;

まずはシリアル通信の設定方法。使用しているPCには当然RS-232Cポートがないので、USBシリアル変換アダプターを用意しました。バッファロのBSUSRC06という型番のもので、FTDIのFT232RLが使われています。他のものでも動くと思います。PCに挿してdmesgコマンドを使うとどこのポートに割り当てられたかわかります。

jf1dir@dir:~$ dmesg | grep 'USB' | tail
・
・
・
[ 6828.533327] usb 2-1.1: new full-speed USB device number 7 using ehci-pci
[ 6828.626947] usb 2-1.1: New USB device found, idVendor=0403, idProduct=6001
[ 6828.626955] usb 2-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 6828.626959] usb 2-1.1: Product: USB <-> Serial
[ 6828.627682] ftdi_sio 2-1.1:1.0: FTDI USB Serial Device converter detected
[ 6828.628132] usb 2-1.1: FTDI USB Serial Device converter now attached to ttyUSB0
jf1dir@dir:~$ 

ここでは/dev/ttyUSB0に割り当てられたことがわかります。ubuntuだけの問題なのか、このポートは読み書きの権限が一般ユーザーにありません。

jf1dir@dir:~$ ls -l /dev/ttyUSB0 
crw-rw---- 1 root dialout 188, 0 1229 20:40 /dev/ttyUSB0
jf1dir@dir:~$ 

この問題を回避する方法で一番簡単なのが、/etc/udev/rules.dの下に.rulesという拡張子のファイル(ファイル名はなんでもOK)に

KERNEL="ttyUSB*", MODE="0666"

と書いておけばOKです。sudo service udev restartで再起動してもう一度変換アダプターをPCに挿すと書き込みの権限がついた状態でポートが生成されているはずです。

次に、DMMのRS-232C端子にUSBシリアルアダプタを接続して動作チェック。WindowsならハイパーターミナルやTeratermに、Unixならばgtktermで接続し、SCPIコマンド":INIT"の後、":MEAS:VOLT:DC?"とすると電圧をワンショット測定し測定結果が表示されるはずです。SCPIコマンドはメーカーに関係なくほぼ共通です。詳しくはDMMのマニュアルを参照^^;

次にハードの設定。バッテリーの端子とDMMを接続します。今回はマルチプレクサも用意できたのでスキャナカードのch1にバッテリー端子間、ch2に電子負荷の電流値シャント端子を接続しておきました(電流値を電圧値としてセンス)。

DMMとの通信チェックがOKならば、次に、pythonのシリアル通信ライブラリのpySerialをpipを使ってインストールします。せっかくなのでpython3用にインストールしました^^;

ロギングプログラムのpython3ソードコードはこちら。測定停止はCTRL+Cで強制停止させてます^^;

import serial
import time
ser = serial.Serial(port = '/dev/ttyUSB0', baudrate = 9600, 
                    bytesize = serial.EIGHTBITS,
                    parity = serial.PARITY_NONE,
                    xonxoff = 0,
                    rtscts = 0,
                    timeout = 1)
start = time.time()
ser.write(b':INIT:CONT\r\n')
ser.write(b':SENS:VOLT:NPLC 1\r\n')
while True:
	time.sleep(10)
	ser.write(b':ROUT:CLOS (@1)\r\n')
	ser.write(b':MEAS:VOLT:DC?\r\n')
	v_value = float(ser.readline().decode('utf-8'))
	ser.write(b':ROUT:CLOS (@2)\r\n')
	ser.write(b':MEAS:VOLT:DC?\r\n')
	i_value = float(ser.readline().decode('utf-8')) / 0.0317
	elasped_time = float(time.time() - start) / 60.0
	print("T:%6.2f, V:%10.6f, I:%10.6f" % (elasped_time, v_value, i_value))
ser.close()

python3のpySerialでは送受信データはstr型ではなくbytes型なのでb'foobar'のようにbをつけて明示的にbytes型にしないとエラーが出ます。センス電圧を0.0317で割ると電流値が得られるのでそう指定しておきます。
サンプリング間隔はsleep文で10秒に設定したのですが、NPLC(積分時間)が1秒なので測定に各チャンネル1秒必要になります。従って、約12秒ほどのサンプリング間隔となっています。

プログラム開始とともに電子負荷をONにすると定電流放電が始まります。ログファイルをグラフ化するとこのような放電特性が得られます。

ここで例としてかなり使い古した10.8V(単セル3.6V)10Ahのリチウムイオン電池を3A(0.3C)の定電流で放電したときの放電特性を示しました。約90分で電圧が急降下していることがわかりますが、90分ではまだ4.5Ahです。従って、だいぶ古くなっていることがわかりました(汗)。丁寧に調べるには放電電流を変えて、放電停止(1セルあたり2.5Vくらい)まで放電して特性を調べるとよいようです。