# realtime software 90 degree phase shift a sinusoidal signal

I would post this to stack overflow but it seems to me more like a signals and systems problem, which EE's thrive on.

I need a realtime system implemented in software that can generate a sinusoid that matches the input signal's frequency but with a phase lag of 90 degrees. The input signal will be a pure tone but can drift a bit in frequency (0.4 to 0.8hz) over time. Eventually I'll want output amplitude to scale with input amplitude as well but that's for another day. I'm aiming to be able to respond to input signal changes such that I'm under 5% phase error within about 10-15 seconds (a few input signal cycles).

My first attempt at this has used a hilbert transformer FIR filter to give me the "instantanous" relative phase between my input signal (100hz sample rate) and output, then a PI controller with set point =-90 to drive frequency f_out of output_signal = math.sin(2*math.pi*f_out*t). My hilbert transofmer FIR has a latency of 2.5 seconds and the dead time seems to prevent me from having any kind of a P constant without instability.

I'm currently doing a deep dive into phase locked loops (I'm new to them) but it's not clear to me yet if this is the right tree to bark up.

I'd appreciate any manner of direction/advice.

• Have you considered simple integration and/or differentiation? Feb 22 '20 at 5:01
• "At a glance" it seems that you could - Store the signal, start outputting an appropriate offset signal after one cycle (so under 2.5s initial delay) then ongoingly analyse the latest cycle and then apply the result to the signal "outputter". You CANNOT get a pure output sine wave for a shifting signal (and indeed the input is not a pure sinewave if it is shifting in frequency as the cycle length and thus waveshape is varying continually) but this should allow as good a result as any. Feb 22 '20 at 5:31
• PLL is the best way to do this, IMO. Feb 22 '20 at 7:44
• I agree with @pericynthion : use a PLL that has a phase detector that has 0 error in quadrature condition such as a mixer or xor gate. Once locked this will continuously track the changing input signal condition and stay in 90 degree phase for all signals within its tracking bandwidth. Feb 22 '20 at 12:54
• If, as you say. the signal "can drift" 0.4Hz ... does that suggest its frequency is reasonably well known in advance? 5 degrees tolerance on the phase shift is quite a lot. Simply delaying it a quarter cycle may be an option (tuning the delay as it drifts). In the analog domain, a quarter wave delay line (length of coax cable) was a traditional answer; somewhat simpler than a Hilbert transform. Feb 22 '20 at 14:00

If you have it in a buffer and have enough computing power, you can track it to quite significant accuracy using two DFT bins and the formulas shown here:

For minimum latency I would recommend a frame length near 2 and 1/2 cycles, though for a clean signal 1 and 1/2 cycles should also give good results.

As you do a series of sliding windows, this will generate a sequence of parameters. A moving exponential average of the parameters should give you a good current value (when they are slowly varying) to use. More sophisticated techniques are available.

Once you have the current parameters, you can reconstruct a signal with any phase lag and/or amplitude adjustment you want.

Or if you are tracking the phase value frame to frame, the most accurate fit is at the center of the frame ($$t_f$$ is at $$n=N/2$$).

$$x(t) = A( t ) \cos( \Phi( t ) )$$

Where $$\Phi( t )$$ is a (predictive) near linear function and $$A( t_f )$$ comes directly from the two bins solution.

You could use a SOGI-based PLL. They are used for single-phase power systems.

https://www.researchgate.net/figure/Diagram-of-the-SOGI-based-PLL-SOGI-PLL_fig3_224165889

You could use the Vd and Vq output, Vd would correspond to your input, and Vq would be your input shifted by 90 degrees.

• Even the SOGI takes a while to sync. It can be adjusted with the error gain, but that affects the bandwidth. But if the signal is clean, no need for much bandwidth... Feb 22 '20 at 20:29
• Yeah of course, it takes a while but you can pre-initialize it in order for the PLL to match the incoming signal faster
– Ben
Feb 22 '20 at 22:25

"At a glance" it seems that you could -

• Store the signal, or even just determine when a cycle had completed. Then

• Start outputting an appropriate offset signal after one cycle (so under 2.5s initial delay) then

• Ongoingly analyse the latest cycle and then apply the result to the signal "outputter". Rather than step skewing the signal frequency with any new result you can produce a slew rate in the output source based on some 'law" - could be linear rate until matched, rate dependent of difference in frequencies, PID or ... .

You CANNOT get a pure output sine wave for a shifting signal (and indeed the input is not a pure sinewave if it is shifting in frequency as the cycle length and thus waveshape is varying continually) but this should allow as good a result as any.