AVR LC Meter With Frequency Measurement

I have been thinking about building an LC meter for a while since I do not have a multimeter that is capable of measuring inductance and while the multimeters I have can measure capacitance, they are not able to give accurate readings for small capacitance in the range of several pF’s.

There are quite a few good articles on how to build LC meters using PIC MCUs (like the ones here: 1, 2, 3), but instructions on how to build one with an ATmega MCU are few and far in between, although the basic principle is largely the same. So I decided to write this article on how to build an LC meter using an ATmega328p chip and Arduino libraries.

A typical LC meter is nothing but a wide range LC oscillator. When measuring an inductor or capacitor, the added inductance or capacitance changes the oscillator’s output frequency. And by calculating this frequency change, we can deduce the inductance or capacitance depending on the measurement.

The following schematic shows the comparator based LC oscillator I used in the LC meter. The oscillator portion is quite standard. Most of the other designs I have seen use LM311 comparator. But for this type of application, any comparator capable of oscillating up to 50kHz should be more than sufficient. I happen to have some spare LM339’s lying around so I used it in the oscillator circuit.

LC Meter - Oscillator

LC Meter - Oscillator

Note, there should be a 3K pull up resistor on pin 1 and the feedback resistor should be 100K instead of 10K.

Because what we are really meausring is the frequency of the oscillator, we can build a frequency meter using the same circuit at almost no additional cost. As you can see in the circuit above, a reed relay is used to switch the measurement from LC mode to frequency mode. In the schematics above, the second comparator forms a Schmitt trigger to condition the input waveform so that the frequency measurement can be made more accurate. When in the LC mode, the frequency output from the first comparator is simply feed through the Schmitt trigger. The output frequency is determined by

\[L=L_0 + L_{measured}\] and
\[C=C_0 + C_{measured}\]

Choosing a high accuracy L0 and C0 helps improve the accuracy of the meter.

Here’s the MCU side of the schematics:

LC Meter

LC Meter

This circuit is capable of measuring inductance in a wide range, from a few nH all the way up to a few Henrys. For capatance measurement, I have found that it is most suitable for measurement from a few pF to tens of nF. You maybe able to measure slightly larger capacitors if they have a high ESR rating. But this range limit in capacitance measurement should not be an issue as what we care most about is the accuracy in the pF range.

I used this frequency library for the frequency measurement. By default, the display is updated every second. This mode provides the most accurate result. You can shorten this update interval easily, but the measurement accuracy will be reduced.

The Arduino code for this project can be downloaded here (LCFrequencyMeter.zip). This project was developed using the NetBeans IDE and you may need to adjust the included header files if you are using Arduino IDE. For more information, please see my previous article on this topic.

The calibration method I used is like this: in capacitance measurement mode, the none-load reading is used to calculate stray inductance (assume that C0 is accurate) which is then used to compensate capacitance measurements. And similarly, in inductance measurement mode, we assume that L0 is accurate and the none-load reading (by shorting the test leads) is used to calculate stray capacitance which is then used to compensate inductance measurements. If you read through the code you will get a better idea on how this is done.

The following picture shows the capacitance reading when using this meter to measure a known 2.22nF capacitor:

Capacitance Measurement

Capacitance Measurement

And this picture shows the LC meter in inductance mode, measuring a small inductor:

Inductance Measurement

Inductance Measurement

Here is a picture showing frequency measurement. The frequency source is a 555 timer generated square wave:

Frequency Measurement

Frequency Measurement

Within a selected mode, the display is auto ranged for the components/frequencies under measurement.

Be Sociable, Share!


  1. pagan says:

    Hi Kwong, what’s the range of Lc meter (anductance), how about the accuracy?

  2. Gab says:

    Hello! Thanks for the quick responds to previous question I asked.
    Pls, I want to understand something. Digital pin 5 (Frequency in) is not declared and used in the program. Can U explain that to me? OR How is it used?

  3. jimis says:

    nice job i fix the cirquit but not working screen is not open what is wrong please help me to fix it ! thank u!

  4. Tom says:

    Is that resistor on the first op amp circuit a 10k or a 1k or what? it’s marked 1\k.

  5. Eadrom says:

    I’ve made a very simillar LC meter. The problem is, that it is very unstable. What I mean is that, when in calibration mode it goes from 432,5 kHz to 437,1 kHz in about 20 minutes!

    The meter is soldered on a breadboard. I’ve used 581pF ceramic capacitor and 221uH inductor, but the “vertical” one, like this: http://static.tme.eu/katalog_pics/a/5/c/a5c773a26a582806508bb46de396949b/coil0.33.jpg

    What can cause the problem?

    • kwong says:

      Good question, as the stability of an opamp LC oscillator should be well within 1% over time (that’s already 10000 ppm). I’d change the reference L/C components and see whether that changed the outcome.

  6. SImas says:

    Now I really DO need help :] I’ve put everything in place, double checked and fired up – but the only thing I can get out of it is “Mode: C / Mode: L” and “—” in second line.

    I have no idea how to start debugging it, finding the cause and making it work. I would be really thankful for an advice.

    A) I’ve ditched all the frequency-measurement-related part (since I only need it for measuring an inductor) – so no relay, no LC/Frequency button and pins 2 and 6 are directly connected on LM339. I don’t think I could have messed anything up here :].
    B) I’ve used 1K for a resistor marked as “1\K” and 100K for this one: http://snag.gy/GwKvY.jpg . Those are the only modifications to the original circuit, everything else is as drawn (double checked).
    C) L/C switch works: it changes modes on LCD successfully.
    D) Calibrate button works – once it’s pressed, “Cal” appears on the LCD briefly.
    E) If I reset the Arduino Uno – I get a brief display of “27.20 nf” or “6.01 mH” briefly, then it goes to “—” and doesn’t change ever, no matter what mode and what I plug into test contacts.
    F) Code wise, I only added FreqCounter library to Arduino IDE, and removed folder names in includes (“FreqCounter/FreqCounter.h”->”FreqCounter.h” and “LiquidCrystal/LiquidCrystal.h”->”LiquidCrystal.h”. That removed all the compiling errors. BTW, where do all the other includes are comming from? Do I also have to get and install them, or they are something left from that NetBeans thing and doesn’t play a role in this code?

    Thanks in advance for your answers/guidance!

    • SImas says:

      Got it solved, found a loose solder joint to pin5 of LM339. But it still doesn’t work as supposed:

      C Mode: displays wildly alternating digits, mostly negative.
      L mode: whatever I plug in – shows “ovf nH”.


      • SImas says:

        I’ve tried just loading an example freqCounter code to see what it reads at pin5. Results are strange and give me no ideas how to progress further :]

        C mode: “90” with nothing plugged / “123” with 100 nf
        L mode: 0 with irregular 1 / ~230 with 33uH inductor

        As I understand it’s far from the digits that should be seen.

        One more thing – I didn’t do anything with “there should be a 3K pull up resistor on pin 1” part. Might it be the reason? Can someone explain how this should look like?

        • kwong says:

          That might have been the issue, as LM339 has open collector output, you will need a pull up resistor at the output for it to work correctly. To isolate the issue, you could also by pass the second IC (e.g. connect the output from pin 2 of LM339 to Arduino pin 5) temporarily to see if it works.

  7. Tom says:

    Can an LM1458 be used in place of the LM339?

  8. Tom says:

    More digging to do. I can finally get a capacitance reading with a capacitor connected. When I hook up and inductor and press the LC sense switch, it give me a frequency. When I press it again, the inductance is briefly displayed before going back to Mode:C. I guess I have more troubleshooting.

  9. Tom says:

    Is the default mode “L” or “C”?

  10. Tony says:

    Hello, I have built your LC meter -which will be very useful -but I have been unable to load the software. I’m using the Arduino IDE and the problem may be that the version I have is 1.0.5 and I can’t get version 0018 (which I believe you used) or it may just be that I don’t know what I’m doing. There seems to be a problem with the libraries not being available.
    I would be grateful for any help!

    • kwong says:

      If you are using the latest IDE, change


      define __AVR_ATmega328P__

      include avr/interrupt.h
      include binary.h
      include HardwareSerial.h
      include pins_arduino.h
      include WConstants.h
      include wiring.h
      include wiring_private.h
      include math.h
      include WProgram.h
      include EEPROM/EEPROM.h
      include LiquidCrystal/LiquidCrystal.h
      include FreqCounter/FreqCounter.h


      include LiquidCrystal.h
      include FreqCounter.h

      (you will need to put in the correct syntax, the editor I am doesn’t like c syntax…
      and it will compile (given you have downloaded the frequency counter library I mentioned in my post). Good luck!

  11. ashad says:

    can we use atmega328 instead of atmega328p?

  12. ashad says:

    Is it necessary to use atmega? can we jst connect the lcd pins as defined in the code?.

  13. ashad says:

    relay specs please…

  14. Mikkel says:

    Hello Kerry
    I have found your design and tried to copy almost everything, but I see no oscillations ;(

    All I want here is to measure the capacitance with the ATmega328p (Arduino Pro).

    I have therefore removed the two switches. I made connections straight through from pin 2 to pin 6, I could properly completely neglect the Schmitt trigger/the second comparator, however didn’t in my first try. I then connected straight through from the input (GND) to GND and from input (High) into the junction where the 1000pF capacitor and the inductor are joined.
    (Something about you had written L on one and C on the other. The fact was just the opposite!?)

    I have corrected your feedback resistor from pin 1 to pin 7 to a 100kOhm resistor in stead of 10kOhm, as well as added a 3kOhm resistor from pin 7 to Vcc.

    Since I wanted another resonance frequency, than yours, I have changed the capacitor in the LC circuit to 470pF rather than 1000pF. Theory says ~488 kHz, as fare as I have found. Which should be below what the LM339 will run (>500kHz).

    The LM339 is powered at pin 3 with Vcc and pin 12 is connected to GND.

    Vcc is 5V.

    I have connected the non-inverting inputs of comparator 3+4 to Vcc and the inverting of comparator 3+4 inputs to zero.

    No ATmega is connected, only 5V LAB power supply and an oscilloscope on output from both pin 1 and pin 2. No square output and what I get is very weak noise oscillations, properly from the overhead lights.

    I can send hand drawings of my design, output from the oscilloscope, and pictures of the circuit. The prototype is done on a PCB stripboard.

    Any ideas?

    I’ll try redo the board tomorrow on a new piece of PCB Stripboard with another layout I have drawn up today. To see if I have been handling something wrong on the first drawing or made bad soldering joints somewhere.

    Your help will be highly appreciated

  15. Mikkel Wahlgreen says:

    After a rebuild of the circuit I am now able to get something from the circuit: ~191 kHz square wave signal on both pin 2 and pin 1. (Jubi)
    On the other hand I have a 222µH inductor and a 477pF capacitor, theory says: ~489 kHz
    If the inductor is correct then the system must have 3160pF capacitance installed???

    Im using a PCB Strip eurocard for the build, does this add that much stray capacitance? :S

  16. OMARY says:

    Sir, I have tried to download the source code (LCFrequencymeter.zip) but UNFORTUNATELY I can’t OPEN IT…
    II BECOMES PLAIN WHITE, I HAVE winRAR software but it doesn’t open.
    the window writes “windows cant open the file, FILE TYPE UNKNOWN”
    help me.

  17. OMARY says:


    I have few important questions right here:


  18. Sleepwalker3 says:

    Why is Pin 20 showing it connected to 3.3V when the Arduino has that connected to 5V VCC? Can it be used with just 5V, or does it need a 3.3V supply as well as 5V?

    The switching arrangement is not clear on the diagrams, the relay appears to be the SPDT contacts that switch from F to LC, though it’s not marked as such. What about the L/C switching, it that just a DPDT switch (I can’t see one in your pictures) or am I missing something?

    @Omary –
    1. I believe the relay switches the SPDT contacts to select F or LC
    2. The oscillator is for the micro’s clock circuit and it’s very likely it’s necessary or they wouldn’t have added it.
    3. The 100nF cap is used as a bypass capacitor, without it the current switching peaks would likely cause noise and momentary supply drops that would upset the operation of the micro. It’s value is not critical, but 100nF is a commonly used value. Ideally use a low inductance Monolythic ceramic cap, also known as a Monoblock. If you are using an Arduino board, this cap would already be fitted (and likely a few more around the board too).
    4. The switches are just common pushbuttons, typically small tactile pushbuttons are used and they are readily available from electronics suppliers worldwide or ebay.
    I think you’ll have to sort your own list, but nothing in this circuit is fancy, it’s all just normal commonly used components.

  19. Sleepwalker3 says:

    Thanks Kerry for the clarification with the voltages. I could see the DPDT switch, but was just a bit unsure, as the switch and the relay looked identical (other than being DPDT Vs. SPDT), but it’s clearer now thanks.

  20. LAS says:

    Thanks a lot for this awesome project….
    I have been working on this and have implemented the circuit using a bread board and arduino UNO. I added additional libraries,
    #include as u have mentioned above. And the code have been successfully uploaded to the arduinoUNO with no compilation errors.And all the switches(with relay), LCD, modes are working correctly. But my problem is it seems like the oscillator is not working. Even after the calibration it shows changing minus(-) values in both L and C modes. And they speedily change in a huge range. In the frequency mode it shows a frequency value of 50 Hz all the time. Still I can’t figure it out how does that 50Hz default value come from.
    I know this question is quite familiar to you because i have been through most of the comments above:).

    Your help is highly appreciated :)
    PS: I have used LM339N instead of LM339P… Is this the reason? Other components are exactly same as you have metioned.

    Thank you,

    • LAS says:

      In my previous comment newly added libraries have not appeared correctly.
      #include EEPROM.h
      #include LiquidCrystal.h
      #include FreqCounter.h

    • kwong says:

      It’s hard to tell… the oscillator portion is pretty simple, and if you hooked it up correctly it should oscillate with a wide range of LC values. The 50 Hz you is most definitely from the mains.

      To isolate the problem, I would suggest testing the output from pin 2 of the OpAmp (see the first schematic). If you have an oscilloscope that would be ideal as you could observe the output waveform. But even without an oscilloscope, you should be able to tell whether the circuit is oscillating properly or not via a decoupling capacitor and a multimeter in AC voltage mode.

      • LAS says:

        Thank you for the reply :). Comparator was the problem. So I had to change the IC.Now it is almost working with ArduinoUNO. I have got 234.27 uH and 1.26 nF readings when 220uF inductor and a 1pF capacitor were connected to the measuring probes. You can see the tolerance there:).Furthermore i am still working on finding a way to reduce the tolerance of the instrument.I’ll let you know when i finished the complete equipment :)

        Thank you.
        Cheers :)

  21. Hans says:


    stupid question: what is the relay doing? How is it triggered?
    I tried to understand the circuit and the explanation of Sleepwalker3, but failed.
    Could you explain and maybe give details on specs?
    Thanks alot!

    • Sleepwalker3 says:

      @Hans – I believe it’s working like this… (please correct me if I’m wrong, I only had a quick skim of the code)
      When you press the LC/Freq button it’s toggling the dispfreq variable which then determines if the relay output should go high or low. That turns the transistor on or off and so turns the relay on or off. From what I understand, the relay’s contacts are the ‘switch’ between the two comparators, which selects Frequency or L/C measurement. So by pushing the LC/Freq button, you are effectively switching between Frequency and L/C. That variable within the code also determines if the LCD will display the Freq. From there the actual freq seems to determine whether it’s displaying Hz or kHz (the code says KHz, but it should read kHz with a lower case k).

      The relay type shouldn’t matter too much, but you’d be best with a small signal relay (or Reed Relay), preferably with gold contacts (not essential), as they will be more reliable for small signals, but most small relays will do, providing they are Change-Over (C/O) contacts (also known as SPDT) and providing the coil is a suitable voltage, e.g. 5V. The transistor could be anything with a suitable current rating for the relay. Some that would likely be suitable in most cases would be BC639, 2N2222, etc.

      The code for the backlight seems to work in a similar fashion, just toggling to the opposite state when the backlight button is pressed.

      I hope that explanation helps.

      Now maybe somebody can help me? Has anybody got the code in Hex file or Bin file form? I don’t use Arduino, but I have access to professional device programmers, so it’s much easier for me to quickly load it with a Hex or Bin file than wasting time setting up a bloated Arduino IDE that I’ll hardly use, loading up the Bootloader first, etc. etc.

  22. Wunderbred says:


    In the LC Meter Oscillator, the inductor is a 221uH but I only have a 220uH is this alright or should I add a 1uH inductor in series to bring it to a 221uH inductor?

    • kwong says:

      For the reference inductor and capacitor you can pretty much use any value, you just need to update the code to reflect the value you used:
      const float Cth = 1000 * 1e-12; //theoretical 1000pF
      const float Lth = 221 * 1e-6; //theoretical 221uH

  23. Amogh says:

    Whats the max frequency it can measure ??

  24. john says:

    Hello. I would like to ask you something about frequency measurement. I need to measure frequency in my power circuit which generates ac square waves. The voltage of this circuit is 30V. I can measure it by my multimeter, but is it possible to measure it with your meter. Than you for your answer.

    • kwong says:

      You can always use an attenuator (e.g. voltage divider in this case) to keep the input voltage under 5V and the voltage is level shifted to be above ground (i.e. add a DC offset to your input signal) then you can use this circuit to measure frequencies up to 8 MHz.

  25. nishu says:

    can i get the source code of this project??

    • OMARY says:



  26. Leo says:


    if I want to build a meter using to measure capacitance only, how can I simplify the circuit?

    At the beginning, I should connect the measured capacitor to be ground in both sides. Or do I get wrong?
    Because I see there is a gnd before the inductor. So the pin (L) and GND are both grounded.


  27. Adam says:

    Hi Kenny,
    I’m working with measuring LC circuits for coils in the range of 10 to 200uH @ 40khz. Its my understand that the frequency is pretty important to determine the best impedance matching for my circuit. How does this relate to this circuit is there a way of selecting frequencies? What about using a higher voltage to simulate what is coming out of the Class D PWM I am using also?

  28. Adam says:

    Hi Kerry,
    I’m working with measuring LC circuits for coils in the range of 10 to 200uH @ 40khz. Its my understand that the frequency is pretty important to determine the best impedance matching for my circuit. How does this relate to this circuit is there a way of selecting frequencies? What about using a higher voltage to simulate what is coming out of the Class D PWM I am using also?

    • kwong says:

      The frequency of this simple circuit is determined by the reference L/C and the DUT. If your goal is to measure ESR and other characteristics that depend on frequency you will have to take a different approach.

  29. Soligen says:

    Thank you for posting this circuit. I have a question about the calibration source code. I see you set the frequency FO to the frequency read during calibration, but you also change the L0 and C0. It seems that if you calibrate twice then the L0 and C0 will end up being the same as Lth and Cth. The first calibration may change then because F0 changes, but a second calibration seems like it would set them back to Lth and Cth (Assuming the read frequency during calibration stays the same) because the calcV function will return zero if the frequency is the dame as F0. Am I missing something here? Can you plese explain the thought process behind changing L0 and C0? Thanks.

    • kwong says:

      Thanks for your comment. So the assumption here is that the frequency counted by the MCU is accurate. This is a reasonable assumption since it is using a crystal oscillator.

      The calibration is done in either “L” mode or “C” mode. In “L” mode, we assume that the capacitor value is accurate and by shorting out the leads, the deviation from the theoretical inductance (e.g. the lead inductance or inaccuracy in our reference inductor) would cause the frequency to deviate from the calculated frequency. So to zero this out, we would add the stray inductance to the original value (so the display would show zero).

      In “C” mode, the assumption is that L is accurate so similar calculation is done to compensate the stray capacitance.

      • Soligen says:

        Thanks for responding. I think I understand, but I don’t think you code accomplishes this. Lets look at the inductance example in the calibration:
        l0 = calcV(frq, Lth) + Lth;
        F0 = frq;
        Since calcV used F0, which is initially set to a constant (that later gets over ridden) and does not use Cth. Assuming that initial F0 constant is the theoretical value, then the first calibration will adjust the offset accordingly, but the second calibration will likely undo this. I think you should reset F0 to the theoretical frequency before doing this, or you calculate L0 from frq and Cth instead of using calcV.

        BTW the initial F0 is not the theoretical value. It is initialized to 348000, but I think the theoretical is 338551

        I would assume you want F0 initialized to an initial calibration constant (not the theoretical), so then I would define a new variable Fth to permanently hold the theoretical frequency
        const float Fth = 1.0/(2.0*3.14159/(sqrt(Lth*Cth))
        then set F0 to Fth just before calling calcV in the calibration process

        Perhaps I’m missing something. I have been developing software for over 30 years, but I am new to electronics. Does what I say make sense?

  30. Omer says:

    How will i calculate the range of an LC meter.

    • kwong says:

      The range is largely determined by the maximum achievable oscillation frequency range, which in this case is at around 500 to 800 kHz. So given your reference L/C value, you can derive the value you can measure with this meter.

Leave a Reply