[IDEA] Atmega32U4 DDS with digital amplitude control - Page 1
Forum section: electronics / general

author: Sigmoid
author_rank: Frequent Contributor
timestamp: July 28, 2016, 09:31:19 am
content: Hey,I have an idea and want to ask some people around here if it sounds good or is complete bollocks.So the Atmega family used in Arduinos is admittedly not a prime choice for signal synthesis, but hey, I have some lying around. I have found some blogs detailing how to implement DDS on an Atmega, and I was thinking that a (low frequency) function generator shield based on the PWM outputs might be a cool thing to make.That said, having an 8 bit resolution is bad enough, and if I wanted to be able to scale the waveform, I'd end up with 2 or 3-bit waveforms, which sounds pretty sad.So what I noticed is that the Atmega32U4 used in the Leonardo and compatible boards gives you the ability to set the multiplied USB clock as the clock of one of the PWM outputs. This allows for having a 250kHz PWM output((96MHz/1.5)/256). Which is exactly 256 times the frequency of the default PWM frequency on Arduinos, 976.6Hz. So for each "timer step" for the slow PWM pins, I have a full PWM period on the fast pin.So my idea is to generate a full-scale signal on a "slow" pin, and a multiplier on the fast pin 4. Take these two signals, and feed them into a fast AND gate... and the result should be, after a Chebyshev low pass filter, a signal scaled to the desired amplitude. Yes, it only goes up to 488Hz.It sounds like a cheap and simple solution, without the need for multiplying DACs (or any kind of external DAC), it doesn't reduce resolution and doesn't need a recalculation of the waveform lookup table, etc. I'm wondering if there's something wrong with it I might be overlooking - or if there is a better solution without using external DACs that would provide higher frequencies AND precise scaling, that I'm not aware of.

author: MosherIV
author_rank: Super Contributor
timestamp: July 28, 2016, 09:49:03 am
content: Any signal generated from PWM iis going to be pretty noisey and jittery.You would better off using the DAC method and doing some kind of amplitude multiplier before outputting to the DAC.I suspect this will be very non linear as the amplitude gets small/near 0V

author: Sigmoid
author_rank: Frequent Contributor
timestamp: July 28, 2016, 10:05:21 am
content: These guys did a really good job here, the signal looks kinda nice:http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-dds-sinewave-generator/I guess I'll protoboard it and post some oscilloscope screenshots if it's worth anything.

author: dannyf
author_rank: Super Contributor
timestamp: July 28, 2016, 10:49:41 am
content: QuoteSounds far more complicated than to just recalculate the look-up table.FYI, On a ATtiny85, I can get a few Khz of output, depending on the look-up table used.

author: bktemp
author_rank: Super Contributor
timestamp: July 28, 2016, 12:17:57 pm
content: Quote from: Sigmoid on July 28, 2016, 10:05:21 amTo me it looks like typical arduino code, bodged together by somebody who does not really know what he is doing:Every second the DDS code gets disable to calculate a new frequency using floating point. The waveform must be really ugly with the quite large gap (my guess >10ms) every second. This behavior can easily be avoid by doing the calculations while the interrupt is running and only switching the interrupt off for the very short time the value actually gets updated.I would use an audio DAC: It does not only support high sample rates (typically up to 100kS/s), but it also has at 16bits and has a build in oversampling filter, avoiding the complex low pass filter and giving almost samplerate/2 useable output range. And many audio dacs also have a build in volume control if 0.5 or 1dB steps are good enough. You can use SPI to write the data to the DAC. Since most audio codecs are stereo, you have two channels, so you can create two waveforms having the same frequency with a phase shift or even being completely independent.But I wouldn't use an AVR, because writing 32bits using SPI takes some time and it is hard to to anything useful in the meantime between writing the 4 bytes. So I would recommend using a controller with either a dedicated audio codec interface, or having at least an SPI with a FIFO where you can put all the data at once.

author: Brutte
author_rank: Frequent Contributor
timestamp: July 28, 2016, 01:01:56 pm
content: Quote from: Sigmoid on July 28, 2016, 09:31:19 amGet yourself STM32F103 lying around. $1.5/pop. $2.5 for eval. With shipping.These have two independent 12-bit DACs, 1Msps each. IIRC there is a DDS demo from ST.Give away your ATMegas to your enemies