Using counter modules to control frequency of sine, square, or triangle wave
Mad A
Posts: 17
I am building a function generator with my propeller. So far I can generate the basic square, sine and triangle waves. On the sin wave, I can only achieve a speed of about 5 KHz because I am reading from the sin table in main memory every sample. So I was thinking of reading one cycle of the sine wave into cog memory and then using a counter module to control writing the samples to the output pins (which are connected to an 8 bit DAC) faster. I am not certain how to do this. Also I eventually want to add knobs to control frequency and maybe amplitude....
Comments
http://forums.parallax.com/showthread.php?140927-Propeller-Signal-Generator
LOL @ this thread being like #1 or #2 on the forum right now
How much faster do you actually need, and at what precision ? (Frequency step size and distortion )
I see you also have this thread :
http://forums.parallax.com/showthread.php?140784-Sine-wave-generator
Sine generation has two dimensions, and you can choose to work in either.
You can use low precision Y axis, and try to compensate for that with more samples in X, or a higher precision Y axis, allows less samples in X.
As I mentioned in the other thread, fast polling a NCO gives the best natural scaling, and you then choose a DAC.
The Sine ROM gives 16 bit sine values, so an obvious step is to feed an external i2s DAC, which can run to 192KHz Stereo 16/24/32bit update rates.
This means 19.2 sample points in a 10KHz sine, and 192 sample points in a 1KHz sine, but those points are precisely placed in X & Y, so filtering gives low distortion sine results.
Parallel DACs could give more bandwidth, but using more pins, and at higher prices (outside the high volume areas)
Edit : I see Beau has posted an exact example of fast NCO polling, using the Prop 'Duty' mode DAC.
I think PhiPi found the Prop 'Duty' Mode DAC limit was ~12-13 bits (ignoring crosstalk effects).
So below 5-10KHz, using an external i2s DAC could be expected to give much better numbers, in distortion.
Above 20-30KHz the i2s DAC will 'run out of steam' with limited samples per sine.
Frequency Granularity is the same, independent of DAC choice, I make that 18.6 milli hertz.
There is a trade off in the XY points : At the 30KHz reference point Beau mentioned, you have 41.66 updates/full cycle, and around a 6 bit DAC equivalent.
At that speed, an i2s DAC still delivers >> 16 bit Y axis, but has dropped to 6.4 updates/full cycle
If using I2S with a sample rate of 96kHz then a 32 bit frequency / phase register setup gives a frequency increment of 22.35 micro Hz... The 18.6 milli Hz figure applies to one sample per system clock (which is unlikely for a sine-table lookup). Make the registers 64 bit then the frequency precision is greater than you will ever need!
True, but then you have flipped from a Hardware adder, to a software one.
I guess at 96/192KHz that is do-able, if i2s from clocked-video is practical.
The sine table is only 16b, which will limit how usable that 22.34uHz is, but there may be time for linear interpolate, to push that Y axis precision higher ?
Going by the small code size of these loops, there is room to give a user choice of all of these in 1 COG
** NCO square wave
** Prop DAC Loop Sawtooth/triangle/square
** Sine LUT Loop, i2s Stereo DAC, HW adder
** Sine LUT Loop, i2s Stereo DAC, SW adder, (possible extended precision Y ?).
Edit : In case anyone is wondering why 18.6mHz vs 22.35uHz is even being discussed, more precision is always good, especially on test systems
Some real examples where 18.6mHz might be coarse, are testing crystals, and Physics experiments where you might select two very close frequencies to give a constant slow phase advance in multi-resonant systems. (18.6mHz is 56 seconds for full phase move.)