Goertzel Operation with Ultrasonic Transducers

Share on facebook
Share on twitter
Share on linkedin
Share on email
Share on print
Table of Contents

The P2 Goertzel circuit measures up to four ADC input signals for magnitude and phase correlation of four internal reference signals, which can also be output to form closed-looped systems.

In this demo, the Goertzel circuit outputs a reference sine pattern to two DAC pins which differentially drive a 40 kHz ultrasonic transducer. Another identical transducer is connected between GND and an ADC pin, so that its ADC bitstream can be used as input to the correlator. On each clock cycle, the correlator multiplies the ADC bit (+1 or -1) by the current reference sine and cosine values, accumulating the products into separate sine and cosine accumulators. The accumulators can be periodically sampled and converted from cartesian to polar form, in order to get the magnitude and phase of the incoming signal(s) relative to the internal reference sine and cosine signals. The Goertzel measurement is done over 1 to 65,534 complete waveform cycles. The more cycles that are measured, the more precise the measurement.

On every clock cycle the Goertzel circuit effectively does this in sequence:

   t := LUT[nco[30:22]] (the LUT can be partitioned in 1/2’s, 1/4’s, etc)
   nco += xfrq (set by SETXFRQ instruction)
   cog_dac_3 := t.byte[3] ^ $80 (cog DAC channel 3 playable on pins %xxxx_11)
   cog_dac_2 := t.byte[2] ^ $80 (cog DAC channel 2 playable on pins %xxxx_10)
   cog_dac_1 := t.byte[1] ^ $80 (cog DAC channel 1 playable on pins %xxxx_01)
   cog_dac_0 := t.byte[0] ^ $80 (cog DAC channel 0 playable on pins %xxxx_00)
   sin := t.byte[3] sign-extended
   cos := t.byte[2] sign-extended
   m := ADC_bit ? 1 : -1
   sin_accumulator += sin * m (32-bit sin accumulator)
   cos_accumulator += cos * m (32-bit cos accumulator)

After each XCONT, GETXACC can read and clear the accumulators in one clock cycle:

   capture sin_accumulator for conveyance to GETXACC’s D
   capture cos_accumulator for conveyance to next instruction’s S
   sin_accumulator := sin * m (clear to current sin * m)
   cos_accumulator := cos * m (clear to current cos * m)

The Goertzel circuit may also be used to simply detect magnitude of a frequency within a noisy signal. In that case, no reference outputs would be needed, because there is no feedback loop.

Parts Used
Programming Language
Tools and Operating System
Document Author
Source Code Author
Table of Contents
0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments
Copyright © 2021 Parallax Inc. All Rights Reserved
Designed and Made in California, USA