precision sine wave generation
TCP71
Posts: 38
I've been looking through some of the sine wave generation threads and OBX modules, but everyone seems to want faster generation, whereas I am looking for precision. Assuming that I can clock the propeller with perfect precision (using a GPS sync'd frequency generator), I need to be able to produce frequency stable sine waves in the range of 10-100Hz in 10Hz increments. There seem to be multiple different objects that I can use, but my concern is the circuit required at the output pin to create the actual waveform. I really need an output of 0.3Vp-p centered around a ground. Any ideas or help appreciated. I can transformer couple the output if necessary.
Comments
perhaps you could specify a little bit more exactly, what precision you need.
I have used the ROM sine table and pwm-dac, which is "quite stable".
Good luck, Christof
BTW, a transformer that would work at 10 Hz would have to be rather bulky.
-Phil
Thanks. Sorry for the simpleton questions.
http://forums.parallax.com/showthread.php?126254-DAC-Help
with an 18k resistor and 0.01uf cap perhaps.
Precision needs numbers ie- tolerated deviation in uHz or ppm, and tolerated jitter in ns
You only want relatively few points, as 10Hz is quite coarse.
For example, a /N approach, has no cycle-cycle jitter, but has small but stable errors.
A NCO approach, will allow many more frequencies, but can have sub-frequency jitter components.
Errors look to be 250ppb/125ppb/0ppb in the time domain.
In the analog domain, digital power noise will limit 'highest precision' , so you may need an external DAC.
I2S DACs are cheap, and have very low analog noise floors, and are great for Audio-frequencies.
There was talk of an I2S sine option, in an earlier Sine thread.
Not sure where that ended up ?
Using differential DUTY-mode outputs in this fashion automatically gives you an AC signal that straddles ground. It's important to use matched resistors and an op-amp with a very low input offset voltage. You might even consider using an instrumentation amplifier. I would wire it up on a good-quality perf-board with plated through holes and a ground plane. A solderless breadbaord, if my experience today with this circuit is any indication, will permit too much noise to appear on the output.
-Phil
That means the opamp does NOT have to try to cope with 80Mhz digital common mode....
So the new values would be 10K, 10K, and 910R instead of 1K.
-Phil
You really do need to explain what "precise" means to you though in terms like phase-noise, jitter, SNR,
Maybe generate the basic sin wave using the rom table to create the samples for the period you want and feed this to the serial input of a multiplying DAC. For example using the LT8043 in 4 quadrant mode looks like it will be able with a couple of opamps give you a waveform centered about gnd. Currently I am generating a ramp into the DAC input and supplying a signal from an HP function generator (sin/square or triangle/sawtooth) into vref and that was to see if I could make the device control the output amplitude of the output stage, and it gives out a ramp from near 0 to vref. The waveform looks like a ramp made up of whatever is going into the vref input. Currently I am testing this in two quadrant mode with a single supply opamp. With a programable divider, you could probably make the device amplitude and offset fully programmable.
FF
http://forums.parallax.com/showthread.php?140989-Using-counter-modules-to-control-frequency-of-sine-square-or-triangle-wave
with a scan rate of 1.25MHz, it will output one of each of the Sine ROM values, at 152.5878Hz.
The design Auto-adjusts how it handles Sine lookup - at higher Fo, it skips some values in the Sine ROM, and below ~152Hz, it will output the same value more than once, on some samples, which also gives more time for the DAC to average over.
For best precision, an external DAC would be used, as the PWM/PDM DAC needs 2^N clocks to average over.
(at that 152Hz example, and an update per scan loop, there are just 64 clocks per DAC change, so only 6 bits of Y axis precision.
Compare that with a I2S DAC, which can give > 20 bits in Y axis, at an assumed 192KHz sample rates.
So taking that example of 152Hz, you would drop X axis steps from 8192 to around 1263 per whole cycle, but gain a lot in Y axis, so a I2S system could expect to have better Zero-crossing precision.
If you only want sub 100Hz a reasonably aggressive low pass, (ie not much above 100Hz ) would bring more sample-points into the averaged output.
http://www.sercel.com/Products/land/systems/428XL.php
The phase variable repesents 0 .. 2pi, so the top bits index the sine table (hence the shift to get the right bits). The frequency variable is the phase increment to add every output-sample period. If you were generating 100Hz waveform using a sample-rate of 44.1kHz then the frequency variable needs to be 2^32 * 100 / 44100 = 9739155 (0.0000089 % error) and a unit change in frequency variable is about 10.3 micro Hz!!
The output could be done with a DAC or a cog doing PWM, or whatever. You wanted 0.3V p-to-p so a resistive divider and a blocking capacitor could be used to reduce the output (you'll need to know the input impedance of the 428XL).
-Phil
The code linked to here, should work out of the box
http://forums.parallax.com/showthread.php?140989-Using-counter-modules-to-control-frequency-of-sine-square-or-triangle-wave&p=1107683&viewfull=1#post1107683
and a recorded sine wave would allow the more accurate post-processing.
(you can also derive a distortion value using this too )
A square wave has information only in the samples right at the edges, whilst a sine wave record can be fitted to many points.
The loop-rate of the code above is 1.25MHz, so has 800ns time quanta, but the sine 'position', is good to 12.5ns on average (because that is the adder-rate).
Given the average analog trigger circuit struggles to get above 15-16 bits, you should be fine.
This is frequently done in audio, so as long as the input impedance is reasonably high, a few mF is enough.
As you can see, I'm trying to create two frequencies out of the same propeller (on different cogs simultaneously) . Is this possible? The code as above only puts out the signal on the Pin 3 and 14 no longer works. Thanks for any input.
-Phil