# How to choose sample offset values in timing synchronization for a QPSK demodulator?

I am implementing a timing synchronization loop for a QPSK demodulator. I have chosen to use a Gardner timing error detector, which has often been mentioned. I am about to close my loop and I am connecting the output of the detector to the loop.

A question comes to my mind. The output of the detector follows an S-curve. There are symmetries (at -0.25T and 0.25T). For a given value calculated by estimator, what offset value should I put in the loop (if two are corresponding)?

The target offset is 0. This corresponds to zero timing error, and also has the highest slope (sensitivity) to a timing offset which is the ideal location to lock a loop.

The Gardner using three samples when the waveform is samples 2 samples per symbol. With $$n$$ sequenced at that sample rate, these samples are depicted as $$y[2n-1]$$ as the past sample and $$y[2n+1]$$ as the current sample, with $$y[2n]$$ as the sample in between. When there is no timing error $$y[2n]$$ will be at the zero crossing (on average) and these transitions from high to low (and low to high) is how the Gardner derives the S-curve. So once "locked", the resulting waveform can be down-sampled by two such that we are only using the $$y[2n-1]$$ and $$y[2n+1]$$ to be the previous and current sample for demodulation. The resulting S-curve is depicted in the graphic below as the long term average of the Gardner Timing Error Detector (TED) output vs symbol timing offset. As I detailed in this other post, the Gardner TED performs better when using the samples prior to the matched filter rather than after, since the waveform has less zero-crossing variation at this location in the receiver (the matched filter minimizes inter-symbol interference or ISI at the correct symbol sampling locations, but increases it at the zero crossings where we derive time error from!). The output of the TED should go to at least an integrator (accumulator) as the "loop filter" to get a first order Type 1 loop (which will lock to zero error under condition of static time offset). This is the cyclical counter below. The output of the integrator then drives a variable delay to correct time offset such that the integrator output "floats" to whatever value will keep the time error at zero on average. For an efficient and effective variable delay implementation, I recommend using a polyphase filter bank which very efficiently implements the interpolating upsampler, shift and down-sampler shown in the graphic without ever actually increasing the sampling rate. How do I know this? I teach courses on DSP and Python related to wireless comm through dsprelated.com and the IEEE with new courses running soon! This topic is detailed in my "DSP for Software Radio Course.