Shop OBEX P1 Docs P2 Docs Learn Events
Goertzel for detecting a 'beep'? Solved! — Parallax Forums

Goertzel for detecting a 'beep'? Solved!

R BaggettR Baggett Posts: 247
edited 2026-02-13 14:26 in Propeller 2

I have been trying to get a handle on the Goertzel function. It is exceedingly cool to see some of the sensors demonstrated for measuring position. But all the examples I find are doing this exact thing. I get that you must generate or sample the original signal to be able to measure phase.

All I want is amplitude. We have a product that beeps (Usually 2.4KHZ) and I want to detect this happening in the test fixture. The fixture is also RF-tight so there is a vanishingly small chance of any significant external acoustic noise. I just want to see some step response in the amplitude at 2.4 KHZ for the 'beep' which will be sensed using an electret microphone in the usual way.

Is there some way to do this without worrying about a beat between some locally generated 2.4KHZ and whatever the UUT puts out?

I suspect I am making this much harder than it needs to be, and I have little time for experimentation... or even the high probability that there simply is a better way...

Comments

  • A while ago I made some experiments with an electret microphone in a headset and it was very frustrating because the long cable picked up a lot of 50Hz humming from the power grid and ~30kHz common mode noise from the power supply. The noise was so strong that it drove the ADC into saturation so I couldn't get any useful signal even with (post-) filtering unless I powered the whole circuit from batteries. I wonder how the audio input of a PC can get a quite good sound quality with all the noise inside the PC.

    However, that shouldn't happen in your case if the microphone is placed close to the P2. I'm not worried about the Goertzel function itself. If the sample time is long (say 100ms) you can get very good selectivity (narrow bandwidth, high Q). Is the 2.4kHz frequency accurate or is it generated by a piezo buzzer?

  • @ManAtWork said:

    A while ago I made some experiments with an electret microphone in a headset and it was very frustrating because the long cable picked up a lot of 50Hz humming from the power grid and ~30kHz common mode noise from the power supply. The noise was so strong that it drove the ADC into saturation so I couldn't get any useful signal even with (post-) filtering unless I powered the whole circuit from batteries. I wonder how the audio input of a PC can get a quite good sound quality with all the noise inside the PC.

    I have had pretty good results with Electrets in previous projects.. and dismal results using stuff intended for PCs (Which were very possibly damaged...) Headsets, especially those for HTs, do some really evil things with ground..

    Is the 2.4kHz frequency accurate or is it generated by a piezo buzzer?

    this one is driven from a ESP32-C3-WROOM-02-N4 pin, so really accurate. Not always the case. Sometimes a buzzer or PIC running RC mode. I don't anticipate needing a very narrow bandwidth, and again, I will look for a difference between beep or no beep. I need to be fairly quick, these UUTs come in a panel of 12 and I will need to time them so the beeps (And other things) happen one at a time.

    I was also laboring under the assumption that this was a function of the smart pin which I have not had the luxury of the time needed to understand well.. but now I know it is a function of the streamer.. which is still complete voodoo to me.>

  • No voodoo required. You can just use the Goertzel demo and play a bit with the parameters:

      'set operating parameters
      dacpins   := 0 addpins 1      'differential DAC outputs on P0 and P1 connect to one 40 kHz transducer
      adcpin    := 8                'ADC input on P8 and GND connect to the other 40 kHz transducer
      adcmag    := 4                'full 100x magnification on ADC
      frequency := 40_000           '40 kHz output/input
      cycles    := 400              '40 kHz / 400 cycles = 100 measurements per second
    

    Leave the DAC pins unconnected and connect your microphone to the ADC pin. Set the frequency to 2_400 and cycles to something around 100. This gives 100 / 2.4kHz = 41.6ms sampling time. The longer the sampling time the better the selectivity but also the higher the reaction time. You can experiment with adcmag and cycles until you get reasonable amplitude readings.

    If the beep is the loudest signal and the distance is constant a fixed threshold should work. If there is noise and other sounds in the background it might be a little more difficult. A loud hissing sound could trigger a false alarm because white noise has a widespread spectrum and might induce enough power into the 2.4kHz slice. So a relative threshold would be better, calculating the signal vs. noise ratio.

  • Perhaps some additional comments from my side. I have used Goertzel filters for several purposes.
    1. About hum: It is very dependent from careful shielding and grounding. Use a separater analogue GND as a star to avoid ground loops. A connection to "real ground" is often very helpful.
    2. Almost certainly an analogue amplifier with low impedance output will help much. The onboard gain of the adc leads to lower input impedance and adds noise. Gain 100 gives worse results than gain 33.
    3. Probably the sample frequency can be lowered to perhaps 12kHz or so.

    The hardware "Goertzel" filter of P2 (the name is misleading, I think, it's a IQ mixer) has three major restrictions: It does overflow relatively easily. And it does need a cog waiting for the result, because it has no double buffering for the result. There is only one filter per cog, so only one frequency can be watched at one input.
    Because of these restrictions it's use is really good only for relatively high frequencies. As a Cog must be dedicated anyways, you can do real software Goertzel filtering for the Audio Frequency range. Can have several filters in parallel. Software Goertzel can often be done on the fly between adc sampling.
    In my opinion using software for the filter is less obscure and easier to debug. The (simple) pseudo code is here: https://en.wikipedia.org/wiki/Goertzel_algorithm
    Cheers Christof

  • @ManAtWork said:
    No voodoo required. You can just use the Goertzel demo and play a bit with the parameters:

    Well, now I know where to stick the pins.. and kinda why...

    @"Christof Eb." said:
    I think, it's a IQ mixer)

    Agreed. (Places streamer effigy with pins on top of 'ARRL Handbook for Radio Communications'. No observable difference. Maybe it's not voodoo.)

    Ok, the experiment:

    I don't have a microphone available, so I use a signal generator set to 2.4 KHZ and 10.0 mV P-P out.(minimum amplitude available)
    I apply this to a 10:1 voltage divider made of 2 resistors in a Jonnymac breadboard. This is coupled to the P2 Pin 8 through .33uF cap. Should be 2 mV p-p (The signal generator expects 50 Ohm impedance, actual is >2.4K) Scope measures at about 11mV barely visible buried in noise.

    Bandwidth appears to be about 40 Hz. (2420, 2380 HZ are visually indistinguishable from no signal)

    I had to place 'Magnification' at zero, Cycles at 50.

    Signal applied: Goertzel window shows a fairly coherent dot, with a consistent amplitude and slowly drifting phase. Terminal shows magnitude numbers around mid 90K.
    Signal Off: Goertzel window goes chaotic. Terminal shows magnitudes 1K-5K

    I think this will work. There are no spare pins (Or cogs) available, so I will need to hijack a pin for output and cog somewhere temporarily during the inspection.

    Thanks!

  • @"Christof Eb." said:

    Software Goertzel can often be done on the fly between adc sampling.

    In my opinion using software for the filter is less obscure and easier to debug.

    Basically, I totally agree. But the question is if you want to start a multiple man-month software project aiming for a general purpose tool for customers or you're happy with a quick hack that just works in a special case.

    There are no spare pins (Or cogs) available

    Maybe you have some cog that already runs a loop to poll something every 10..20ms or so. The Goertzel streamer doesn't need much computing power, just a poll for every sample period.

Sign In or Register to comment.