I’m working on a project to measure unknown inductance using an inductor meter. I’m approaching it as a first-order RL system and measuring the output voltage across the resistor R. The input is a fixed pulse that is on for 500 microseconds and off for 500 microseconds.
My goal is to determine the time constant (T), which is 63% of the steady-state value, and then calculate the inductance (L) using the formula ( L = TR ).
The issue I’m facing is that I’m unable to capture the transient response values to determine the time constant. My code only provides the final steady-state value.
Here is the code I’m using:
// Define the output pin and the analog input pin
const int outputPin = 13; // Digital pin 13 to output the pulse
const int analogPin = A0; // Analog pin to read the voltage
const float targetVoltage = 4.779 * 0.632; // Target voltage to detect, calculated as 3.018 V
// Time for on and off in microseconds (control frequency)
const unsigned long onTime = 500; // 500 microseconds on time
const unsigned long offTime = 500; // 500 microseconds off time
void setup() {
pinMode(outputPin, OUTPUT); // Set the output pin mode
Serial.begin(9600); // Initialize serial communication for logging
}
void loop() {
// Generate a square wave pulse
digitalWrite(outputPin, HIGH); // Turn ON the pin
delayMicroseconds(onTime); // Keep it ON for 500 microseconds
digitalWrite(outputPin, LOW); // Turn OFF the pin
delayMicroseconds(offTime); // Keep it OFF for 500 microseconds
// Read the analog input and convert it to a voltage
int analogValue = analogRead(analogPin); // Read the analog value (0-1023)
float voltage = (analogValue * 5.0) / 1023.0; // Convert to voltage (0-5V)
// Check if the voltage reaches 3.018V
if (voltage >= targetVoltage) {
unsigned long currentTime = micros(); // Record the time in microseconds
Serial.print("Voltage reached target Voltage at time: ");
Serial.print(currentTime);
Serial.println(" microseconds");
// Optional: Stop after the first detection, or continue to find more events
// while(true); // Uncomment this line if you want to stop the loop after detecting 3.018V
}
}
To measure the transient response, you need to measure a series of voltage values, very quickly. The posted code measures only one value, after a delay.
There are plenty of Arduino projects on line showing how to measure capacitance, using the same basic approach (fewer LR examples). Example search phrase: "arduino capacitance meter".
I have tried a code from one of the projects to measure unknown inductors after making minor changes, but I am getting incorrect results. I always get 116 mH, even when changing the inductor. Here is the code I am using and .`
// Initialize Pins
int analogPin = A0; // Pin to read voltage across series resistor (representing current)
int chargePin = 13; // Pin to control charging of the inductor
int dischargePin = 11; // Pin to control discharge
// Initialize Resistor (Series resistor used to measure current)
int resistorValue = 1000; // Adjust based on your inductor range. Try 100 ohms for low inductance.
// Initialize Timer
unsigned long startTime;
unsigned long elapsedTime;
// Initialize Inductance Variables
float microHenries;
float milliHenries;
const int targetADCValue = 648; // Target ADC value (63.2% of full scale on 10-bit ADC)
void setup() {
pinMode(chargePin, OUTPUT);
digitalWrite(chargePin, LOW);
Serial.begin(9600); // Initialize serial communication for monitoring
}
void loop() {
digitalWrite(chargePin, HIGH); // Start charging the inductor
startTime = micros(); // Start the timer (microsecond precision)
// Monitor the voltage across the series resistor until it reaches 63.2% of total current (represented by voltage)
while (analogRead(analogPin) < targetADCValue) {
// Wait until the current reaches 63.2% of the total current (voltage)
}
elapsedTime = micros() - startTime; // Calculate the time in microseconds
microHenries = ((float)elapsedTime * resistorValue); // Calculate inductance in microHenries
Serial.print(elapsedTime);
Serial.print(" µs ");
if (microHenries > 1000) {
milliHenries = microHenries / 1000.0;
Serial.print(milliHenries);
Serial.println(" milliHenries");
} else {
Serial.print(microHenries);
Serial.println(" microHenries");
}
digitalWrite(chargePin, LOW); // Stop charging inductor
// Discharge the inductor
pinMode(dischargePin, OUTPUT);
digitalWrite(dischargePin, LOW); // Allows the inductor to discharge
while (analogRead(analogPin) > 0) {
// Wait until the inductor is fully discharged
}
pinMode(dischargePin, INPUT); // Stop discharge
delay(500); // Small delay before repeating the process
}
Well, that is a problem.
The maximum sample rate for the Uno is a little less than 10,000 samples/second, that's one sample every 100us.
For an accurate reading you should get atleast 100 samples during the 500us pulse and that would require a sample every 5us
You need to increase the time constant, so that you can get enough samples. You can try increasing the pulse to 10ms and of course you need to make the resistor smaller
The Uno R3 takes about 110 microseconds to make one ADC reading, by default.
Studying the posted code, and assuming that the very first ADC reading exceeds 648, then all you learn from that is that L is less than about 110 mH. Does that seem like a familiar number?
It is possible to speed up the ADC by changing the ADC prescaler, but that is an advanced programming technique.
I tried reducing the value of the resistor to increase the value of T further, but the change in the time constant is still much faster than what the Arduino can handle.
For example, T = (L max) / R = (100 mH) / (100 Ω) = 10 µs, while the Arduino's smallest sampling interval is approximately 100 µs.
I will now be moving to a second-order system to implement this project.
100mH/100 = 1ms
However, even at 1m you will only get 10 samples.
The Arduino has an unadvertised peripherial called the analog comparator. It can set a bit or start an ISR when one voltage becomes larger/smaller than another.
If you connect one input to your LR circuit and the other to say 3.3V you can use it to measure the time it takes for the Resistor voltage to exceed 3.3V. From that you can calculate the time constant.