Measuring phase shift of a 10kHz analog signal: need help getting started

I'm working with a prototype sensor that changes impedance when environmental conditions change (sorry, can't provide too many details on the sensor itself).

Currently the sensor is read by generating a 10kHz sine wave, and measuring the phase difference using two fast comparators and a digital 12 bit counter with a 2MHz clock. The comparators generate a pulse on zero crossing, one starting and one stopping the counter. The sensor value is read as a 12 bit value from the counter.

I was hoping to simplify the circuit a lot with just an external sine generator, generating a 1.65V centered, 3.3V sine (single supply). And use the nRF52840 comparator to detect zero crossing (using differential mode with the negative input at 1.65V), starting a timer when the reference signal (AIN0) crosses zero, and stopping it when the sensor signal (AIN1) crosses zero. That should give me a good enough resolution. The original circuit uses a 2MHz clock, and I should be able to use the 16MHz timer.

If I understand things correctly, I need to use the comparator, PPI and timer peripherals, using PPI to route events. And that's where I get lost, the only PPI example I found is for timer to timer PPI. I'm assuming I need to set the AIN0 comparator to generate an UP event when the + input is "zero crossing" the - input set at 1.65V (my reference point for the 0 point of the 3.3V signal), and use PPI to start TimerX. Then use the UP event for AIN1 (with same reference point) to stop the timer, and store the value for further processing

Am I on the right path? Is there any guidance on how to properly initialize PPI, comparators and timer for a case like mine? I'm not expecting code, just pointers to get started and avoid going down dead ends

  • I think you may be asking the wrong question in terms of a PWM sine wave, but more of that anon. Here is the error with the 40-step PWM spoofing a 'scope with 10x sampling (160MHz of the 10kHz signal):

    Note the error is worst at the point of most interest.

    Returning to my earlier comment, PWM sine waves are often generated with a constant sampling interval, constant in terms of time as they are often derived from a periodic timer, however a better curve fit can be generated by using a constant amplitude interval. For (say) 40 samples for one cycle that means 10 intervals per quadrant, and arcsin(step) as the  time increment. A little awkward with this PWM as we can't change the underlying clock frequency but can change the repeat interval COUNTERTOP. This was my back-of-envelope spreadsheet waveform, which may well be promising:

    So what question might give a better answer? It depends on the unknown sensor, but purity of the sine wave is (probably) only critical near the zero-crossing points, as that is all that is actually used for the sample. So - and as this figure shows - it might be better to cuddle up more samples around the zero-crossings.

  • .. and of course I forgot to add the promising addition that might help, and now can't edit the response. Anyway note the error could be reduced by adding a second output pin. That could be done using two PWM peripherals but may as just use a second output on the same PWM as the clock signal would be the same in both cases 16MHz with no phase shift. This won't help unless the two output pins are combined with a (small) phase shift and amplitude attenuation on the correction phase. You might get away with simply using 150R 100nF on the primary output pin and connect a larger value resistor from the second output pin to the same capacitor; larger is try-it-and-see, but maybe 820R as it will both introduce a phase shift and attenuate the error signal. Worst-case use a potential divider on the error signal; the curve looks like 10% error so maybe attenuate by 10. I don't recall actually trying this ..

    The other point is that the secret sensor may not be ground-referenced in which case instead of using a half-bridge PWM (single pin) a full-bridge PWM (two pins) could be used with the second pin a simple table-inversion of the first pin. With full-bridge error-correction that would then require 4 pins but only 4 resistors and a single capacitor. Full-bridge doubles the excitation voltage on the sensor, which in turn compensates for the attenuation caused by the CR filter.

  • Thanks for the additional suggestions, I'm learning a lot from your answers. 

    Given all the issues I'm seeing with PWM and how much noise is left around zero crossing even after filtering, I'm at the moment experimenting with generating a square wave at 10kHz instead, and filtering it down to a sine. It won't be a perfect sine, but that is not a problem for this project: anything "sinusoidal enough" works. What is critical, is having a clean signal at zero crossing, and from early tests, square-to-sine seems to be much better

  • In the spirit of contributing to the community, I posted sample code to generate a square wave using timers and PPI, and to read the phase delay using the comparator github.com/.../nRF52_sample_code

Related