石原 博の覚書

電子工作に関する日々の覚書を記載します

LCメーターの作成

2023-03-19 14:49:01 | 日記
何年も前にどのサイトを参考にしたのか忘れたが、フランクリン発振でLCメータを作ろうとしたことがあった。
当時LM311 90S2313を使用し感光基板で作ったが、AVRの書き込み用のパターンの表裏を間違え、
意気消沈してそのままになっていた。
ほっておくのも勿体ないので、今回基板から部品を取り外し万能基板で作ってみた。

Web上には多数の同様なサイトがあるが、90S2313を使用していた
T. Nakagawaさん(https://middleriver.chagasi.com/electronics/lcmeter.html)のサイトを参考にさせていただいた。

回路的にはオーソドックスなのだが、ソフトウエアが凝っている。
90S2313(2KB ROM)なので小さくするため、浮動小数点数の演算を通常のCのライブラリではなく自前で作っている。
16ビットカウンタを使うため、カウントの上限は65535(2**16-1)。ゲートタイムは0.1sec なので約655KHzまでなら測定出来る。
回路上のキャパシタは1000pF インダクタンスは85μH なのはここから来ているようだ。
(f=1/(2*PI*SQRT(LC)) なので、1000pF 85μHで、546KHz)

色々情報を集めると、LM311の場合発振周波数は1.5MHz程度までに抑えた方が良さそう。
ただ分解能を上げるためには、周波数が高い方が良い。
今回使用した校正用のキャパシタは、共立電子で購入した1200pF これに合わせるインダクタンスは良いものがなかったので、
トロイダルコアで自分で巻いて60μH(*1)とした。これで発振周波数は593KHz程度となり655KHz内に収まる。
(キャパシタだけなら周波数の絶対的な値は不要なため、ゲートタイムを変更しても良いのだが、
インダクタンスは周波数の絶対的な値が重要)

Nakagawaさんのソフトウエアでは、校正用キャパシタの容量等を以下のように定義している。
=======
/* #define CONST_CCAL FP_CONST(1e16 * 1000e-12) */
/* #define CONST_R2PI FP_CONST(1e16 / (1000e-12 * M_PI * M_PI) / 1e2) */
/* #define CONST_UMAX FP_CONST(0x80000000) */

#define CONST_CCAL (( 8UL << 16) | 39063UL)
#define CONST_R2PI ((58UL << 16) | 35153UL)
#define CONST_UMAX ((11UL << 16) | 32768UL)
=======

最初はなんのことかわからなかったが、8ビット指数、16ビット仮数の内部表現ということで、
rubyで以下のスクリプトで計算してみた。

===スクリプト===
def cal(n)
e = 0
n = n.to_i
while (n >> 16) != 0
e += 1
n >>= 1
end
puts %Q|#{e} #{n}|
end

puts "1000pF"
cal(1e16 * 1000e-12)
cal(1e16 / (1000e-12 * 3.14159 * 3.14159) / 1e2)
cal(0x80000000)
#
puts "1200pF"
cal(1e16 * 1200e-12)
cal(1e16 / (1200e-12 * 3.14159 * 3.14159) / 1e2)
cal(0x80000000)

===実行結果===
1000pF
8 39062
58 35152
16 32768
1200pF
8 46875
57 58588
16 32768
======

この結果を元に1200pFの場合は以下のようにした。 (UMAXは良くわからないのでそのまま)
#define CONST_CCAL (( 8UL << 16) | 46875UL)
#define CONST_R2PI ((57UL << 16) | 58588UL)
#define CONST_UMAX ((11UL << 16) | 32768UL)



校正用のCをつながない場合の周波数をf1, つないだ場合の周波数をf2とすると
f1=1/(2*PI*SQRT(L*C))
f2=1/(2*PI*SQRT(L*(C+Ccal)
から
C=f2*f2/(f1*f1-f2*f2)*Ccal
L=1/(4*PI*PI*F1*F1)*(f1*f1-f2*f2)/(f2*f2)/Ccal
が得られる。

この式からCはf1,f2が定数倍変わっても問題ない->ゲートタイムに依存しないが、
Lはそうは行かないことがわかる。

プログラムではf1*f2-f2*f2=(f1-f2)*(f1+f2)として計算。f1+f2はオーバーフローを防ぐため
ADDDIV2で計算した(f1+f2)/2を使用している。
これによりval=C*2。Lについては、CONST_R2PIを使用し、val=L*2を計算している。

測定はそのvalを利用し、
Cx=f3*f3/(f1-f3)*(f1+f3)/2*val
Lx=f3*f2/(f1-f3)*(f1+f3)/2*val

最近のATmegaならROM容量が気にならないからdoubleで計算したと思うけれど、
なかなかすごい手法。

プログラムではLCD表示以外にもUARTを利用して信号を出しているが、
LCD以上の情報を出しているわけではないので削除し完成。



(*1)DE-5000を使用している。これがあるためいまさらLCメーターは必要ないのだが、趣味の工作なので。


その他
 そういえば30年以上前にキャパタンスメータを秋月のキットで作成したことを思い出して、
 実家を漁ったところ埃まみれの状態で見つかった。82pFのキャパシタを測定したはずなんだけどかなりずれている。
 今更見直しても仕方ないので、記念においておこう。昔からやっていることは変わらないな。

 


最新の画像もっと見る

コメントを投稿