Status

  • not done - I'm fine tuning and documenting

Introduction

This is my attempt at building an accurate L/C meter. This design is based on other designs found on the internet. It was just my luck that the other designs didn't work as expected. By that I mean: I have my own PICs on hand, I wanted other features, I fine tuned the LM311 oscillator.

This project is for my ham bench.

The features are as follows:
- Measure inductance and capacitance.
- Auto ranging.
- Auto measure L or C.

The Schematic

Below is the schematic for the meter. The image has been sized to fit the browser window. Right click to save or view the full size image.

The Parts List

Here's the list of parts you get to spend money on.

C1capacitor - 68uf 25V elec
C2,C3capacitor - 10uf 25V tantalum
C4capacitor - 750pf 1% 100V mica
C5capacitor - 1100pf 1% 100V mica
C7,C10capacitor - 0.01uf 100V ceramic disc
C8,C9capacitor - 47pf 50V ceramic disc
C12capacitor - 10uf 16V elec
D1,D2,D4diode - IN4001
D3LED4 - red
J116x1 LCD display
J2connector - 2 position for test points
J32 position connection for 9-12VDC in
k1relay - reed 5VDC 20ma coil
K2,K3relay - DPST 5VDC coil
L1inductor - 82uh high Q
Q1transistor - 2N3904 or 2N222
R1resistor - 10K ohms 5% 1/4 watt
R2resistor - 9.2K ohms 5% 1/4 watt
R4resistor - 1k ohms 5% 1/4 watt
R3,R5resistor - 47K ohms 5% 1/4 watt
R6,R7resistor - 6.5K ohms 5% 1/4 watt
R9potentiometer - 10K ohms
U1IC - PIC16F628 microcontroller
U?IC - LM311
VREGvoltage regulator - LM7805 3 terminal 5V
X1crystal - 4Mhz clock

The Main Players

The circuit is composed of 3 functions.

Power Supply

The power supply uses a LM7805 voltage regulator. Nothing more than the standard textbook design.

The Brains

A PIC16F628 is the brains of the circuit. It handles all the calculations and displaying the results

LC Oscillator

The LC oscillator is based on a LM311. And I bet you're saying that there is a mistake in the schematic. There isn't. The oscillator can be improved by feeding the output of the LM311 back to the L/C tank.

The Software

The software was written in basic. I don't use floating point math. This is a great example showing how to use integers to do floating point math. This program is far from done.

Here is the hex file for the program below. The file will download as a text file. Just change the .txt extension to .hex and you're good to go.
Attach:lcMeter.txt

 
'*****
'*          PROJECT:  CAMP L/C Meter
'* SOFTWARE VERSION:  0.7
'*       TARGET PIC:  PIC16F628
'*       TARGET PCB:  ?
'*          CREATED:  
'*     LAST UPDATED:  
'*       WRITTEN BY:  Richard Camp
'*
'* OVERVIEW
'* --------
'*
'* INPUTS/OUTPUTS
'* --------------
' A0 OUT -
' A1 OUT -
' A2 OUT - LCD enable
' A3 OUT - LCD reg select
' A4 OUT -
' A5 INP -
' A6 XTAL OSC
' A7 XTAL OSC
'
' B0 OUT - LCD data 0
' B1 OUT - LCD data 1
' B2 OUT - LCD data 2 
' B3 OUT - LCD data 3
' B4 OUT - cal cap relay
' B5 OUT - mode select relay
' B6 IN - freq count
' B7 OUT - 

' DEVICE PROGRAMMING OPTIONS
' --------------------------
@ DEVICE pic16F628, XT_OSC
@ DEVICE pic16F628, WDT_ON
@ DEVICE pic16F628, PWRT_ON
@ DEVICE pic16F628, BOD_ON
@ DEVICE pic16F628, MCLR_OFF
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, CPD_OFF
@ DEVICE pic16F628, PROTECT_OFF

' picbasic defines
' ================
DEFINE LCD_DREG PORTB     ' LCD RA to LCD data port
DEFINE LCD_DBIT 0         ' Starting data bit on b0 & last on b3
DEFINE LCD_BITS 4         ' Set 4-bit data bus width
DEFINE LCD_RSREG PORTA    ' Set LCD register select port to A
DEFINE LCD_RSBIT 3        ' Set A3 to register select pin
DEFINE LCD_EREG PORTA     ' Set LCD enable to port A
DEFINE LCD_EBIT 2         ' Set A2 to LCD enable pin
DEFINE LCD_LINES 1        ' LCD is a 1 line display
DEFINE LCD_COMMANDUS 2000 ' Set LCD command delay time in uS
DEFINE LCD_DATAUS 100     ' Set LCD data delay time in uS


' HARDWARE ASSIGNMENTS
' --------------------
freqin      var portb.6   ' input - freq in
calRelay    var portb.4   ' relay pin for calibration 0=calibrate
modeRelay   var portb.5   ' relay pin mode select
                          ' 0=measure cap
                          ' 1=measure ind

' RAM ASSIGNMENTS AND VARIABLES
' -----------------------------
tmpvar      var word  ' temp storage
tmpvar2     var word  ' temp storage
units       var byte  ' units to display
freq1       var word  ' F1 frequency
freq2       var word  ' F2 frequency
fratio      var word  ' F1/F2 ratio
FRdecMv     var byte  ' num of dec places to move fratio
                      ' ex:
                      ' fratio=1.032
                      ' prdecmove=1
                      ' fratio=10.32 recalculated
valmult     var word  ' (fratio -1)
fcount      var word  ' raw count from osc
ovf         var bit   ' overflow flag for fcount
OscC1       var word  ' C of osc in pf
OscL1       var word  ' L of osc in uH
meterMode   var bit   ' 0=measure capacitance 
                      ' 1=measure inductance
decmult     var word  ' number of digs after dec point
                      ' ex: 10, 100, 1000, 10000
LCval       var word  ' L or C value
LCvalR      var word  ' remainder of L or C value

' PROGRAM CONSTANTS
' -----------------
ctime     con 100     ' fcount sample time in ms
rtime     con 3000    ' relay and osc settling time ms
Ccal      con 1100    ' 1.1 nf
Ccap      con 750     ' 750pf
Cind      con 82      ' 82uh calibration inductor

' -------------
' PROGRAM START
' -------------

' START OF PROGRAM INITIALIZATION
' ===============================
  Disable
progstart:
  ' initialize hardware
  CMCON=%00000111			'disable comparators
  TRISA=%00101111			'setup port A
  TRISB=%11110000			'setup port B
  OPTION_REG.7 = 0		'enable port b pullups
  VRCON.7 = 0
  VRCON.6 = 0
  RCSTA.7 = 0
  Pause 1000 		      'timeout to let the hardware settle
  high calrelay       'turn the cal relay off
  low moderelay       'turn off the relay

  ' setup lcd and display title
  LCDOUT $FE,1,$FE,$0C,$FE,2,"CAMP L/C Meter V0.7b"
  pause 4000

  ' set program vars
  metermode=0          ' set meter mode to measure capactance
  OscL1=cind           ' set to default value
  OscC1=ccap           ' set to default value

  'calibrate the device
  gosub calibrate
  OscL1=cind           ' set to default value
  OscC1=ccap           ' set to default value

' START OF MAIN PROGRAM LOOP
' ==========================
mainloop:
  'measure the freq and store in F2
  gosub readfreq                  ' load fcount with Osc frequency
  freq2=fcount                    ' store fcount in F2

  ' Do range checking and mode switching
  if (freq2>(freq1+75) or ovf=1 or freq2<30) and meterMode=1 then
    metermode=0                   ' set mode to measure cap
    low moderelay                 ' turn off mode relay
    pause rtime                   ' pause to let things settle
    goto mainloop
  endif
  if (freq2>(freq1+75) or ovf=1) and meterMode=0 then
    meterMode=1                   ' set mode to measure inductance
    high moderelay                ' turn on mode relay
    pause rtime                   ' pause to let things settle
    goto mainloop
  endif

  ' Do the calculations
  ' There is no floating point here
  ' 
  '         F1^2
  '  Cx= [-------  -1]*Cref
  '         F2^2
  '
  '         F1^2
  '  Lx= [-------  -1]*Lref
  '        F2^2
  '
  ' Auto scaling is also done.  This provides the best 
  ' accuracy for the part we are measuring.
  '
  decmult=1                 ' set the mult to 1
scalecalc:  
  gosub freqratio           ' calc F1/F2
  gosub valuemult           ' get the num to mult L or C by
                            ' fratio^2-1

  ' the section below checks to see if we have a large
  ' enough integer.  If the answer is below what we are
  ' looking for then change the multiplication factor and
  ' redue the calcs.
  if valmult<=1000 and decmult<10000 then
    decmult=decmult*10
    goto scalecalc
  endif

  gosub calcLc             ' calc Lx or Cx

  ' this section displays the result
  lcdout $fe,1,$fe,$c0,$fe,2,"Auto "
  if metermode = 0 then
    lcdout "C"
  else
    lcdout "L"
  endif 
  lcdout "=",#LCval,".",#LCvalr
  if metermode = 0 then
    select case units
      case 1
        lcdout "pF"
      case 2
        lcdout "nF"
      case 3
        LCDout "uF"
    end select
  else
    select case units
      case 1
        lcdout "uH"
      case 2
        lcdout "mH"
      case 3
        LCDout "H"
    end select    
  endif

  pause 200                     ' pause between readings
	GoTo mainloop                 ' repeat the main loop forever
' END MAIN PROGRAM LOOP
' =====================

' read freq on a pin
' use hardware timer1 to count the pulses from the 
' LM311.  
readfreq:
  fcount=0              ' zero fcount
  ovf=0                 ' clear the overflow flag var
  t1con = 7             'set timer 1 on, external clock, non sync = bit0 =1, bit1 =1, bit2 =1
  tmr1h = 0             'clear timer 1 high byte
  tmr1l = 0             'clear timer 1 low byte
  pir1 = 0              'clear overflow flag
  pause ctime           'wait for the sample period
  t1con = 0             'stop timer 1 , bit0 =0
  fcount.byte0 = tmr1l  'get the timer low byte
  fcount.byte1 = tmr1h  'get the timer high byte
  ovf = pir1            'get the overflow flag
  fcount=fcount/2       'divide fcount by 2
Return

' calibration routine
' we need to know the actual L1 and C1 values
' calibration is done using a high accuracy calibration
' capacitor
calibrate:
  lcdout $fe,1,$fe,$c0,$fe,2,"Calibrating"
  decmult=10000       'set the dec multiplier to 10000

  ' get F1 then enable cal cap and get F2
  pause rtime         'pause to let the osc settle
  gosub readfreq      'get the osc freq
  freq1=fcount        'store in F1
  low calrelay        'turn on the calibration relay
  pause rtime         'pause to let the osc settle
  gosub readfreq      'get the osc freq
  freq2=fcount        'store in F2
  high calrelay       'turn off the calibration relay
  'lcdout $fe,1,$fe,$c0,$fe,2,"F1=",#freq1," F2=",#freq2
  'pause 3000

  ' calculate C1
  '         F2^2                    F2^2
  ' C1 = ----------- * Ccal = ----------------- * Ccal
  '       F1^2-F2^2            (F1+F2)*(F1-F2)
  tmpvar=freq1*freq1      ' square F1
  tmpvar=div32 10000
  tmpvar2=freq2*freq2     ' square F2
  tmpvar2=div32 10000
  tmpvar=tmpvar-tmpvar2   ' F1^2-F2^2
  tmpvar2=tmpvar2*1000
  tmpvar2=div32 tmpvar
  tmpvar=tmpvar2*Ccal
  OscC1=div32 1000

  ' Calculate L1
  '           1
  ' L1 = -----------------
  '       39478*F1^2*C1^2
  tmpvar=freq1*freq1
  tmpvar=div32 1000
  tmpvar2=OscC1*OscC1
  tmpvar2=div32 1000
  tmpvar2=tmpvar2*39478
  tmpvar2=div32 1000
  tmpvar=tmpvar2*tmpvar
  tmpvar=div32 1000
  tmpvar2=1000*1000
  tmpvar2=div32 tmpvar

  lcdout $fe,1,$fe,$c0,$fe,2,"Cal C1=",#OscC1,"pF"  
  pause 5000
  lcdout $fe,1,$fe,$c0,$fe,2,"Cal L1=",#tmpvar2,"uH"  
  pause 5000
  return

' calc F1/F2  
freqratio:
  tmpvar=freq1*decmult
  fratio=div32 freq2
  return

' calc fratio^2-1  
valuemult:
  tmpvar=fratio*fratio
  valmult=div32 decmult
  valmult=valmult-decmult
  return

' calc L or C
' load tmpvar2 with L1 or C1 value
' tmpvar2 returns unit scaling for display
' 1 = pf or uh
' 2 = nf or mh
' 3 = uf or h
calcLC:
  if metermode = 0 then
    tmpvar2=OscC1
  else
    tmpvar2=OscL1
  endif
  units=1
rescale:
  tmpvar=valmult*tmpvar2
  LCval=div32 decmult
  LCvalR=R2
  if LCval>50000 then
    tmpvar2=tmpvar2/10
    decmult=decmult*100
    units=3
    goto rescale
  endif
  if LCval>1000 then
    tmpvar=LCval*1
    LCval=div32 1000
    LCvalR=R2
    units=2
  endif
  tmpvar=lcvalr*100
  lcvalr=div32 100
  return

' END OF PROGRAM
' ==============         

The Theory

(the last part to be done)

Conclusion

Enjoy. Below is a photo of my version.

Comments

Add Comment 
Sign as Author 
Enter code 593

babsabtabkazzxvc3f?21 March 2016, 08:37

babsabtabkapvbdrgsdg?05 February 2016, 23:39

25 February 2014, 09:55

Not work!!

maroton?29 December 2013, 05:37

NOT work

maroton?17 December 2013, 10:42

done it? send me at maroat@inwind.it for software work fine. Tank you.

Airton?11 November 2011, 09:31

Congratulates the project Inductance and Capacitance L / C Meter Based on The PIC Micro PIC16F628, did the same and was very good as inducers, but the capacitance indicates less than half the value out, what could be wrong? agradesso much if you can help, have a nice day ..

Hernán?14 June 2011, 09:09

HI rcamp, in equation for calculating calibrating inductor L1, OscC1 shuldn't be squared F= 1/ [2pi (L1.OscC1)^1/2]

pete?10 June 2011, 12:40

hi there...does thhis project fully works...

MANUEL?27 May 2010, 09:23

From Manuel 27-5-10 In SPAIN

Hi RICHARD I have seen your LC-METER program writing basic and It’s very good. In what basic Did you write in. I have Modified your program to PROTON PIC BASIC.everything is fine but when I get to compile I get an error R2 ????? WHAT IS IT ????? A VAR A CON ????. THE REST OF THE PROGRAM IS OK. please send me this information so that I can build this LC Meter… SEE part of the listing IF YOU SEND ME YOUR EMAIL I WILL SEND YOU A COPY OF THE UNIT I MADE MY EMAIL IS MCDCAR@YAHOO.ES THANK YOU

 LCvalR=R2  ???????
  if LCval>50000 then
    tmpvar2=tmpvar2/10
    decmult=decmult*100
    units=3
    goto rescale
  endif
  if LCval>1000 then
    tmpvar=LCval*1
    LCval=div32 1000
    LCvalR=R2  ??????

??11 January 2010, 21:35

16f628 have internal comparators use it and sure u don't need lm211.

Lam?02 October 2009, 17:40
 Please help me to know 16F628A will work

with your hex (16F628).Many thank you for your time and your site.

     Best regards

rcamp?06 June 2009, 21:37

parts list added

Pedro?11 May 2009, 19:18

Please send part list for casacomponentes@hotmail.com

guest?24 November 2008, 07:04

Nikolai4?11 November 2008, 10:35

Опишите пожалуйста все номиналы резисторов конденсаторов и т.д.

livo?31 October 2008, 06:03

Where is the parts list? liviogiannelli@yahoo.it

mfisch?18 June 2008, 17:18

What is the max range for L and C measurments?

rcamp?07 April 2008, 09:53

I've added the hex file for those who don't have pic basic.

preda?05 April 2008, 09:29

Hello I'm want to build project L/C meter please help me share hexcode for 16f628 in work your project i'm cannot convert to hex thank you very much Regards preda preda_panapan@yahoo.co.th

jjose?02 April 2008, 16:48

hi Richard

I liked the program. could you pls inform the resistors/capacitors values ?

thanks

Dexter Dude?31 March 2008, 22:29

Please , more detalis ( part list , maybe updated code ).I really need this device .Thanks ! Ps: I want to use an LCD from Nokia 3310 with this .

H Davies?24 March 2008, 08:35

I find this interesting.Where is the parts list?


Custom Search