morecat_labさんのtwitterでaruduinoの周波数カウンタのライブラリを知りました。
精度、安定度は不明ですが周波数から逆算するLCメータが作れるのでは? なんて考えました。
基本的考え方はtiny2313vでLCメータと同じでソフト部分だけ妄想してみました。
実数を使うとどれくらいメモリーを消費するか調べるために基本部分だけです。
コンパイルサイズは
Binary sketch size: 6406 bytes (of a 32256 byte maximum)
なので余裕です。
ハード部分は後日tiny2313vでLCメータを分解して再利用予定。
/*
Martin Nawrath KHM LAB3
Kunsthochschule f¸r Medien Kˆln
Academy of Media Arts
http://www.khm.de
http://interface.khm.de/index.php/labor/experimente/
*/
/*
Masahiko KANETAKA
kane4d@gmail.com
http://kane4d.blogspot.com/
Port MAP
D0 I RX
D1 O TX
D2
D3 I LC Mode SW (High: C, Low: L)
D4 I Zero Adjust Botton
D5 I Wave(Frequency)
D6 O LCD d7
D7 O LCD d6
D8 O LCD d5
D9 O LCD d4
D10 O LCD enable
D11 O LCD rs
D12 O Relay drive
D13 O LED
*/
#define USE_SERIAL
#define USE_LCD
#include <FreqCounter.h>
#ifdef USE_LCD
#include <LiquidCrystal.h>
#endif
double getfreq(unsigned int f_comp = 10, int gateTime = 100);
#ifdef USE_LCD
LiquidCrystal lcd(11, 10, 9, 8, 7, 6);
#endif
double frq1_r = 0.0F, frq2_r = 0.0F, frq3_r = 0.0F;
double val_r;
int cnt;
bool cal_bool = false;
#define pinLed (13)
#define pinRelay (12)
#define pinZeroAdjBtn (4)
// High: C, Low: L
#define pinLCModeSW (3)
#define DEFAULT_TRY_COUNT (3)
//1000pF + 100uH
#define CAL_CAP (1000.0F)
double getfreq(unsigned int f_comp, int gateTime)
{
double _frq_r = 0.0F;
FreqCounter::f_comp = f_comp; // Cal Value / Calibrate with professional Freq Counter
for(int i = 0; i < DEFAULT_TRY_COUNT; ++i){
FreqCounter::start(gateTime); // 100 ms Gate Time
while (FreqCounter::f_ready == 0) ;
_frq_r += FreqCounter::f_freq;
}
return _frq_r / DEFAULT_TRY_COUNT;
}
void setup() {
pinMode(pinLed, OUTPUT);
pinMode(pinRelay, OUTPUT);
pinMode(pinZeroAdjBtn, INPUT);
pinMode(pinLCModeSW, INPUT); // High: C, Low: L
#ifdef USE_SERIAL
Serial.begin(9600); // connect to the serial port
Serial.println("LC Meter v0.1");
#endif
#ifdef USE_LCD
lcd.clear();
#endif
//frq1_r = frq2_r = frq3_r = 0.0F;
}
void loop() {
if ( ! digitalRead(pinZeroAdjBtn) && ! cal_bool ){
//zero cal
digitalWrite(pinRelay, false);
delay(30);
frq1_r = getfreq();
digitalWrite(pinRelay, true);
delay(30);
frq2_r = getfreq();
digitalWrite(pinRelay, false);
cal_bool = true;
}else{
cal_bool = false;
if ( frq1_r > 0.0 && frq2_r > 0.0 ){
digitalWrite(pinRelay, false);
delay(30);
frq3_r = getfreq();
if (digitalRead(pinLCModeSW)){
//CALC_C
//val_r = CAL_CAP * ( (frq1_r / frq3_r) ^ 2 - 1.0 ) / ( (frq1_r / frq2_r) ^ 2 - 1.0 );
val_r = (frq1_r + frq3_r) / frq3_r;
val_r *= (frq1_r - frq3_r) / frq3_r;
val_r *= frq2_r / (frq1_r + frq2_r) ;
val_r *= frq2_r / (frq1_r - frq2_r) ;
val_r *= CAL_CAP;
}else{
//CALC_L
//val_r = CAL_C * ( (frq1_r / frq3_r) ^ 2 - 1.0 ) * ( (frq1_r / frq2_r) ^ 2 - 1.0 ) / CAL_CAP /( (2 * M_PI frq1_r)^2 );
val_r = (frq1_r + frq3_r) / frq3_r;
val_r *= (frq1_r - frq3_r) / frq3_r;
val_r *= (frq1_r + frq2_r) / frq2_r;
val_r *= (frq1_r - frq2_r) / frq2_r;
val_r /= CAL_CAP;
val_r /= 4 * M_PI * M_PI * frq1_r * frq1_r;
}
#ifdef USE_SERIAL
Serial.println(val_r);
#endif
#ifdef USE_SERIAL
lcd.println(val_r);
#endif
}
}
digitalWrite(pinLed,!digitalRead(pinLed)); // blink Led
}
0 件のコメント:
コメントを投稿