Inductance Meter Design Using LC Oscillator:

Hello everyone,

I am designing an inductance meter using the LC oscillator concept. The circuit uses an Arduino Uno to measure the pulse duration output from a comparator connected to the LC circuit. The measured frequency is then used to calculate the inductance.

I have two key questions:

  1. Input Pulse Parameters:
    I use a digital pulse to excite the oscillations in the LC circuit. Initially, I chose the duty cycle and frequency such that the pulse allows the LC circuit to fully discharge (pulse = LOW) before starting a new oscillation (pulse = HIGH). However, the results were inaccurate. When I used the pulse duration specified in this reference:
digitalWrite(3, HIGH);
delay(5);
digitalWrite(3, LOW);
delayMicroseconds(100);

the results improved significantly. Could someone explain why this specific pulse duration yields better results? What should be the criteria for choosing the input pulse parameters (duty cycle and frequency)?


2. ADC Sampling Rate Issue:
The Arduino Uno's ADC sampling rate is about 10,000 samples per second, but the shortest pulse duration I need to measure is approximately 41.24 microseconds (4.12425E-05 s). While it does not give me an exact value, the accuracy is good enough for my application. How can the Arduino measure such a short duration without undersampling, or do I misunderstand the process?

pulse = pulseIn(8, HIGH, 5000);

Any insights or suggestions would be greatly appreciated!

Thank you!

can you pos5t a schematic please?

Here is my schematic diagram:

The comparator lacks a part number.

My math isnt good enough to work out exactly what will happen - an interesting experiment.
It looks as if you are following this circuit

Thanks, but i still did not get my questions answered:
Input Pulse Parameters:
I use a digital pulse to excite the oscillations in the LC circuit. Initially, I chose the duty cycle and frequency such that the pulse allows the LC circuit to fully discharge (pulse = LOW) before starting a new oscillation (pulse = HIGH). However, the results were inaccurate. When I used the pulse duration specified in this reference I got better results:
digitalWrite(3, HIGH);
delay(5);
digitalWrite(3, LOW);
delayMicroseconds(100);

ADC Sampling Rate Issue:
The Arduino Uno's ADC sampling rate is about 10,000 samples per second, but the shortest pulse duration I need to measure is approximately 41.24 microseconds (4.12425E-05 s). This duration is shorter than the ADC sampling interval. How is the Arduino able to measure such a short duration without undersampling, or do I misunderstand the process?

Did you consider your exciting pulse contains an infinite number of odd multiples of the pulse rate. That is what makes a digital pulse have sharp, square corners.

1 Like

If using the ADC, change the ADC sample frequency to 50 kHz or higher.

You seem to be using pulseIn(), which does not use the ADC. Post the code, using code tags.

1 Like

Here is the code:

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSansOblique12pt7b.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Declare variables for pulse, frequency, capacitance, and inductance
double pulse, frequency, capacitance, inductance;

void setup() {
  Wire.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  delay(1000);
  display.clearDisplay();
  display.display();

  // Initialize serial communication with a baud rate of 115200
  Serial.begin(115200);

  // Set pin 8 as INPUT and pin 9 as ;'//''//'
  pinMode(8, INPUT); // this is the output of the comparator
  pinMode(9, OUTPUT);// input pulse for the circuit

  // Wait for 200 milliseconds
  delay(200);
}

void loop() {
  // Generate a 5 ms HIGH pulse on pin 9
  digitalWrite(9, HIGH);
  delay(5);
  digitalWrite(9, LOW);
  delayMicroseconds(100);

  // Measure the duration of the HIGH pulse on pin 8
  pulse = pulseIn(8, HIGH, 5000);

  // Print output pulse to the Serial Plotter as "output signal"'''''
  Serial.print("output signal: ");
  Serial.println(pulse);

  // Check if the measured pulse duration is greater than 0.1 microseconds
  if (pulse > 0.1) {
    // Update with your specific capacitance value
    capacitance = 2.112E-6;

    // Calculate frequency and raw inductance using the measured pulse duration
    frequency = 1.0E6 / (2 * pulse);
    inductance = 1.0 / (capacitance * frequency * frequency * 4.0 * 3.14159 * 3.14159);
    inductance *= 1E6;

    // Apply piecewise calibration based on updated practical inductance range
    double calibratedInductance;
    if (inductance <= 0.8) {  // Practical range for low values (100 µH - 800 µH)
      calibratedInductance = 1.0139 * inductance - 0.0174;
    } else if (inductance > 0.8 && inductance <= 14) {  // Practical range for mid values (1 mH - 14 mH)
      calibratedInductance = 0.9324 * inductance + 0.1187;
    } else if (inductance > 14 && inductance <= 100) {  // Practical range for high values (20 mH - 100 mH)
      calibratedInductance = 0.9032 * inductance + 3.743;
    } else {
      // Out of range, no calibration applied
      calibratedInductance = inductance;
    }

    // Print calibrated measurements to the Serial Monitor
    Serial.print("High for uS:");
    Serial.print(pulse);
    Serial.print("\tfrequency Hz:");
    Serial.print(frequency);
    Serial.print("\tcalibrated inductance uH:");
    Serial.println(calibratedInductance);
    delay(10);

    // Display measurements on the OLED screen
    display.clearDisplay();
    display.drawRect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, SSD1306_WHITE);

    display.setFont(&FreeSans9pt7b);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(6, 25);
    display.print("Inductance:");

    // Choose appropriate units (uH or mH) based on the magnitude of inductance
    if (calibratedInductance > 999) {
      calibratedInductance /= 1000.0; // Convert to millihenries (mH)
      display.setFont(&FreeSans12pt7b);
      display.setCursor(6, 52);
      display.print(calibratedInductance);
      display.setCursor(58, 52);
      display.print("  mH");
    } else if (calibratedInductance < 1000) {
      display.setFont(&FreeSans12pt7b);
      display.setCursor(6, 52);
      display.print(calibratedInductance);
      display.setCursor(85, 52);
      display.print("  uH");
    }

    // Display on the OLED screen and wait for 2 seconds
    display.display();
    delay(2000);

  } else {
    // Inductor not connected, print "out of range" in place of inductance
    display.clearDisplay();
    display.drawRect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, SSD1306_WHITE);

    display.setTextColor(SSD1306_WHITE);
    display.setFont(&FreeSans9pt7b);
    display.setCursor(6, 25);
    display.print("Inductance:");

    display.setFont(&FreeSansOblique12pt7b);
    display.setCursor(6, 52);
    display.print("out of range");
    display.display();
    delay(10);
  }
}

Indeed, no use of the ADC

  // Measure the duration of the HIGH pulse on pin 8
  pulse = pulseIn(8, HIGH, 5000);

Many thanks for pointing this out.
Do you have any idea about this:
I use a digital pulse to excite the oscillations in the LC circuit. Initially, I chose the duty cycle and frequency such that the pulse allows the LC circuit to fully discharge (pulse = LOW) before starting a new oscillation (pulse = HIGH). However, the results were inaccurate. When I used the pulse duration specified in this reference I got better results:

digitalWrite(3, HIGH);
delay(5);
digitalWrite(3, LOW);
delayMicroseconds(100);

The best choice of pulse timing depends on the value of the L and C in the circuit. The design of this inductance meter is not the best, and it will work well only over certain ranges of L and C values.

2 Likes