電池を直列接続で使っていると、電極が反転してしまう(転極)電池が出てきてしまいます。これは特に古い電池を使いまわしているときに発生しやすいようです。
<参考>
電池をテスターで電圧測定するとプラスとマイナスが逆に表示されますがなぜですか?
目的
まめのプラモデル工房のコンセプトの1つとして、「家電で使えなくなった電池を最後まで使い切る」があります。そのため、古い電池(電圧の異なった)をランダムに使うことになりますので特に転極が発生しやすいです。
転極が発生した電池は液漏れしやすいので、早々に交換する必要があります。
電源電圧が下がれば、マイコンも動作しなくなりますが、まめ工房で主につかっているのは、XLP(超低消費電力)タイプのPICなので定格1.8v~になっています。先にLEDが点かなくなるでしょう。いまは動作しなくなった時点で電池を取り外し、1本1本テスターで測っています。
大体は1本だけ転極してしまって、残り2本はまだ使えそうな電圧になっています。
テレビやエアコンのリモコンで使えなくなった電池でもこの基板では数か月間動いているので、電池を変えることは滅多にありませんが、毎回テスターで測るのも少々面倒です。
そこで、直列の電池の1本1本をセットしたまま計測できるかテストしてみました。
開発環境
開発PC
THERDWAVE Magnate IM
13th Gen Intel(R) Core(TM) i5-13400 RAM16GB,SSD 500GB
Windows 11 Home 22H2
ソフトウェア
統合開発環境: MPLAB X IDE Ver 6.15
MCC Ver 5.3.7
Cコンパイラ: XC8 Ver 2.45
マイコン書き込み、デバッグツール
PICkit3
ターゲットデバイス
PIC12F1827
まめの開発環境についてはこちらを参照してください。
ターゲットボード
ターゲットは以下の回路をブレッドボードで組みました。
基本的には「PICガジェット制作1 MCC設定を使い電源電圧を測定する」の回路に8ピンと9ピンをBT2とBT3に接続しただけです。LEDは各バッテリーの電圧状態を表示するために取り付けてみました。
プログラム作成手順
プロジェクトを作成する
MPLAB X IDEを起動して、プロジェクトを作成します。作成手順は「PIC開発環境の整備4 PICkit3の動作確認」を参考にしてください。
MCCでPICの情報を設定
MCC(Microchip Code Configurator)を使ってPIC16F1827の設定をしていきます。
基本的な設定は、「PICガジェット制作1 MCC設定を使い電源電圧を測定する」を参照してください。
今回は、その設定に追加でRB1(電池1電圧測定), RB2(電池2電圧測定), RB4(LEDの点滅)の信号の設定を追加していきます。
「Pin Manager. GridView」でPort B2,3でADC ANx inputを設定します。
同様にPort B 4はGPIO outputを選択します。
各選択後、Pin ModuleのEasy SetupでCustom Nameを
RB2: V2 Analog
RB3: V1 Analog
RB4: LED Output
に書き換えと、チェックを選択します。
「Project Resources」で[Generate]をクリックします。
mcc_generated_filesのフォルダに基本設定と自動生成関数が生成されています。
この中に生成された関数を利用してコーディングをしていきます。
プログラムコーディング
uint16_t vdd = ADC_GetConversion(channel_FVR);
float fVdd = 1047.552 / (float)vdd;
で電源電圧を取得します。
<参考>なよよんのホームページ
uint16_t row_v1 = ADC_GetConversion(V1);
float fV1 = (float)row_v1 / 1024.0 * fVdd;
で電池1の電圧を計算しています。
同様に電池2の電圧を計算します。
最後に各電池の電圧を計算して0.5v未満のときLEDを点滅させています。
電池毎にLEDの点滅方法を変えています。
void LED_Flush(uint8_t n)
{
for(uint8_t i = 0;i < n; i++)
{
LED_SetHigh();
__delay_ms(500);
LED_SetLow();
__delay_ms(500);
}
}
void main(void)
{
SYSTEM_Initialize();
while (1)
{
uint16_t vdd = ADC_GetConversion(channel_FVR);
float fVdd = 1047.552 / (float)vdd;
uint16_t row_v1 = ADC_GetConversion(V1);
float fV1 = (float)row_v1 / 1024.0 * fVdd;
uint16_t row_v2 = ADC_GetConversion(V2);
float fV2 = (float)row_v2 / 1024.0 * fVdd;
if( fV1 < 0.5 )
{
LED_Flush(1);
}
if(fV2-fV1 < 0.5)
{
LED_Flush(2);
}
if(fVdd-fV2 < 0.5)
{
LED_Flush(3);
}
__delay_ms(5000);
}
}
電池の測定結果
ここでは、3本目の電池が0.5v未満の電池に変えてあります。(青い電池)
この時のPICのLED出力をオシロスコープで測定した結果です。
本回路とプログラムで各電池の電圧を測定することが可能になりました。電源電圧Vddを基準にしているので、Vddが変化すると各ADCが触れてしまいますが、ここでは直列電池の転極を事前チェックするのが目的なので、電圧測定の精度は目を瞑っています。
まあ、それでも弱ってきた電池の検出が出来ているので、機能としては合格だと思っています。
プログラム容量について
Memoryの使用状況が「Dashboard」で確認できます。
ここでは、既に58%ほどProgram Memoryを使用していることがわかります。XC8のFreeバージョンを使っていますので、最適化はされていません。
MCCを使っていることが原因なのか、まだ判断ができませんが、今後プログラム容量を減らす工夫を検討していこうと思います。
ちなみにLED_Flush(uint8_t n)の関数内で使っていた変数をuint16_t型からuint_8t型にしただけで1%減少しました。