lyricalmagicalのアイコン画像
lyricalmagical 2026年01月30日作成 © CERN-OHL-P 2
製作品 製作品 閲覧数 49
lyricalmagical 2026年01月30日作成 © CERN-OHL-P 2 製作品 製作品 閲覧数 49

arduino UNOで超簡易にコンデンサ容量測定をする

概要

コンデンサ(特にスイッチング電源の電解コンデンサ)は古くなるとよく死ぬものです。
総取り換えで大体治るのですが、その時外した電解コンデンサって生きてるのか死んでるのかわからないのに処分するのは勿体ないですよね。
まあ、生きててもどうせ時間の問題で近いうちに死ぬんですが、貧乏性としては生きてればちょっとした実験とかに持ち合わせがないときくらいには使えるので、生死判定をしたいものです(そんなこと言ってないで捨てろ)。

というわけで、コンデンサの実容量を(ざっくり概算で)調べてみようというものです。

原理

容量を測定する原理についでです。まず単純にコンデンサに抵抗Rを介して電源に接続します。
回路図
この場合、コンデンサの端子電圧V(t)V(t)は、以下の式で表されます(なんでこうなるかは省きます。電磁気学とかの領域のはずです)。

V(t)=V0(1etRC)V(t) = V_0 \left( 1 - e^{-\frac{t}{RC}} \right)

tは時間(秒)、Rは抵抗値(Ω)、Cは容量(F)、V0V_{\text{0}}は電源電圧です。
このことから、V0V_0、R、が決まっていれば、特定の電圧V(t)V(t)まで充電されるまでの時間tがわかれば、Cを求めることができます。
これを式変形するのですが、
1e10.6321-e^{-1}\approx 0.632
を踏まえて、
V(t) = (1e1)V0(1-e^{-1}){V_0}
とし、
(1e1)V0=V0(1etRC)(1-e^{-1}){V_0} = V_0 \left( 1 - e^{-\frac{t}{RC}} \right)
するとその後が楽になります。
※つまり充電完了電圧を5×0.632Vとする

・両辺を V0V_{\text{0}}で割る
1e1=1etRC1-e^{-1} = 1 - e^{-\frac{t}{RC}}

・項を整理
e1=etRCe^{-1}=e^{-\frac{t}{RC}}

・両辺ともにeの指数項となっているため、両辺の自然対数lnをとり、Cを指数項でなくする
1=tRC-1=-\frac{t}{RC}

・両辺に-Cをかけて、
C=tRC=\frac{t}{R}

となり、tを測れば割り算一発でコンデンサの容量を求めることができます。

作る

非常に簡単です。原理としては、GPIOポートから抵抗を通して測定対象コンデンサを充電し、その端子電圧を測ります。
A5とA1の間に1kΩの抵抗、A1とGNDの間に測定対象のコンデンサを接続します。
回路図よりも写真を見てもらったほうがわかりやすいでしょう。
これだけです。
キャプションを入力できます

ソースコード

簡易容量チェッカー

#define step 500000 #define R1 1000 void err( char * str){ Serial.println(str); while(1){} } void setup() { int i; Serial.begin(9600); Serial.println("start"); pinMode(A1, OUTPUT); pinMode(A5, OUTPUT); digitalWrite(A5,1); digitalWrite(A1,1); for(i=0;i<1000;i++){ if (analogRead(A1)==1023){i=999;} delay(1); } if (i!=1000){Serial.println(i);err("value 1 error");} digitalWrite(A5,0); digitalWrite(A1,0); for(i=0;i<1000;i++){ if (analogRead(A1)==0){i=999;} delay(1); } if (i!=1000){err("value 0 error");} Serial.println("mesure start"); } void loop() { pinMode(A1, INPUT); unsigned long s_time = micros(); digitalWrite(A5,1); unsigned long next=s_time+step; while(analogRead(A1)<647){//1023の0.632121%にするとlogの計算がいらない if(micros()>next){ next=next+step; Serial.print("."); } } unsigned long e_time = micros(); unsigned long t = e_time-s_time; Serial.print(t); Serial.println(" us"); double C = t/R1; Serial.print(C); Serial.println(" uF"); while(1){} }

動作

(1)まずキャリブレーションをします。としたかったのですが、めんどくさいので0Vと5VでADCがフルレンジ(0~1023)で振れるかを確認しています。
A1とA5に1を出力し、A1のADC値が1023になることを確認します。この時点でコンデンサに充電が始まりますので、1023に達するまでに多少時間がかかります。
一定時間(ここでは1000ms)以内に1023にならなかった場合、エラーとしています。
コンデンサの容量によってはそこそこGPIOに電流が流れる気がしますが気にしないことにします^^;
※要改善検討ポイント

(2)次に、A5とA1に0を出力し、A1のADCが0になることを確認します。ここで、コンデンサの初期放電も行います。そのため、ここでも多少時間がかかります。
手元のボードでは問題なくフルレンジに触れましたが、もしかするとフルレンジで振れないボードがあるかもしれません。
もしフルレンジに振れないボードがあるなら、測定値に対してオフセットが必要でしょう。

(3)充電し、電圧が5×0.63V(ADC値で1023×0.63=647)になるまでの時間を測定します

(4)測定した時間からコンデンサの容量を求めます
R=1KΩの場合、測定値(us)/1000で容量(単位uF)が求められます。

理論上どんな容量でも測定できるはずですが、容量によってはかなり精度に問題がある(容量が小さいとき)場合や、測定にかなり時間がかかる時があるので、測定対象によって抵抗(と計算の定数)を変更するのがよいでしょう。
R=1000Ωの場合、1uF~4700uFあたりが実用範囲と思います。

おわりに

充電側のGPIOの内部抵抗や、外付け抵抗の誤差で測定容量にはそこそこ誤差が含まれます。
今回は主にそこそこ容量大き目電解コンデンサの生死判定を対象として考えましたので、そのあたりは無視することにします。

ちょっと実験に使うときに手持ちがないときなど、部屋に転がってるジャンク基板とかから部品取りしてきたりすることがあるかと思いますが、そういったときに生死判定がお手軽にできるのであれば便利ですね。
複数GPIOを使って抵抗値を自動切換えするようにするとかもできると思うので、もう少し汎用的にして小型のarduinoボードとOLEDを使って単体で測定できるようなものを使ると便利そうです。

lyricalmagicalのアイコン画像
FPGAとか好きな人
ログインしてコメントを投稿する