nobcha a
Published © CERN-OHL2

The Franclin oscillator LC meter

A good material for being familiar with Arduino and peripheral. And you can use this practcally.

AdvancedProtip4 hours469
The Franclin oscillator LC meter

Things used in this project

Story

Read more

Custom parts and enclosures

BOM

Schematics

Franclin oscilltor LC meter

KiCAD

Code

Franclin oscilltor LC meter

Arduino
// 
// updated 2023.03.23
// Arduino LC meter V2.42
//
//   D5:FRQ input, D6:Driving the relay, D7:L/C select PINMODE setting
//   
// Thanks for Teensy-based project to refer FreqCount Library.
// https://www.pjrc.com/teensy/td_libs_FreqCount.html
#include <FreqCount.h>
#include <Wire.h>

// i2c lcd instance
//  Thanks for giving information about i2c LCD adapter
//  https://github.com/marcoschwartz/LiquidCrystal_I2C
#include <LiquidCrystal_I2C.h>

int PIN_Led = 13;        // Gate timing LED lit port
boolean LED_Stat = 1;    // Gate ON/OFF timing LED
int SEL_SW = 7;          // L/C select SW
boolean SEL_SW_Stat = 1; 
int CAL_ON = 6;          // Caliblation relay
int ON = 1;
int OFF = 0;
int f3_SW = 8;           // f3 display select SW
// initialize Serial, i2cLCD,  PCF8574
  LiquidCrystal_I2C lcdi2c(0x27,16,2);     // Adress*0x27, 16 columns, 2 lines



volatile unsigned long freq_d;
volatile unsigned long freq;
volatile boolean err;
char charbuf[16];                     // Character array for sprintf function

char unitbuf[] = {"pF  "};; 
char set_msg[14];
char set_C[] = {" SetCapacitor"};
char set_L[] = {" Set Inductor"};

volatile unsigned char i, l_power,  l_digi,  l_unit,  c_power,  c_digi, c_unit;
volatile unsigned long  freq1, freq2, freq3; 
volatile float  c_int, l_int, l_inv, f_sq;
volatile float  c_cal=1.000e+3;
volatile float  test_value;


volatile unsigned long freq_count()     // Get average from double counting
{
  delay(800);                           // Wait settling v2.41
  FreqCount.begin(200);                 // Start counting with gatetime of 200ms
  while (FreqCount.available() == 0);   // wait until counter ready
  freq_d = 5*FreqCount.read();            // read result of 200mS window
  Serial.println(freq_d);               //  2023.02.26 print freq_d@1000ms
  if(freq_d<2000) err=1;                //  ?? too low, less than 2kHz
  return freq_d;                        // 
}


float freq_cal(unsigned long f1, unsigned long f2){
                                      //  Coefficient calculating
  return((float)(f1)/(float)(f2)*(float)(f1)/(float)(f2)-1);
}

void LCDSetCursor( int column, int line )
{
  lcdi2c.setCursor( column, line ) ;  
} 

void LCDPuts( char *const s )
{
  lcdi2c.print( s ) ; 
}

void setup() {
  Serial.begin(9600);         // connect to the serial port
  Serial.println("LCM on i2cLCD v2.42"); // Version 2.0
  pinMode(PIN_Led, OUTPUT);
  pinMode(SEL_SW, INPUT);
  pinMode(CAL_ON, OUTPUT);
  
  pinMode( 2, OUTPUT);        // To stabilize
  pinMode( 3, OUTPUT);
  pinMode( 4, OUTPUT);
  pinMode( f3_SW, INPUT_PULLUP);
  digitalWrite( 2, 0);
  digitalWrite( 3, 0);
  digitalWrite( 4, 0);  
  
// PCF8574 LCD
// Iniatilize i2c LCD
  lcdi2c.init(); 
  lcdi2c.backlight();
   
  delay(100);

// Write
  LCDSetCursor(0,0) ;                // Starting point [00H]
  LCDPuts("LCM METER v2.42") ;       // 
  LCDSetCursor(0,1) ;                // 2nd line [40H]
  LCDPuts("Let calibrate  ") ;       // 

}

void  loop() 
{
//  START  SWITCH  CHECK
//  If  calibration
  Serial.println("WAIT SEL SW ON");
  while( digitalRead(SEL_SW) == 0 ){ } //  CAL  switch  check
  delay(20);
  while( digitalRead(SEL_SW) == 0 ){ } //  Check  again
  delay(200);
  /*  Get  frequency  1  and  display */
  Serial.println("SEL SW ON");
  freq1=freq_count();             //  F1  get  
//                                result is based on 1000ms gate 
  Serial.println("F1 gotten");
  Serial.println(freq1);
  LCDSetCursor(3,0) ;             // Display position set on 4th column
  LCDPuts(" f1=");    
  sprintf( charbuf,"%ld", freq1, 7);
  LCDPuts(charbuf);
  LCDPuts("Hz   ");  //
// Relay on f2 getting
  digitalWrite( CAL_ON, ON);      //  Calibration  capasitor  on
  delay(200);                     //  Wait 200ms
  freq2=freq_count();             //  Get  F2 
  digitalWrite( CAL_ON, OFF);     //  Calibration  capasitor off
    Serial.println("F2 gotten");
    Serial.println(freq2);
 /*  F2  displaying */
    LCDSetCursor(0,1);            // Move cursur to the top of 2nd line
    LCDPuts("f2=");    
    sprintf( charbuf,"%ld", freq2, 7);
    LCDPuts(charbuf);
    LCDPuts("Hz    ");            //
    delay(50);
/*  Calculating  C  and  L  */
  c_int=(float)(c_cal)/freq_cal(freq1,freq2);
                                   // Calcurate c_int from F and F2 pF
  f_sq=(float)(freq1)*(float)(freq1)/+1.000E+2;
                                   // (F1*F1)
    Serial.println("freq_cal= ");
    Serial.println(freq_cal(freq1,freq2));
  l_inv=(+3.9438E+1)*f_sq*c_int;   // 
  l_int=(+1.000E+16)/l_inv;        // uH
/*  for  debugging  */
      Serial.println("C/L unit gotten");
      Serial.println("C=");
      Serial.println(c_int);
      Serial.println("L=");
      Serial.println(l_int);
      LCDSetCursor(0,1);           // Move cursur to the top of 2nd line
      LCDPuts("C=");    
      sprintf( charbuf,"%d", (int)c_int);
      LCDPuts(charbuf);
      LCDPuts("pF ");              //
      LCDPuts("L=");  
      sprintf( charbuf,"%d", (int)l_int);
      LCDPuts(charbuf);
      LCDPuts("uH   ");            //
// Calibration finished
      Serial.println("Calibration end ");
      LCDSetCursor(3,0) ;          // Move cursur to the 4th of 1st line
      LCDPuts(" Calibrated   ");      
      delay(1000);
// Measurement starting check
    while( digitalRead(SEL_SW) == 1 ){  }  //  Wait sw status changed
  while (1)        // Testing forever
  {    
    digitalWrite(PIN_Led, LED_Stat=!LED_Stat);   //  LED  on/off 
    delay(100);
    
    LCDSetCursor(4,0);         //  Move cursur to the 4th of 1st line

    if(digitalRead(SEL_SW) == 0)  // If SW==0, Ask L measuring 
    {                             // L position 
      LCDPuts( "Set Inductor");   // Set inductor
    }
    else{                         // C position 
      LCDPuts( "SetCapacitor" );  //  Ask setting  C
    }
    delay(300);
    
    freq3=freq_count();        //  Get  F3

    Serial.println("F3 gotten");
    Serial.println(freq3);
    LCDSetCursor(3,0);         // Move cursur to the top of 2nd  line
    if ( digitalRead(f3_SW) == 1)
    {                          // f3_SW on  
      LCDPuts(" f3=");    
      sprintf( charbuf,"%ld", freq3, 7);
      LCDPuts(charbuf);
      LCDPuts("Hz      ");     //
    }
    else
    {
      LCDPuts("              ");
    }
    delay(100);
  /*  displaying  value */
    LCDSetCursor(0,1);         //  Move  cursur  to  the  top  of 2nd  line

      l_power=1;
      l_digi=1;
      l_unit='u';
      c_power=1;
      c_digi=0;
      c_unit='p';  
/*  Calculating value whether C position or L */
    if(digitalRead(SEL_SW) == 0)   // If SW==0, start L measuring 
    {                              // L position
      if ( freq3> 1000 ){
        test_value= ((freq_cal(freq1,freq3))*l_int);
        int f_rate =  (freq_cal(freq1,freq3)*1000);
        Serial.println("f_rate");
        Serial.println(f_rate);

// test_value unit is uH, if test_value < 1, nH used        
        unitbuf[1] = 0x48 ;        // H
        if ( test_value < 1 ){
          unitbuf[0] = 0x6E ;      // nH
          test_value = test_value * 1000 ;
        }
        else if ( test_value < 1000 ){
          unitbuf[0] = 0x75 ;      // uH 
        }
        else {
          unitbuf[0] = 0x6D ;      // mH
          test_value = test_value / 1000;
        }
        LCDPuts("L=");
        dtostrf( test_value, 4, 1, charbuf);    // Changed to use dtostrf(**)
        LCDPuts( charbuf );
        LCDPuts( unitbuf );
        LCDPuts( "        ");   

        Serial.println("L=");
        Serial.println( test_value);
        Serial.println("uH");  
      }
      else {
        LCDPuts(" No inductor    ") ;
        Serial.println( " No inductor    ");          
      }
    }
    else
    {
      test_value=((freq_cal(freq1,freq3))*c_int/c_power);
      Serial.println("C=");
      Serial.println( test_value);
      Serial.println("pF");

      unitbuf[1] = 0x46 ;    // F
      if ( test_value < 1000 ){
        unitbuf[0] = 0x70 ;  // pF
      }
      else if ( test_value < 1000000 ){
        unitbuf[0] = 0x6E ;  // nF
        test_value = test_value / 1000 ;
      }
      else {
        unitbuf[0] = 0x75 ;  // uF
        test_value = test_value / 1000000 ;
      }
      LCDPuts("C=");
      dtostrf( test_value, 4, 1, charbuf);    // Changed to use dtostrf(**)
      LCDPuts( charbuf );
      LCDPuts( unitbuf );
      LCDPuts( "        ");
    }
    delay (500);
  }
}

Credits

nobcha a
10 projects • 5 followers
I'm interested in designing a radio with Si4732 and Si5351a.

Comments