JIS C8708:2019充放電試験回路試運転
JIS C8708:2019充放電試験回路製作中、ざっと
制御ソフトが出来たので試運転中です。
今回はJIS C8708:2019の充電条件へ対応。
「0.5Cで132分 又は -ΔV(5mV~10mV)」
これに対応するため、電池電圧を読むA/D入力に
アンプを入れました。
Arduino(ATmega328P)のA/Dコンバータは10bit。
基準電圧を2.5Vにして0~2.5Vをそのまま入力
すると1ビットが約2.44mV。
5~10mVの-ΔVを拾うとすると、その変化量は
2~4ビットと微少。
もうちょい分解能が欲しいか、ということでこんな
アンプをA/Dの前段に入れました。 (U6 1,2,3のところ)
考え方
・電池の寿命試験で電池電圧を測るのに0V付近は不要。
・0.9Vくらいから2.0Vの範囲を測れたらよいんじゃないか。
・A/Dの分解能を1ビットを1mVくらいにしたい。
・とりあえず、入力範囲を0.85V~2.1Vにして、測定スパン
を1.25Vに。
・これを2倍に増幅。
・1ビットはきっちり1mVにはならないで約1.22mV。
こんな回路になっています。
また、A/D入力処理も、速度は不要なんで
・1mSごとのA/D変換で、256回の加算平均処理。
256回分10ビットのA/D値を加算合計して、256回目に
1/256して平均値を算出。256mSごとにA/Dデータが確定。
・この平均値を16回移動平均。
リングバッファの古いのを捨てて新しいのを加える。
・さらに、バッファのデータをソートして、上下それぞれ
4つのデータを捨て(maxに近い4つとminに近い4つ)、
8つの中央値で平均計算。
・256mSごとにこのスムージング処理したデータが確定。
16回なんで、A/D入力値が安定するまで約4秒。
・これで、一瞬の短絡や開放はデータに出てこない。
こんな処理で-ΔVを見つけるようにしました。
これでうまく処理できるか、試運転中です。
※OP-AMPについて
今回使ったMCP6072、電源電圧5V以下で使うならおすすめです。
特徴
・安価 100円くらい ただしDIPは無い
・レール to レール入力/出力
・ゲインバンド幅 1.2MHz
・低オフセット電圧 0.15mV(max) ★
・入力バイアス電流 1pA (CMOSなんで)
・低消費電流 0.11mA
・動作電圧範囲 1.8V~6V
オフセット電圧の小さなCMOSアンプって、なかなか
ないんですよね。
ただ、DIP品が無いので試作にはピッチ変換基板が必須です。
※追記
・1msタイマー処理とその中で起動されるA/D変換。
・A/D割り込みで行う256回のA/D値平均処理。
↑
この2つの処理は割り込みで行うので、時間待ちは無し。
勝手にA/D平均データが上がってきます。
この中でスイッチ入力処理とブザー報知処理も実行。
液晶画面表示を行っていると、スイッチのチャタリング除去
処理やブザー報知の処理が遅れることがあるんで、タイマー
割り込みの中で勝手に処理するようにします。
・メインルーチン内でf_adokフラグをチェックして
行う256msごとのA/D値スムージング処理。
ソートを行うので、割り込み内からは出してます。
これを示しておきます。 (スペースは全角で)
/********************************/
/* 1ms タイマー割り込み */
/********************************/
// 関数プロトタイプ宣言 (タイマー割込み内で処理)
void swscan(void); // SW入力スキャン
void bzzexc(void); // ブザー報知実行
/***** タイマーデータ *****/
volatile byte tm_1ms; // 1msダウンカウントタイマー
volatile byte tm_10ms; // 10msダウンカウントタイマー
volatile byte f_1sec; // 1秒経過フラグ
volatile byte f_1min; // 1分経過フラグ
// 測定用タイマー(カウントアップ)
byte f_tmion; // 計時指令
// onで計測タイマーをカウントアップ
volatile word tmi_1min; // 1分 カウントアップタイマー
// 24時間で1440分 999分で16時間39分
volatile byte tmi_1sec; // 1秒 カウントアップタイマー
// 00~59
volatile byte tmi_10ms; // 10ms カウントアップタイマー
// tmmreadで読む測定タイマー
word tmm_1min; // 1分 max5999分=99時間59分
byte tmm_1sec; // 1秒 0~59
/***** タイマー0コンペアマッチA割込み *****/
// 割り込みでパルス出力(1kHz周期)
ISR(TIMER0_COMPA_vect)
{
static byte cnt10 = 0;
PB0_H; // (!!!) 14pin
if(tm_1ms) tm_1ms--; // 1msダウンカウント
// 10msタイマー
cnt10++;
if(cnt10 >= 10){
cnt10 = 0;
if(tm_10ms) tm_10ms--; // 10mS ダウンカウント
if(f_tmion){ // 計時する?
tmi_10ms++;
if(tmi_10ms >= t_spdup){ // 100カウントで1秒
tmi_10ms = 0;
f_1sec = 1; // 1秒フラグをオン
tmi_1sec++; // +1秒
if(tmi_1sec >= 60){ // 60秒
tmi_1sec = 0;
f_1min = 1; // 1分フラグをオン
tmi_1min++; // +1分
if(tmi_1min >= 6000){ // 6000分越え?
tmi_1min = 5999;
tmi_1sec = 59; // 99時間59分59秒に
}
}
}
}
}
// 1ms処理関数
swscan(); // SW入力スキャン
bzzexc(); // ブザー報知実行
// 内蔵A/D開始
ADCSRA |= (1 << ADSC); // A/D変換開始
PB0_L; // (!!!) 14pin
}
/******************************/
/* 内蔵A/D処理 */
/******************************/
/**** A/D データ *****/
#define ADAVR_ADD 256 // A/D平均回数
volatile word ad_avr; // A/D変換データ 0~1023
// 平均処理された結果
volatile ulong ad_add; // A/D平均処理用加算データ
volatile byte f_adok; // A/D変換完了フラグ
// 割り込みでセット
// 平均処理確定でad_avrを転送 電池電圧に変換
byte f_advolt; // A/Dデータ転送変換完了フラグ
word ad_data; // 電圧A/D値 (平均値)
word bat_ad; // スムージング処理結果A/D値 (0~1023)
word bat_volt; // 電池電圧 bat_adをmV値に変換
word bat_peak; // 電池電圧ピーク値(mV)
word bat_deltav; // ΔV値 ピーク-現在値 (mV)
byte f_peakon; // ピーク検出開始フラグ
/***** A/D割り込み処理 *****/
// 1msタイマー割り込みでA/D変換開始
// 256回で平均値算出
ISR(ADC_vect)
{
word d;
static word cnt = 0; // A/D変換平均回数
PB4_H; // (!!!) 18pin
d = (word)ADCL; //
d |= (ADCH & 0x03) << 8; // 符号なしで 0~3FF
// 測定値
ad_add += (ulong)d; // 平均用に加算
// 平均処理
cnt++; // 平均加算回数
if(cnt >= ADAVR_ADD){ // 256回?
cnt = 0;
ad_avr = (word)(ad_add / ADAVR_ADD); // 平均
ad_add = 0L; // 次加算データクリア
f_adok = 1; // 変換完了
}
PB4_L; // (!!!) 18pin
}
/***********************************/
/* A/Dデータスムージング処理 */
/***********************************/
// 処理バッファ
word ad_smzbff[16]; // A/Dデータ保存バッファ
word ad_sort[16]; // ソート用バッファ
/***** qsort用データ比較 *****/
// wordで比較
int wordcmp( const void *p, const void *q ) {
if( *(word *)p > *(word *)q ) return 1;
if( *(word *)p < *(word *)q ) return -1;
return 0;
}
/***** スムージング処理 *****/
// 16コのA/Dデータを順にサンプル
// ソートして上下4コ(8コ)を捨て、中央の8コを平均
// 256ms X 16 = 4.096秒後に安定
word adsmz(word d)
{
static byte f1 = 0; // はじめてフラグ
static byte wp; // 書き込みポインタ
byte i;
long a;
word b;
if(f1 == 0){ // 初めて
f1 = 1;
for(i = 0; i < DIMSIZ(ad_smzbff); i++){
ad_smzbff[i] = d; // バッファを初期データで埋める
}
wp = 0; // データ書き込みポインタ
}
else{ // 2回目以降
ad_smzbff[wp] = d; // A/Dデータをストア
wp++; // 書き込みポインタを進める
if(wp >= DIMSIZ(ad_smzbff)) wp = 0; // 一周回って先頭に
}
memcpy(ad_sort, ad_smzbff, sizeof(ad_smzbff)); // バッファにコピー
qsort(ad_sort, DIMSIZ(ad_sort), sizeof(word), wordcmp); // qsort実行
// 中央の8つで平均処理 上下4コは捨てる
a = 0; // 合計
for(i = 0; i < 8; i++){ // 中央の8コを加算
a += ad_sort[4 + i]; // 4コ目から8コを加算
}
b = word(a / 8); // 1/8して平均値
if((a % 8) >= 4) b += 1; // 四捨五入
return b;
}
全体のスケッチはまた今度に。
| 固定リンク
「電池」カテゴリの記事
- 秋月電子で買った単3ニッ水GoldenPower 2100mAhを試す(2023.12.03)
- 放置していた2014年製「eneloop lite」の充放電実験、4000cycで終了(2023.12.01)
- トラ技に投稿した記事が参考文献に記されているとちょっとうれしいゾ(2023.11.24)
- タミヤ★★ミニ四駆用充電池「NEO CHAMP」950mAh 4400サイクルで終了(2023.11.20)
- 絶滅品種:パナソニックのオキシライド乾電池(2023.10.24)
「電子工作」カテゴリの記事
- TRWの16pin DIP IC「8543」 これは何?(2023.10.06)
- 予告:「マイコン型導通チェッカー」「電池電圧チェッカー」値上げします(2022.11.16)
- 三和の針式テスター「GP-5」不調(2022.10.18)
- 「ダイソー ミニケース 5個組」が見つからない #2(2022.10.12)
- 「ダイソー ミニケース 5個組」が見つからない(2022.09.29)
「Arduino」カテゴリの記事
- Arduinoで「ボコスカハンマー」 あれれれれっ?!(2023.12.07)
- Arduino UNO R3で±19.9V表示電圧計(2023.10.14)
- 「御詠歌プレーヤー」の製作 (MP3-TF-16Pモジュールの使用例)(2023.08.10)
- Arduino UNO R3のソケット・・思えば違和感がぁ(2023.07.07)
- 初めて買ったArduino UNO・・・今は(2023.05.25)
コメント
2020年04月10日:JIS C8708:2019対応ニッケル水素電池充放電実験回路(回路図とプログラム)
http://igarage.cocolog-nifty.com/blog/2020/04/post-614212.html
投稿: 居酒屋ガレージ店主(JH3DBO) | 2020年4月11日 (土) 09時36分