Daqarta
Data AcQuisition And Real-Time Analysis
Scope - Spectrum - Spectrogram - Signal Generator
Software for Windows
The following is from the Daqarta Help system:

# Macro Array Frequency Counting

To obtain the frequency X of a waveform in BufN, use the form X=BufN?F.

This uses the same general methods as the main Daqarta Frequency Counter, but applied only to data in the specified buffer. Unlike the main Frequency Counter, the buffer must contain at least one full cycle of a waveform, so it can't measure frequencies lower than 1/1024 of the sample rate, or 46.875 Hz for the default 48000 Hz rate.

However, also unlike the main counter, it is not tied to the main display Trigger operation. This means you can measure the frequencies of multiple channels independently, and none of them needs an active Trigger.

Each buffer uses its own 3 internal trigger parameters to specify the trigger event. These parameters are also used with X=BufN?E and X=BufN?e for Edge/Event (Trigger) Detection.

In the following, parameter value V may be a constant, variable, or expression:

Buf0#s=V sets the Buf0 trigger slope to Positive if V is zero or less, else Negative. (This counter-intuitive scheme is used for compatibility with the main Trigger Slope variable TrigSlope, which is a 2-state button variable with 0 for Pos and 1 for Neg.)

Buf0#t=V sets the Buf0 trigger level to V, where V is typically in the +/-32767 range if you have filled the buffer with 16-bit data by copying from an input or output channel. Zero is a good starting value for ordinary waveforms.

Buf0#h=V sets the Buf0 trigger hysteresis. This is used for noise rejection, just as for the main trigger, but here the values for V are absolute. So for an ordinary +/-32767 waveform, 1638 gives about 5% hysteresis. For a positive slope, this value is subtracted from the trigger level to get the lower threshold that the signal must rise through to arm the trigger. The signal must then pass through the sum of the trigger level plus hysteresis for the trigger event to be accepted.

If you are not sure what settings of these parameters to use for measuring the frequency of a tricky signal on a particular channel, you may want to try using that channel as the main display Trigger Source until you understand what is going on. Make sure the small button next to the Trigger Level control is toggled to '%'. Adjust the main Trigger Slope, Level, and Hysteresis settings for a stable display using only Normal trigger mode, with no Holdoff, then translate the percentages to the +/-32767 range and set the buffer values.

After you obtain the frequency, you can obtain two internal values that were used to compute it. N=Buf0?t sets N to the number of triggers that were encountered. This is one more than the number of cycles of the waveform.

Similarly, S=Buf0?s sets S to the number of samples between the first and last trigger. Note that this is not a simple count; it usually has a fractional part. That's because the actual waveform value at the trigger sample is usually a little past the specified trigger threshold, since it is unlikely that the sampling operation and the waveform are in synchrony. The previous waveform sample is, of course, before the threshold. From these the effective fractional trigger sample is found by simple interpolation.

The reported frequency Buf0?F is computed internally from F=(Buf0?t - 1) / Buf0?s * SmplRate.

The accuracy on a noise-free sine wave is at least 3 decimal places for low frequencies (below about 1000 Hz).

At higher signal frequencies the instantaneous reported frequency may show jitter except at certain integer submultiples of the sample rate (1200, 2000, 2400, etc). You can reduce or eliminate this by averaging multiple values between meter displays. This can be a simple average of N values, with correspondingly infrequent updates. Or you can use a simple "time constant" scheme: See the Meter Time Constants sub-topic under Custom Meter Macros.

Square, Pulse, or other rectangular-wave signals may also result in jitter, even at low frequencies, because there is no slope for interpolation. (This is true for the main Frequency Counter as well.) Simple or time-constant averaging is likewise effective here.

At the very lowest frequencies, where less than 2 cycles appear in the data, there is a possible problem when the buffer trigger point is set the same as the display trigger. The buffer can't respond to the same trigger event as the display, because the trigger operation must be armed by encountering at least one sample on the specified slope prior to the trigger point. That sample is not part of the displayed data unless you set Trigger Delay to a negative value.

Since the buffer only gets the displayed data, if it doesn't get the first trigger and there is only one full waveform cycle in the data, then it only finds the final trigger (start of the following cycle). Without a full cycle it thus reports 0 frequency. The simplest solution is usually to set the buffer trigger level a little higher than the main trigger (assuming positive slope), so the same cycle will be detected a few samples after the main trigger.

If you run with Trigger off, then the low-frequency data set will sometimes contain a full cycle and sometimes not, so the reported frequency will jump back and forth between 0 and the proper value. If this is a common situation in your work, you can use an IF statement to only report non-zero values.

One way to measure very low frequencies is to detect when Buf0?F reports 0 frequency, then use edge detection plus the Posn?D read-only variable to determine the absolute sample position of each trigger event. The frequency can then be computed from the sample distance between triggers and the sample rate. This method is used by the _Multi_Mtr_Task of the Multiple Meters mini-app.

There is nothing to prevent you from using the buffer frequency counter in unorthodox ways. For example, you could count the number of peaks in a magnitude spectrum by careful setting of the trigger parameters. (Since the magnitude spectrum only contains 512 points, you must make sure the upper 512 samples of the buffer are set to 0 ahead of time). You could even measure the "frequency" of a multi-harmonic spectrum, treated as a waveform.