I am trying to extract the impedance from a sampled signal. Specifically, I have only noisy samples of a sinusoid, of a single period, of current and voltage at a given known frequency. I am trying to implement a method that does not use the FFT, due to potential requirements of the MCU where the algorithm would run.

Back to the question - I can heavily digitally filter those samples and extract a more or less clean sinusoid (this was tested).

My approach starts with the assumption that I can have the phase shift from the cross-correlation that uses a reference phase signal (here: the current), therefore collapses to a dot-product, also normalized for the amplidute variation of the two signals (reference: How do I get the phase angle from Cross Correlation?)


I am not sure about my assumptions here, which are:

  • The real part of the impedance Z is R = VRMS / IRMS.
  • X = 2πf·sin(θ), because when I look around it seems I always need to know C or L, but C or L is actually my unknown.

If this approach is wrong, what about the rectangular notation? I can have:

R = Acos(θ); X = Asin(θ)

It seems that A is the peak value of the sinusoid, but I have 2 different sinusoids with 2 different amplitudes. So what would be "A" in this case?

  • 2
    \$\begingroup\$ You should try a DFT on your "simultaneously" taken samples. See this post. electronics.stackexchange.com/questions/574979/… \$\endgroup\$
    – Antonio51
    Jan 12 at 11:54
  • 1
    \$\begingroup\$ That gets you the power factor, but not necessarily the reactive power because harmonics/noise contribute to the apparent power; you can get phase correlating each (x and y) with sin and cos, i.e., a single-frequency Fourier transform (you can use DFT and take the fundamental bin(s) if you like). \$\endgroup\$ Jan 12 at 11:58
  • \$\begingroup\$ The key is that avoiding the DFT would be easier to implemente on an embedded platform (and the cross correlation shoudl habe o(n^2) complexity). \$\endgroup\$
    – thexeno
    Jan 12 at 12:48
  • \$\begingroup\$ Please, add a picture of your "noisy" waveforms ... and perhaps simplified schematic. \$\endgroup\$
    – Antonio51
    Jan 12 at 12:57
  • 1
    \$\begingroup\$ The calculation shown will generate a close answer, but does not give sign, so you need to add the assumption whether it's inductive or capacitive. In the presence of noise, the difference (intended: apparent minus real equals reactive power) will include Vrms and/or Irms from those other frequencies, not just the actual reactive part. You need a correlation to the voltage at least (and its 90° conjugate), or an independent reference (hence DFT), to measure these. \$\endgroup\$ Jan 12 at 22:30

2 Answers 2


The canonical way to approach this problem is I-Q demodulation.

In RF terms, we're using a synchronous detector/demodulator. A real AC signal has in-phase (I) and out-of-phase (Q) components, or sin and cos if you prefer, and if we simply multiplied a signal (point by point) by a sine wave, we'd lose half that information. So we multiply by cosine as well, and this preserves all information in the signal.

$$ \begin{eqnarray} I & = \int_0^{2\pi} x(t) \sin t \, dt \\ Q & = \int_0^{2\pi} x(t) \cos t \, dt \end{eqnarray} $$

Written here as integral over a single cycle, giving the correlations for that cycle. In practice, this might be done by taking a weighted average of the product over some time window (that is to say, a lowpass filter), as in an analog receiver; or by changing \$d\$s to \$\Delta\$s and integral to summation to give the DSP case (in other words, what you'd implement on an MCU). (A receiver might then take the magnitude (\$\sqrt{I^2 + Q^2}\$) for AM, or the angle change per cycle for FM, for example; but we're doing a much simpler kind of detection here.)

Of course, \$x(t)\$ is one signal; you have two (current and voltage), so you can either assume rather than measure one (when the circuit permits such -- using an op-amp to force voltage, or read current with minimal voltage drop, for example), or repeat the analysis for both. (Your resources seem limited, suggesting the double measurement would be undesirable?)

In case both are measured, you need to divide one by the other to get the normalized phase and magnitude: $$\hat{Z} = R + jX = \frac{I_V + jQ_V}{I_I + jQ_I}$$ (Denoting complex impedance Z with a hat, and voltage and current readings with respective subscripts.)

Measuring just one, you're still doing the same thing (you can't get impedance from units of voltage and current other than by taking their ratio!), but using an assumed value for one of the complex numbers: this will be a calibration parameter, which ideally should be set on initial power-up testing. It may depend on frequency, in which case a lookup table would be helpful (calibrating over a range of frequencies).

And that's it. The \$X\$ can be converted to equivalent L or C, and then we have the R-C or R-L series equivalent circuit at the measured frequency, or we can apply the suitable transformations to get the parallel equivalents.

Which, as long as it's fresh in my mind -- I recently wrote that for a calculator on my website:
Vector Impedance by Resistor Divider | Calculators | Seven Transistor Labs, LLC
Opening dev. console shows the code quoted below (plain old JS):

function vec_Update() {
    var R = parseFloat(document.getElementById("vec_R").value);
    var V1 = parseFloat(document.getElementById("vec_V1").value);
    var V2 = parseFloat(document.getElementById("vec_V2").value);
    var th = parseFloat(document.getElementById("vec_th").value);
    var F = parseFloat(document.getElementById("vec_F").value);
    th = th * Math.PI / 180;
    F = 2 * Math.PI * F;
    var H = V2 / V1;
    var HR = H * Math.cos(th), HI = H * Math.sin(th);
    var ZR = (R * (HR - H * H)) / (1 - 2 * HR + H * H);
    var ZX = (R * HI) / (1 - 2 * HR + H * H);
    document.getElementById("vec_ZR").innerHTML = ZR.toPrecision(9);
    document.getElementById("vec_ZX").innerHTML = ZX.toPrecision(9);
    document.getElementById("vec_ZMag").innerHTML = Math.sqrt(ZX * ZX + ZR * ZR).toPrecision(9);
    document.getElementById("vec_ZArg").innerHTML = (Math.atan2(ZX, ZR) * 180 / Math.PI).toPrecision(5);
    document.getElementById("vec_ESR").innerHTML = ZR.toPrecision(9);
    document.getElementById("vec_ESL").innerHTML = (ZX / F).toPrecision(9);
    document.getElementById("vec_ESC").innerHTML = (-1 / (F * ZX)).toPrecision(9);
    var ZPR = (ZR * ZR + ZX * ZX) / ZR;
    var ZPX = (ZR * ZR + ZX * ZX) / ZX;
    document.getElementById("vec_EPR").innerHTML = ZPR.toPrecision(9);
    document.getElementById("vec_EPL").innerHTML = (ZPX / F).toPrecision(9);
    document.getElementById("vec_EPC").innerHTML = (-1 / (F * ZPX)).toPrecision(9);

This takes in a magnitude and angle as measured by an oscilloscope, but it's immediately decomposed into I and Q parts (HR and HX). A more accurate measurement would be had by taking in the raw waveforms and doing the correlations, but, well, that's rather hard to do from a browser(!).

This also uses a slightly more complicated expression, since the voltage divider has to be accounted for: it's not measuring current and voltage, it's measuring a ratio of voltages. The reference resistance (assumption: its phase is very close to 0°) is a calibration parameter here. In your case, the ZR (\$R\$) and ZX (\$X\$) are given as above.

Incidentally, this method (phase angle by zero-crossing) kind of has the same problem as your proposal; they're quite different in method of course, but in the sense that, they aren't measuring exactly the intended aspect (fundamental sin/cos components), but aspects only related to it (real/apparent power there, zero-crossing here). As such, both are sensitive to components other than the fundamental -- harmonics and noise.

And, if you are in such a situation, where assumptions can be taken, perhaps fairly strong ones -- maybe taking ratios of magnitudes (as yours), or zero-crossing points, or assuming a scalar is wholly real or imaginary as the case may be -- as long as you're comfortable with those assumptions, that can be effective too. Common example: capacitor ESR testers generally measure magnitude voltage, assuming it to be a resistive component; but ESL, and C itself if small, also participate; ESL especially, since the waveforms are often sharp (e.g. square wave). This makes the readings diverge rather dramatically for long lead lengths, or at small values, but such a device is still useful enough as both of those can be controlled. Using one on in-circuit electrolytics of modest or greater value, meets both of those assumptions.

  • \$\begingroup\$ My DFT approach is the application of the (I,Q) calculus (?). As I have shown, for a good search of the phase, one needs a big "number" of periods if "random" noise is added. And sub-degree resolution seems "very" difficult to achieve. \$\endgroup\$
    – Antonio51
    Jan 17 at 8:21
  • \$\begingroup\$ To be clear, @Antonio51's method is the generalization of this -- DFT is a faster way (O(N lg N)) to do all frequencies at once. When you know the frequency (e.g. from a DDS source), convolution with it is O(N); and that work can be done incrementally (per sample) so it's easily done on an MCU. \$\endgroup\$ Jan 17 at 13:38
  • \$\begingroup\$ That's a clear explanation, thanks. I will measure 2 signals at the same time, I and V simultanously no problem there. My doubt is: would make sense to get I/Q with an internally numerical (assumed) sin/cos, used for the I/Q calc of V, then the same numerical sin/cos for the I/Q cal of I, then making the complex ratio? That is despite I know the I in advance, it must be measured to compensate some circuit parasitics (and this would avoid calibration for this specific case) \$\endgroup\$
    – thexeno
    Jan 21 at 11:39
  • \$\begingroup\$ Indeed, you can measure the phase and amplitude of the reference and see what it is. It would be maybe surprising to me that an MCU can run fast enough (while getting enough samples/cycle (100s?) to get good harmonic rejection) that significant phase error is produced in the circuit, but that is indeed the way to compensate for it when needed. \$\endgroup\$ Jan 21 at 17:00
  • \$\begingroup\$ Firmware (or tricking MCUs to do what I want) is more my speciality, but I might not do everyday certain signal processing stuff, so I am a bit on the learn for it. So I am not sure I understand what you mean by "and see what it is": I would measure I and Q of current, then I and Q of voltage, and calculate Z. The sin()/cos() function of the I/Q gneerted in the FW would be the same sin() I use to propagate the electrical current signal in the circuit. So that would be related. Just checking is these steps are correct in theory \$\endgroup\$
    – thexeno
    Jan 22 at 10:50

I am trying to extract the impedance from a sampled signal. Specifically, I have only noisy samples of a sinusoid, of a single period, of current and voltage at a given known frequency.

Here is a Maple sheet (1 period, DFT application, 3 cases, N samples 1024 & 32 & 8) that "checks the error percentage of the calculated data with some "random" added to the theoretical data.

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

An with "no noise" for checking ...

enter image description here


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.