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

  • That's interesting. I was actually wondering what would happen if I tried to use GPIOTE instead of COMP, relying on the digital threshold for high vs low, but I was worried about threshold matching. Based on what you say, it's well worth trying.

    I don't have a lot of experience using PWM to generate a smooth sine, but if I could use the nRF52840 to also generate the sine, it would simplify the circuit further, on top of improving uncertainty. Actually, if I can generate the sine signal cleanly enough, I only need a single input, and can use COMP. Since I'm generating the PWM using a timer, I will know by definition when the original signal crosses zero.

    I'm assuming I should use an RC filter to smooth things out. What values of RC would you suggest using to generate a smooth 10kHz sine from the nRF52 PWM output? 

  • It's just the nrfx_comp.c/.h files. But they do provide a way to trigger a handler from the comp interrupt.

    I don't know how I missed that. Thanks!

  • The CR filter is just that, a resistor feeding a capacitor to Gnd with the output at the CR junction. -3dB frequency set to (say) 10kHz gives 50% of available signal at the output. f=1/2pieCR, but very high values of R will be a problem depending on the impedance of the connected circuit being driven. Avoid polarised Tants, instead use ceramics for the capacitor.

    Maybe try 160R 100nF for 10kHz -3dB. Need to set PWM output pin to H0H1 drive levels, by the way, since driving a capacitive load

  • I wonder if the search for a zero-crossing detector is quite the optimal approach, since maybe phase offset is actually what is required. If the phase offset signal at 10kHz is slowly changing two SAADC channels can be used to sample the sine voltage over a period of time then use correlation to align in time the two phase-shifted sequences to get a measure of phase offset. Alternatively a time-shifted sample of the excitation and reference voltages can be used to calculated phase offset given the voltage difference.

    A reference time-shifted signal can also be used on a second PWM with the time-shift adjusted until the sensor output and the reference are time-aligned, then the time-shift indicates the phase difference.

    With a slow phase-difference change from the sensor note comparators could still be used, simply switch the comparator from one pin to the other every other 10kHz cycle.

    // Read Mode: Digital Counter Input or ADC or Comparator
    // =====================================================
    //                                                                       +--------------------
    //                                                                       |    VDD
    //   CR = 10kHz or higher, 150R optional                                 |   --#--
    //                                                                       |     |
    //                                                                       |     |
    //                                  +------+                             |     +-|
    //   +---------#--------------------[ 150R ]-----+                       |       |--+
    //   |         |                    +------+     |                       |     +-|  |
    //   |         |                    +------+     |                       |     |    |
    //   |         |       #--------#---[ 150R ]-----#-----------------------O-----#    0<-- P0.nn from PWM
    //   |         |       |        |   +------+                             |     |    |    H0H1 Output
    //   |         |       |        |                                        |     +-|  |
    //   |         |       |        |                                        |       |--+
    //   |    100nF|  100nF|        |                                        |     +-|
    //   |       -----   -----      |                                        |     |
    //   |       -----   -----      |                                        |     |
    //   |         |       |        |                                        |   =====
    //   |         |       |        |          (Dummy)                       |    ===
    //   |       =====   =====      |         +--------+                     |     =
    //   |        ===     ===       |         |        |  (Reference)        |                        Optional
    //   |         =       =        +---------0        0---------------------O-----#-------------#--> P0.nn ADC
    //   |                                    |        |                     |     |             |          Ref = VDD (Ratiometric)
    //   |                                    |        |                     |     +-|           |          or COMP
    //   |                                    |        |                     |       |<- P0.n  -----        or Digital Counter
    //   |Excitation                          +--------+                     |     +-|         -----
    //   |10kHz Sine                                                         |     |             |
    //   |                                                                   |     |             |
    //   |                                                                   |   =====         =====
    //   |                                                                   |    ===           ===
    //   |                                                                   |     -             -
    //   |                                                Sensor Excitation  |
    //   +-------------------------------------------------------------------O-----#-------------#--> P0.nn ADC
    //   |                                                                   |     |             |          Ref = VDD (Ratiometric)
    //   |                                                                   |     +-|           |          or COMP
    //   |                                                                   |       |<- P0.n  -----        or Digital Counter
    //   |                                                                   |     +-|         -----
    //   |                                                                   |     |             |
    //   |                                                                   |     |             |
    //   |                                                                   |   =====         =====
    //   |                                                                   |    ===           ===
    //   |               Unknown                                             |     =             =
    //   |               Sensor                                              |
    //   |              +--------+                                           |
    //   |              |        |                        Sensor Signal      |
    //   *--------------0        0-------------------------------------------O-----#-------------#--> P0.nn ADC
    //                  |        |                                           |     |             |          Ref = VDD (Ratiometric)
    //                  |        |                                           |     +-|           |          or COMP
    //                  |        |                                           |       |<- P0.n  -----        or Digital Counter
    //                  +--------+                                           |     +-|         -----
    //                                                                       |     |             |
    //                                                                       |     |             |
    //                                                                       |   =====         =====
    //                                                                       |    ===           ===
    //                                                                       |     =             =
    //                                                                       |
    //                                                                       +----------------------------------
    

    The FET drivers in the nRF52 have a finite resistance; in principle the external resistors could be left out by adjusting the capacitance to give a clean signal relying on that internal FET resistance.

    Low-level drivers would be preferred instead of the Nordic libraries for optimal performance.

  • If the phase offset signal at 10kHz is slowly changing two SAADC channels can be used to sample the sine voltage over a period of time then use correlation to align in time the two phase-shifted sequences to get a measure of phase offset.

    I actually did think about that as my first approach, but the SAADC of the nRF52840 is too slow for such an approach (200ksps) and the sensor resolution would be 10x lower than the current analog circuit using fast comparators to detect zero crossing with a 2MHz clock. Also, in my experience, SAADC noise would make the correlation even lower resolution than the theoretical 200kHz. Given that the sensor won't change impedance quickly, I could average over multiple values to reduce noise, but I still think it would be computationally intensive for no real value over zero crossing detection and a timer

    A reference time-shifted signal can also be used on a second PWM with the time-shift adjusted until the sensor output and the reference are time-aligned, then the time-shift indicates the phase difference.

    With a slow phase-difference change from the sensor note comparators could still be used, simply switch the comparator from one pin to the other every other 10kHz cycle.

    Oooh, clever. This is a really interesting idea, need to mull this over, thanks!

Related