You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think that line 219 of genericUsbDriver.cpp should be changed from return CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq);
to return CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq) - 0.5;
As I understand it, CPS = CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq) is the appropriate number of clock cycles per waveform sample. Also, it looks like the PER setting of the waveform generating timer is set to the value returned on line 219, which is (int) CPS in the current code. But, the formula at the top of page 173 of the xmega-au manual indicates that the timer triggers every (PER + 1) clock cycles. This means that PER should be set to CPS-1 if CPS is an integer. If CPS is not an integer, adding 0.5 to the result before returning it produces a PER = (int) (CPS - 0.5) that is rounded instead of truncated to the nearest integer.
The attached plots show the power spectra of nominally 5 khz sin waveforms generated by the Labrador both before (PER = 75) and after (PER = 74) the change to line 219 is made. Before the change, the power spectrum peaks at 4,935 Hz, which corresponds to 76 clock cycles per waveform sample. After the change, it properly peaks at 5,000 Hz, which corresponds to 75 clock cycles per waveform sample.
Before change:
After change:
The text was updated successfully, but these errors were encountered:
Thanks so much for the write up. I've had a few messages about slightly off frequencies, but have always come to the conclusion that it was just quantisation error (which, I suppose some of it is, but still).
I've committed the fix and it should upstream soon.
No problem at all. I'm glad I could make some small contribution to the device. I think this also explains why the spectrum mode waveform breaks (#241) showed up for a nominally 1 khz signal. Because the signal was actually 48e6 / (128 * 376) = 997.34 Hz, a phase difference ( [ 3 * 33 * (0.001 s) * (997.34 Hz)] mod 1 = 0.74 periods ) built up over the 3 missing frames.
I think that line 219 of genericUsbDriver.cpp should be changed from
return CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq);
to
return CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq) - 0.5;
As I understand it,
CPS = CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq)
is the appropriate number of clock cycles per waveform sample. Also, it looks like thePER
setting of the waveform generating timer is set to the value returned on line 219, which is(int) CPS
in the current code. But, the formula at the top of page 173 of the xmega-au manual indicates that the timer triggers every(PER + 1)
clock cycles. This means thatPER
should be set toCPS-1
ifCPS
is an integer. IfCPS
is not an integer, adding 0.5 to the result before returning it produces aPER = (int) (CPS - 0.5)
that is rounded instead of truncated to the nearest integer.The attached plots show the power spectra of nominally 5 khz sin waveforms generated by the Labrador both before (
PER = 75
) and after (PER = 74
) the change to line 219 is made. Before the change, the power spectrum peaks at 4,935 Hz, which corresponds to 76 clock cycles per waveform sample. After the change, it properly peaks at 5,000 Hz, which corresponds to 75 clock cycles per waveform sample.Before change:
After change:
The text was updated successfully, but these errors were encountered: