In PteroDAQ frequency channels, I wrote
One of the clocks is out of spec. When the FG085 was putting out a nominal 500kHz signal, the PteroDAQ system measured it at 499958.5 Hz, which is –83ppm. The two crystals should each be about ±20ppm, so an 83ppm discrepancy is larger than expected. With a nominal 5kHZ signal, the PteroDAQ system measured it at 4999.524 Hz (–95ppm). I’ll have to take the function generator and PteroDAQ board into the circuits lab and use the frequency counters and function generators there to see what the actual accuracies are. For anything that we do in the applied electronics class, 100ppm is good enough, but it would be nice to know how far off my instruments really are.
Today I took all three of my PteroDAQ boards (Teensy 3.1, Teensy LC, and FRDM-KL25Z) and my JYEtech FG085 function generator into the circuits lab, to compare the measurements made with the PteroDAQ to measurements made with the bench equipment in the lab. I also used the function generator in the lab to get higher frequencies with less jitter, to see if that made a difference in the measurement.
The bench instruments I was using were
- Agilent 34401A multimeter
- Leader LDC822 frequency counter
- Tektronix MSO 2024 digital storage oscilloscope
- Agilent 33120A arbitrary function generator
Some general observations:
- The Agilent 33120A multimeter provided the highest precision on the measurements, but failed at 1MHz.
- The multimeter also had some trouble with pulse trains with a lot of jitter, such as those produced by the FG085.
- The oscilloscope routine reports the frequency for the inputs, but also has a “frequency” option on the measurement menu. The routine report seems to be stable and precise, while the “measurement” option fluctuated a lot—perhaps tracking the jitter in the signal.
The Leader frequency counter and the Agilent function generator agreed pretty well on frequencies, with the Leader counter reporting that the function generator was about 0.3–0.5ppm lower than it claimed to be. The oscilloscope had less precision, and reported the Agilent function generator as 3–5ppm high. The multimeter reported the function generator as 1.4–1.6ppm high.
I’m interested in the PteroDAQ measurements relative to any of the bench instruments. Here is a table of the ppm error for several frequencies (f_s is the sampling frequency for PteroDAQ looking at the frequency channel):
33120A setting | Teensy 3.1 | FRDM-KL25Z | Teensy LC | ||||||
---|---|---|---|---|---|---|---|---|---|
MHz | /33120A | /Leader | f_s | /33120A | /Leader | f_s | /33120A | /Leader | f_s |
0.5 | 11.2 | 11.6 | 20 Hz | 27.4 | 27.8 | 1 Hz | -24 | -21.6 | 1 Hz |
0.9 | 11.556 | 11.889 | 30 Hz | 27.444 | 27.778 | 1 Hz | -23.889 | -23.556 | 1 Hz |
1.0 | 9. | 9.3 | 31 Hz | 27 | 27.5 | 1 Hz | -23.7 | -23.5 | 1 Hz |
2.0 | -23. | -22.5 | 62 Hz | 26.5 | 27 | 2 Hz | -25 | -25 | 2 Hz |
3.0 | -59.667 | -59 | 100 Hz | 25.333 | 26 | 3 Hz | -25.333 | -25 | 3 Hz |
3.9 | 24.359 | 24.872 | 4 Hz | -27.179 | -26.923 | 4 Hz | |||
4.0 | -87.75 | -87.25 | 125 Hz | -1660.8 | -1660.3 | 4 Hz | -2059.5 | -2059.3 | 4 Hz |
4.5 | -1777.555 | -1774.667 | 140 Hz | ||||||
avg | -23.11 | -22.66 | 26.339 | 26.825 | -24.85 | -23.263 |
The entries in red show the frequency counter failing by not counting all the edges—when the DMA channel can’t keep up, it silently ignores edges (not a great failure mode, since the numbers may look plausible while being several percent off). I did not include the red numbers in the average.
The KL25 and KL26 processors (FRDM-KL25Z and Teensy LC) both have fairly sharp transitions between counting every edge (at 3.9MHz) and missing many (at 4MHz). The K20 (Teensy 3.1) has stranger behavior, where it overestimates low frequencies and underestimates high frequencies. There error a 3MHz is already fairly large. I suspect that the problem may result from the shorter counter in the K20, which necessitated counting for shorter periods at high frequencies to avoid overflow. There is a brief dead time at each period while the DMA counter is reset.
If there is a dead time of duration , during which the first pulse is counted (captured by the port circuitry), but subsequent pulses in the dead time are missed, then the relative errors should be
where
is the sampling frequency and
is the frequency being measured. Note that
is an estimate of how many pulses arrive during one dead time. If this is 1 or less, then no pulses are missed, otherwise only one of the arriving pulses is counted.
If the dead time for the Teensy 3.1 is about 900ns, then the errors should be about 0,0,0, -25, -57, and -81 for 0.5MHz, 0.9MHz, 1MHz, 2MHz, 3MHz, and 4MHz, consistent with the observed pattern. With the longer counters and so lower sampling frequencies on the other two boards, I expect errors of about 0,0,0,-1,-2,-3 ppm for a 1µs dead time, which is also consistent with the pattern of errors observed.
I could compensate for the error in PteroDAQ (on the host), by adding to
. The small initial error in
makes an insignificant change to
. I will have to get a better estimate of the dead time than 900ns and 1µs, though, perhaps by counting instruction cycles for the compiled code between disabling and re-enabling the DMAMUX. (Incidentally, do you have any idea how hard it is for a bioinformatician to type “DMA” instead of “DNA”?)
The ±27ppm error for the FRDM-KL25Z and Teensy LC boards seems fairly typical for a cheap crystal oscillator (which is usually ±30ppm). Those errors are much larger than the <2ppm differences between the bench instruments, so it really doesn’t matter which of the bench instruments we treat as the “standard”.
What about the FG085 function generator? What is the ppm error on it?
FG085 setting | 34401A DMM |
Leader LDC822 counter |
---|---|---|
30Hz | -23.667 to -121 | 0 |
3kHz | -88.333 | -100 |
30kHz | -58.667 | -63.333 |
327kHz | -55.352 | -58.716 |
600kHz | -103.33 | -58.500 |
999kHz | -58.158 | |
avg | -76.4 | -56.45 |
The multimeter had some difficult producing consistent reading when there was a lot of jitter in the signal. The frequency counter was more consistent, indicating that the JYEtech FG085 function generator was running about 57ppm slow, which is well outside the normal crystal frequency range. The cheapest crystals are ±30ppm, and ±20ppm often doesn’t cost any more. (There are ±50ppm crystals, but you have to go out of your way to find them, and they aren’t any cheaper.)
There are several possibilities:
- an error in the way the firmware for the FG085 sets up the frequencies,
- I picked particularly bad frequencies to test at, or
- the crystals are unusually bad.
The FG085 uses a 24-bit phase oscillator with a 2.5MHz clock (except for frequencies below 40Hz, where it uses a 10kHz clock), so the worst case rounding should be for 3kHz, with a phase increment of 20133 instead of 20132.659, making the frequency 17ppm too high. If they truncated instead of rounding, then the frequency would be 32.7ppm low. At 30kHz, truncation error would be only 3ppm, though, so this does not explain the consistently high errors. I think that bad crystals are the simplest explanation—it is certainly consistent with the super-cheap (and bad) design of their DAC (see FG085 function generator bugs).
I’m a little disappointed with FG085 function generator, since for about 50¢ more, they could have made a much better instrument (using a resistor-ladder chip instead of discrete, unmatched resistors; using a ±20ppm crystal; drilling large enough holes in the top so that the buttons didn’t stick).