2014年4月30日水曜日

Ni-MH充電器の製作(9)


前回少し話しましたように、古い電池で充電が不十分と思われる現象があり、その改善を検討していましたが、さらに大きな問題が埋もれており、検討し直す事態となりました。

条件を網羅してテストした積もりが、非常に御粗末な状況になっており、毎回申訳ありません。

以下は、前回に続く顛末の報告です。

9 残問題の処置

9.1 顕在問題の対処

いろいろな電池で実験を行ううちに、特に古い電池において、充電が終止電圧に達せず、すぐ終了してしまう現象が発生しました。

電圧の推移を調べると、充電開始後ほどなく、終止電圧 1.38V※ に達して充電終了し、終了後の電圧は、1.1V 程度しかありません。
この状況から、古い電池は内部抵抗が高く、充電電流による電圧降下(吸い込んでいるから、充電電圧は上昇)で、充電完了しないのに終止電圧に達していると考えました。

※ 実際は、この電圧も正確ではありませんでした(次項を参照)。

今回の終止電圧は、回路やプログラムの誤差を考慮して決めましたが、誤差を終止電圧に転嫁することは、本来適切ではありませんでした。
よって、誤差をもう少し追い込んで、終止電圧を本来の 1.4V まで引き上げることにします。

電圧検出に影響する要素として、以下が存在します。

回路面では・・・
・電圧検出用抵抗(R15 ・ R16)
・ADC の Vref( = AVcc)

プログラム面では・・・
・ADC分解能
・電圧の計算・比較

まず回路面において、マルチメータで実測して、誤差がどの位か確認します。

回路要素規格値実測値誤差
R151kΩ998Ω0.2%
R16470Ω470Ω0%
Vref(=AVcc)5.00V5.04V0.8%

この実測値に合わせて、プログラムの定数値を修正します。


次にプログラム面ですが、ADCの分解能は、10ビット固定であり、変換誤差 eADC は、

eADC = (1 / 1024) × 100% = 0.1%

また、電圧の計算は、6.2.2項の通り、10ビットデータで計算していますので、

D(VBatt) = 1024 / 5V × 1.4V = 286.72

これを四捨五入して 287 と定数宣言すれば、誤差 eVbatt は、

eVbatt = 286.72 / 289 × 100% = 0.1%

プログラム面の変換誤差も追い込むに越したことはありませんが、これはADCが10ビットである限り避けられませんので、回路定数のみ反映し、終止電圧を1.4Vに修正してみます。


今度は、充電が終了しません・・・上記の誤差など論外となる問題が内在していました。


9.2 潜在問題の検討・対処

充電が終了した電池の温度がかなり高くなっています(手で触って、熱く感じる)。

当初は、これも電池の加齢が原因ではと考えましたが、比較のため、新しい電池を購入して充電したところ、1.38V で終了せず、1.47V 付近!まで充電が続く状況となりました(当然この電池も熱くなる)。

もはや電池の問題ではなく、電圧検出に重大な問題が存在するようです。

まず回路面は、前項で確認しましたので問題無い筈です。
次に、プログラム面を探って行きます。

ADCの分解能は、10ビット固定であり、以下が守られていれば、10ビット値が正しく読めています。

ADMUXレジスタのADLARビットを操作せず、変換結果が左揃えになっていない。
・変換結果を、ADCWレジスタを使用して読んでいる。

上記は正しく設定されています。

また、変換結果の変換式は、D = 1024/Vref で計算されており、その誤差に前項計算値 0.1% を見込んでも、当然問題はありません。

続いて、検出電圧の計算を調べます。

電圧検出の計算箇所を抜粋してみます。

#define R_15 998

#define R_16 470

//(中略)

uDataI = ADC_GetData(1); // get current(ADC1)

uDataV = ADC_GetData(0); // get voltage(ADC0)

uint16_t uDataB = (uint16_t)(1 + R_15 / R_16) * uDataV - UdataI;


R15・R16 を宣言して、6.2.2項の通り計算していますが、宣言が整数値のため、R15/R16 の計算も整数のままです

本来なら、 R15 / R16 は 2.12 ですが、現状では少数点切捨てで 2 と計算されています。
誤差は6%に及びます。

原因は確定しましたので、少数点が正しく計算できるように、抵抗値が浮動少数点計算されるように、宣言と計算を以下の通り修正します。

#define R_15 998.0F

#define R_16 470.0F

//(中略)

uint16_t uDataB = (uint16_t)(1.0F + R_15 / R_16) * uDataV - UdataI;


998F などの表記では、AVR Studio ではコンパイルエラーとなりました。

この対策により、ようやく 1.4V で充電終了するようになりました。


9.3 お詫びと反省点

このような問題は、本来テストの初期で検出できて当然ですが、今回以下の理由で検出できませんでした。

・電圧の監視をアナログテスタの10Vレンジで行っていた。
・充電中に適切な観察をしていなかった。

電圧の検出に10mVオーダーの誤差が求められるので、精密な測定器を用いるのは当然のことで、また、データロガーなどを用いて、電圧及び時間の経過を正しく把握するのも当然のことですが、手持ちにアナログテスタしか無く、上記を怠っていたのです。

しかも、9.2項の問題を内包しながら、9.1項のように充電がすぐ終了する現象の発生は起こり得ず、実験過程に疑義すら生じています。
※ 実際に、9.1項の問題は、9.1項の時点に回路・プログラムを戻して実験しても、再現しません。

正確に、客観的かつ定量的な実験を行わなければ、品質を確保することはできません。

今後は、最低限の備えとしてマルチメータを用意し、以降の実験を行うものとし、データロガーは予算が付き次第導入することにします。


次回の予定

全く手つかずである、ケース加工や組み立てを行う予定です。