Some Code Taqoz 2.8 with inline PASM. DDS Sine Generator. ADC Sampling. Goertzel Analysis. (VGA)
Hi,
while my project will be rather specific and not of interest for too many others, perhaps some of the code routines might be helpful. I post the code as is, the project is not finished.
(My project outputs a sine signal of known frequency and amplitude to a Guitar sound effect. The output from it is sampled and analysed for amplitude and 2nd and 3rd harmonic distortion. This project has benefit using P2 instead of an other controller: Use cores without timing problems from interrupts. VGA output with enough Ram for fast graphics. Hi resolution DAC/PWM output. Programmable Gain adc input. )
There is:
1. Direct Digital Synthesis DDS Sine Generator. It generates the sine wave using cordic without a buffer and running in a separate cog. Amplitude and frequency can be changed on the fly over global variables. Versions in Forth, Hub assembler and cog LOADMOD assembler.
2. ADC sampling -one pin- into a buffer. Setting the gain factor. Sinc2 sampling, Sinc2 filter, Sinc3 filter. Hub Pasm and Forth code. (It turned out, that for my purpose Sinc2 sample mode is best suited as the other modes do not provide more than ENOB=12,4.) Forth is fast enough for 12 bit sampling.
3. Goertzel frequency analysis. This algorithm does the same as FFT but only for one frequency. So if you do only need to look for specific frequencies, this is faster and simpler. There is code in Forth and assembler. The most difficult part (for me) is the scaling. You don't want to loose precision and you have to make sure that there is no overflow, as the data adds up. In Pasm there is a signed 32bit16.16bit scaled multiply with 32bit result. The Pasm code is about 9 times faster than Forth.
4. In addition some VGA (Standard 640360, 8bit color) output is used, not pretty, but it was helpful to debug.
The picture shows best case of signal to noise analysing the DDS output directly with gain=1. Vertical axis is magnitude.
If there are ideas, how to scale the Goertzel data in a way, that mul16 can be used and still have full 12bit resolution....
Have fun, Christof
Comments
An impressive piece of code. A pleasure to read and nicely commented. I can definitely see it getting its good use.
Thanks for sharing.
BTW, I spent a few hours yesterday playing with Tachyon just to make some simple led blinking patterns. Lots of fun resulted in less than twenty lines of not at all optimal, but working code too trivial to post anywhere
If you mean the code in goeLoopAsm then:
or with scas:
With SCAS the coefficient must be half the value, because the scale range goes from -2.0 to +2.0 (-1 LSB)
Updated the zip file in 1st post. In previous code only the real component of goertzel was calculated. Now both real and imag are taken into account. Much better.
Thank you, Ariba!
The problem is, that the value in c is growing with the number of samples. So for c at the moment more than 16 bits are needed. At the end in the Forth code the result is divided by the buffer length. It is this code in micropython (from: https://forum.micropython.org/viewtopic.php?t=7290 last post ):