0.3 to 1.6KHz sinewave generator: DDS IC or PWM?

Go To Last Post
50 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I need to come up with a sine wave generator from 300Hz to 1,600Hz (100Hz steps) mainly for short beeps alerts. I see many suggesting buying DAC IC's but imports in my country are complex, time consuming and almost always taxed at 60%. Based on requiriments below, do you think I can get away using an atmega64a's PWM?
 

* I don't need to be very precise. 995Hz to 1.005Hz is good enough as 1.000Hz to me.
* Stability is not so important since nobody will notice if the frequency changes little with each alert which are occasional.
* Amplitude should not change too much. Let's say no more than 10%. 
* Spectrum purity is desirable because it will be transmitted over the air (FM).
 

My first try was a square wave oscillator and converting to sinewave with RC filters. But there ate too many harmonics and it will take many extra components to clean. Looks like there is ways to generate relatively clean sinewaves with PWM. 

I would much appreciate suggestions and even better codes examples. 

[]s
JR

Good Soldering JRGandara

Last Edited: Sun. May 30, 2021 - 11:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A simple R-2R resistor ladder and some filtering should work well, some people prefer PWM of course.

 

If you use Xmegas then they have DACs built in. I have such a setup for one of my boards but I have only 2 frequencies to generate so I have added a 2 channel analog switch to change the filter caps according to the frequency required.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your headline says DDS IC but the body says DAC  IC ? 

 

You should be able to generate a modulated PWM sine ok.

You still need filters, but they start from a much higher and fixed rejection frequency - eg 16Mhz /256 PWM is 62.5kHz which is well above your 1600Hz, so it's much easier to filter.

 

What else is your AVR doing ? You might be able to run the DDS based on PWM interrupt, running at eg 62.5kHz 

 

You need need to decide how many entries in your Sine table.

 16M/256/1600 ~= 39 points per sine 

 16M/256/300   ~= 208 points per sine

ie you do not need a table larger than 208 bytes, but for code simplicity you might code as a 256 byte table, index from the high byte of the 16b adder.

At 1600Hz DDS picks a varying 39 sparse points from that table, for every sine cycle. 

 

You need only a 16 bit adder in your DDS, which is faster to code.

your step choices are then 

 

 62500/(2^16/315) = 300.407Hz

 62500/(2^16/316) = 301.361Hz

 62500/(2^16/1678) = 1600.265Hz
 62500/(2^16/1679)  = 1601.219Hz

 Step size is  0.953 Hz, or ~100x finer than your 100Hz you need, or ~5x finer than your 5Hz resolution spec at 1kHz 
 

Suggested example template is jespers DDS  :   

https://www.avrfreaks.net/commen...

and a discussion of variants is here - says that DDS uses a 24b adder, and runs 'flat out', so has a much finer resolution than you need.

https://www.avrfreaks.net/commen...

 

Your specs can be met with a PWM based interrupt, so the adder fires every 256 clocks. jespers design needs 9 clocks for a 24b adder and lookup, plus call/ret overheads.

 

 

 

 

Last Edited: Mon. May 31, 2021 - 12:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:

...If you use Xmegas then they have DACs built in. ...

 

Yes, and more MCUs are adding DAC's these days.

The Tiny212 and up have 8b DAC, and dsPIC33 have 12b. as do XMEGAs - all of those are a overkill by miles for the OP's modest 300~1600Hz tone task 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have lots of options, especially since 1.6 KHz is a pretty low frequency for a (relatively fast uC).

 

You can likely, as mentioned above, just use interrupts and a lookup table for such low frequencies.

A DDS is certainly a great option.

There should be plenty of DDS examples in whatever language you wish to use.

 

Recall that with a DDS the goal, generally, is to have a very high interrupt  rate.

The DDS takes care of repeating samples if you have a very low frequency and a very high interrupt rate.

There is, however, a point of diminishing marginal returns on the actual ISR rate.

There is overhead for each time the ISR is called, and as the % of uC processing time within the ISR increases, the amount of processing time for the Main Loop decreases.

This is obvious, once you think about it.

 

If you use a software DDS, then once you select your ISR rate that is fixed, and it doesn't change depending upon the frequency you wish to generate.

The DDS SW selects the lookup tables values, (skipping over them as needed), based upon the ISR rate, to generate the desired output frequency.

 

If you use a simple ISR and lookup table, then the ISR rate, reading sequential lookup table samples, needs to vary depending upon the output frequency needed.

If you know the exact frequencies, from 300 to 1.6 KHz, that you need, and the clock frequency of the uC, you can calculate the Timer/Counter Pre-Scaler and the ISR rate, and see if you can hit the needed frequencies with adequate accuracy.

 

With the DDS you (usually) have pretty fine frequency control, and none of the above matters.

 

Unless you are only needing 2 or 3 frequencies, I would think the SW DDS approach would be easier.

 

Next:  There are lots of discussions on optimizing the DDS ISR and the lookup table access. 

Optimizing DDS code for speed is one of those programming challenges that many individuals like to tackle.

I'd suggest, however, that at the low frequencies you need, that just doesn't matter.

Your goal should be to get it up and running, you can worry about optimizing it down the road, if needed.

 

Regardless of whether you use a SW DDS or a simple ISR & Look-up table, you end up with a number, (8-Bit, 10-Bit, 12-Bit, whatever...)

Your hardware needs to convert that to an analog voltage.

 

A DAC, either as a module built into the uC, (e.g. Xmega chips, and perhaps some of the newer Microchip AVRs), or a stand-alone DAC chip, make that easy.

If you elect to use an R-2R resistor ladder, then know that the resistors need to be very closely matches for good results, and you need a lot of I/O pins to drive it.

That approach, therefore, is doable, but is often a pretty big hassle if you can get your hands on a real DAC.

 

Regardless of whether you use a DAC or an R-2R ladder, or a PWM, you need to feed the resultant signal into a Low Pass Filter to get a clean output waveform, (with minimal harmonics).

You therefore NEED a an op-amp configured as a LPF for the output.

You can use a couple of simple RC filters, with "voltage follower" (buffer) op-amps between filter stages, as the simplest approach.

You can Google Sallen-Key LPF for a second order LPF per each op-amp, (compared to the first order LPF using the simple RC and buffer approach, above).

There are on-line calculators that will give you the R values for a given C and cutoff frequency.

 

When you wish to generate analog signals, and work with op-amps, having an O'scope, (even a cheap "toy" O'socpe for your frequencies of interest), is extremely important.

 

One truly needs to be able to see the signal as it goes through the various processing stages, and the impact upon the signal of various ISR rates, etc.

 

Good luck with your project.

 

JC

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would look up Jesper's mini DDS.  There's also a similar C /asm  6 bit version that might be interesting . 

 

https://codeandlife.com/2012/03/13/fast-dds-with-atmega88/

 

Good luck!

 

P.S. : If I'm not mistaken the output of the lookup table can be plugged into the timer compare to have a PWM output.  

Last Edited: Mon. May 31, 2021 - 01:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Never looked at xmega family and, for my  surprise, the prices looks about the same. Very interesting for future projects. Now I'm stuck with the atmega64a for this project.

Thank you for your suggestions!

Good Soldering JRGandara

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Never looked at xmega family and, for my  surprise, the prices looks about the same.

But the chips are NOT the same, so you will have a bit of a learning curve before you use them. But once you get used to them they are great.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My fault! I mean DAC.

I have nothing too demanding for this AVR. By now I'm only using a 1KHz interrupt for some tasks. Your suggestions and links were of great value. I already have a 2KHz low pass filter in the circuit. Thank you!

JR

Good Soldering JRGandara

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PLL is an alternative to some DDS (PLL = VCO + counter + phase detector)

Some PIC have a NCO peripheral.

gandara wrote:
... but imports in my country are complex, time consuming and almost always taxed at 60%.
Including HC digital logic?

Reason : PLL by HC

Hopefully, the tax is reduced for mature integrated circuits.

gandara wrote:
My first try was a square wave oscillator and converting to sinewave with RC filters. But there ate too many harmonics and it will take many extra components to clean.
Better filters by op amps; probably one jelly bean op amp is enough.

 


The Art of Electronics 3rd Edition | by Horowitz and Hill

Download a sample chapter

[lower left of page 13]

...

7.1.5 Sinewave oscillators 435

...

7.1.8 Frequency synthesis: DDS and PLL 451

...

MF10-N Universal Monolithic Dual Switched Capacitor Filter | TI.com due to AoE Figure 7.45 (page 454, quadrature sine wave generator, add a comparator)

 

NCO: Numerically Controlled Oscillator - Developer Help

 

Digital Audio Sinewave Generator, a project draft | AVR Freaks

 

edit :

https://www.mouser.com/Semiconductors/Active-Filters/_/N-6owy7?Keyword=capacitor&Ns=Pricing|0

Analog Filters - Maxim Integrated

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Mon. May 31, 2021 - 12:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

Last Edited: Mon. May 31, 2021 - 12:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using C language. I did not mention but those beeps will never exceed maybe 200ms in duration. So I will beep once in a while a very short beep. Looks like SW DDS is the way to go. By now I'm only using an IRS @ 1KHz but I could increase or decrease this frequency without problem. Ladder and resistors would need ports that I don't have available at this point.  So it is not an option. I already have a very good second order LPF in the circuit which I can use for this matter. So the main challenge is to make this DDS work. I never deal with this subject before and all those information you show help a lot. I have a very good scope in hands which serve me well testing the filters. Thank you!

Good Soldering JRGandara

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How about a Johnson counter?  Lots of references around (even in AofE book).

Here's one: https://www.tinaja.com/glib/rad_...  (see option #4 on page #61).

And here: https://electronics.stackexchang...

 

Use two outputs from one AVR timer to get a three-level sine-wave approximation.

 

 

Mike

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:
Recall that with a DDS the goal, generally, is to have a very high interrupt  rate.
or DMA (XMEGA AVR, late model PIC)

XMEGA peripheral application notes mention DMA if the peripheral connects to the DMAC.

DocJC wrote:
(compared to the first order LPF using the simple RC and buffer approach, above).
First-order filters are sometimes inadequate for AAF (anti-aliasing filter, ADC, DAC); MFB (multiple feedback) is one of the second-order filters.

DocJC wrote:
(even a cheap "toy" O'socpe for your frequencies of interest)
For only an order-of-magnitude greater price are the analog oscilloscopes of "golden" days; some of those have enough bandwidth for AVR.

Analog oscilloscopes can be repaired along with calibration that's local or regional (third party)

Step up another order-of-magnitude for today's excellent digital oscilloscopes.

 


Design Methodology for MFB Filters in ADC Interface Applications (Texas Instruments)

[page 2]

Figure 1. MFB Filter Topology

This design is an inverting signal path, 2nd-order, low-pass filter that offers numerous advantages over Sallen-Key filters. ...

 

Veritas ex machina | Videos/Digital Show and Tell - XiphWiki

2246 Service Manual | Tektronix

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note that you can form some simple calculations for forming the sinewave.  However, you still need to spit out xxx points/sec, so it is not a speed saver (in fact, calc a point is more work than just a lookup).  It is mostly a way to avoid a large table, say you were trying to do really fine steps at high DAC resolution (thus needing to store a lot of bits).

 

https://www.eetimes.com/microcon...

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gandara wrote:
do you think I can get away using an atmega64a's PWM?

Yes, let me see. Wait. What frequency your atmega64a is running at? 16MHz?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes , you can likely use PWM, especially since you don't need high CD-quality

here is a very thorugh article

 

https://www.engineersgarage.com/...

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Got it working. Accurate frequency from 300Hz to 1,600Hz with (100Hz steps)

 

Here is the code for atmega328p running at 16MHz, it uses 16bit (timer 1) and PB2 pin as the PWM pin.

 

uint16_t hz_table[15] = {

    0,		// Turn off
    3333,	// 300hz
    2500,	// 400hz
    2000,	// 500hz
    1666,	// 600hz
    1428,	// 700hz
    1250,	// 800hz
    1111,	// 900hz
    1000,	// 1000hz
    909,	// 1100hz
    833,	// 1200hz
    769,	// 1300hz
    714,	// 1400hz
    666,	// 1500hz
    625		// 1600hz
};

void change_freq(uint8_t x)
{
    if(x)
    {
        DDRB &= ~(1 << PB2);
        ICR1 = hz_table[x];
        OCR1B = hz_table[x]/2;
        DDRB |= (1 << PB2);
    }
    else
    {
        DDRB &= ~(1 << PB2);
    }
}

int main(void)
{
    DDRB |= (1 << PB2);

    TCCR1A |= (1 << COM1B1);
    TCCR1B |= (1 << WGM13) | (1 << CS11);

    change_freq(1);

    while (1)
    {
    }
}

Pass value from 1 to 14 to change_freq function to get your desired frequency, pass 0 to turn it off.

 

Add appropriate filters to get sinewave.

Last Edited: Mon. May 31, 2021 - 08:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

gandara wrote:
* Spectrum purity is desirable because it will be transmitted over the air (FM).

Isn't that the six-million-dollar question ?

 

Aiming for a perfect sine at the input may be overkill. Your existing design with some tweaks may well be good enough.

Introducing some soft clipping to round off the square edges could help.

Narrow band FM; will itself filter out any higher harmonics.

Broadcasting type wide band type FM; less so; but still limited to audio frequencies.

 

PS: Did you consider DTMF ?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gandara wrote:
My first try was a square wave oscillator and converting to sinewave with RC filters. But there ate too many harmonics

How about showing the circuit you used, and the results you got?

 

for short beeps alerts

Surely, if it's just beeps, a simple RC filter should be sufficient?

 

it will be transmitted over the air

Tell some more about this.

 

Do you actually need to transmit the actual beeps, or could you just send some code for the far end to generate appropriate beeps?
(this is how mobile phones do DTMF).

 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Heisen wrote:
Add appropriate filters to get sinewave.

 

It's not that easy, the range is 300Hz to 1,600Hz so a filter that lets 1600Hz through will also not filter 3rd and 5th harmonic of 300Hz.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I remember seeing this Magic Sinewave stuff some years ago...Perhaps  worth a glance...I have no study of it to say one way or another if it would be even the least bit useful here (or anywhere!).

https://www.tinaja.com/glib/msin...

 

https://www.tinaja.com/glib/msin...

 

"Magic sinewaves" are repeating long sequences of ones and zeros.
They can get created from ordinary but extremely carefully chosen digitally switched pulses. Digital sinewaves with precisely controlled amplitudes and amazingly
low distortions. Compared to traditional PWM, magic sinewaves can offer far higher efficiencies and lower distortions. With circuitry that is elegantly simple and microcontroller friendly.

For use in such applications as induction motor speed controls, electric autos, solar panels, power factor correction, inverters, home energy
efficiency improvers, 400 Hz avionics, UPS, PFC, and special utilities. The newest steplocked versions of magic sinewaves let you force any
desired number of low harmonics precisely to zero in theory and to astonishingly low levels in practice. While allowing you to do so at the
highest possible efficiency. By using the fewest switching events.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. May 31, 2021 - 10:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


That's very interesting. So you can kill low harmonics with careful placement of pulse edges, and the harmonic power is shifted to very high harmonics that can be filtered easily.

Very clever.

 

edit: of course the method to generate sinewaves with PWM is well known

 

 

but it never occurred to me that you could optimize the placement of the pulse edges to minimize lower harmonics.

Last Edited: Mon. May 31, 2021 - 11:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I keep meaning to try Magic Sinewaves. I bought all the odd value resistors a few years ago to try but never got around to it. As I've got one of these...

 

https://quantasylum.com/collecti...

 

...I ought to be able to take some accurate measurements.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Mon. May 31, 2021 - 11:31 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have square wave, you should do a lot of filtering, because 3rd, 5th and other harmonics are dead-slow-dying.

I vote for #2 of JS. Ladder R-2R on this freq. range is easy to build, with discrete components, too.
And then, you should filter not from the 3rd harmonic of frequency, but much higher, simple amplifier-integrator may do it.

 

Edit: AD9833 can do it

Last Edited: Mon. May 31, 2021 - 11:58 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

That's very interesting. So you can kill low harmonics with careful placement of pulse edges, and the harmonic power is shifted to very high harmonics that can be filtered easily.

Very clever.

 

edit: of course the method to generate sinewaves with PWM is well known

 

 

but it never occurred to me that you could optimize the placement of the pulse edges to minimize lower harmonics.

 

So with this method, every frequency will require its own set of duty cycle values? And one type of filtering will work for all the other frequencies like , 300hz to 1600hz ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


It can do it all, AVR, I2C + AD9833.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Heisen wrote:
So with this method, every frequency will require its own set of duty cycle values?

 

I'm sure they can be scaled, that is, all the timings for 600Hz will be half of the timing for 300Hz.

 

Heisen wrote:
And one type of filtering will work for all the other frequencies like , 300hz to 1600hz ?

 

It seems so, because the low harmonics are nullified by the method so they don't need to be filtered.

 

edit: the principles of the method are explained here  https://www.tinaja.com/glib/msinexec.pdf

But I never tested it - I mean, I trust math, but I need to see this canceling of harmonics with my eyes to believe it cheeky

 

Because

Someone wrote:
In theory there is no difference between theory and practice. In practice there is.

Last Edited: Mon. May 31, 2021 - 01:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you go the DDS route, then you don't need to worry about the 3rd and 5th harmonics of 300 Hz vs the passband for the 1600 Hz signal.

The filtering is to remove the much higher frequency signal introduced by the "stairsteps" at the (very high) ISR frequency.

Filtering for the low frequencies of interest, needed here, is then easy.

 

Chapman, nice article on the MFB filter, although its been a while since I did any of the math therein!

I'll keep them in mind for future projects, although most of my stuff is pretty trivial, and Sallen-Key filters are easy to use and just plain work as expected.

 

The AD9833 is a great approach for this.

Unfortunately the OP didn't want to order / import items.

The AD9833 is a high performance DDS chip (high performance compared to implementing a DDS on a low speed, 8-bit micro).

It also, however, still requires the use of a LPF on the output to clean up the signal.

 

JC  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:
Regardless of whether you use a DAC or an R-2R ladder, or a PWM, you need to feed the resultant signal into a Low Pass Filter to get a clean output waveform, (with minimal harmonics).
A PWM DAC is filter-less.

PWM to DC in One Cycle (Analog Devices)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A PWM DAC is filter-less.

 

PWM to DC in One Cycle (Analog Devices)

That's pretty cool!  You could also use it as a demodulator (as opposed to using it as a mere "dac").  Wonder if they make a PPM demod as well? 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


avrcandies wrote:
Wonder if they make a PPM demod as well? 
This?

LTC2644 (Rev. B) (Analog Devices)

[page 17]

LTC6992 TimerBlox: Voltage-Controlled Pulse Width Modulator (PWM) | Analog Devices

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gchapman wrote:

DocJC wrote:
Regardless of whether you use a DAC or an R-2R ladder, or a PWM, you need to feed the resultant signal into a Low Pass Filter to get a clean output waveform, (with minimal harmonics).
A PWM DAC is filter-less.

PWM to DC in One Cycle (Analog Devices)

 

Wow, I'm always impressed by how Linear Devices can make very costly parts, that replace a sub $1 MCU  ;)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

laugh

At least, there's no software.

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gandara wrote:

... By now I'm only using an IRS @ 1KHz but I could increase or decrease this frequency without problem.

Yes, bump that to 62.5kHz to run the 16b adder to PWM loader.

You can also divide inside that to get a 1ms tick, but keep the code in Timer ISR here very tight (check the assembler listing) as you have just 256 syclks between interrupts at this higher rate..

 

gandara wrote:

... I already have a very good second order LPF in the circuit which I can use for this matter.

That will be good enough, as even the highest 1600Hz tone you need, has 39 samples per sine cycle with a 62.5kHz PWM rate 

 

gandara wrote:

So the main challenge is to make this DDS work. I never deal with this subject before and all those information you show help a lot. I have a very good scope in hands which serve me well testing the filters. Thank you!

 

Down load some of the examples above, and run first with no changes to get a feel for how they work.

Someone looking for widest generated range will use a parallel DAC, but your max Hz is very modest, so a PWM loaded DDS is fine.

 

I did find a code snippet of DDS in C using 32b adder to PWM register re-loading here

https://www.avrfreaks.net/commen...

 

copied here, as the 'DDS engine room' is just 2 lines of code (plus the SINE_TABLE) and each frequency you want, has a unique phase_increment value.

From above in my #3,  315 in a 16b adder gives 62500/(2^16/315) = 300.407Hz and 1678 gives 62500/(2^16/1678) = 1600.265Hz (etc) 

volatile uint32_t phase_increment = 1234;   //actual value depends on the frequency you require

ISR(TIMER0_OVF_vect)
{
  static uint32_t acc = 0;
  acc+= phase_increment;
  OCR0B = SINE_TABLE[acc >> 24];    //assumes a 256 byte sine table
}

(you can use a faster 16b adder, to meet your modest Step & precision specs. )

 

The timer ISR interrupt is set to run at PWM rate and CLK/256 will be fine for what you need, and easy to code. A single 256 byte sine lookup is all that you need.

 

and here is C code for AVR PWM-sine-lookup inside an interrupt, this is not DDS based, but it is very simple to change to DDS

https://scienceprog.com/generate...

This could also be useful, and is getting quite close to what you need.

http://interface.khm.de/index.ph...

 

DDS code inside interrupt, running at  ~32us, comment says runtime : 8 microseconds ( inclusive push and pop) - that's for a 32b adder, and a  16M/510 PWM

So a 16us ISR rate  16M/256 will use roughly 50% of the MCU.

I see they use triangle mode  PWM (called phase correct PWM ) which gives the 16M/510, and that's a valid choice too. If the MCU is doing a lot of other stuff, the /510 mode will have CPU load ~ 25% (32b adder, 256 table)

 

Last Edited: Mon. May 31, 2021 - 10:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gchapman wrote:

laugh

At least, there's no software.

Or, no user visible software ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Wonder if they make a PPM demod as well? 

This?

I was referring to pulse-position demodulation (so where the pulse appears in each cycle gives the "value")

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting discussion of the "magic sinewaves":  https://electronics.stackexchange.com/questions/11844/don-lancasters-magic-sinewaves

In particular, this paper has a detailed discussion by other researchers who seem to have independently developed a similar method.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1


Another idea courtesy of Don Lancaster is Digital Sinewaves...

 

 

...note in this example that the first harmonic present is the 9th and it is already 19dB down.

 

If an full 8-bit port was used to make a 9-stage counter then the first harmonic present is the 17th and it's already 25dB down.

 

This can all be found in his CMOS Cookbook.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm digging out my TV typewriter !!  Who built one?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
I'm digging out my TV typewriter !!  Who built one?

I did!

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

An instance of the Golden Ratio.

golden ratio | Examples, Definition, & Facts | Britannica

Creator -> Nature -> Physics -> Engineering

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With Signetics 2513, I presume?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh, just like #13!  :-)

 

Use two PWM output from a 16-bit timer, set to 33% and 66% of max, tie with equal resistor values, get a three-level sine-wave approximation. Have to change all the values when you change the frequency, but there's no large overhead trying to PWM sinewaves, no look-up tables.  The clock is 6x the sine wave frequency.

 

More references:
-  johnson ring counter sine wave generator - US patent US4368432
-  https://electronics.stackexchang...

 

Mike

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

  This can all be found in his CMOS Cookbook

 

Counter is better known as Johnson counter, for those who may ask for more.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Multiple Feedback Low-pass Filter Design Tool (OKAWA Electric Design)

up one level to see all filters including third-order

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Who-me wrote:
You should be able to generate a modulated PWM sine ok.
Likewise in hardware into a single-order low-pass filter into headphones :

Page 10 | GreenPAK Application Notes | Dialog

[1/3 page]

AN-1111 Sine Wave Generator (1.8 MB) This application note shows how to create a sine wave generator using a SLG46531V GreenPAK™ device with just a few external components SLG46531 Sine Wave, PWM, Arduino, I2C, Duty Cycle, Filter

SLG46537 | Dialog

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Wed. Jun 9, 2021 - 01:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sallen-Key with digital rheostats :

GreenPAK Application Notes | Dialog

[1/3 page]

AN-CM-310 Adjustable Analog Filter (631.76 KB) This application note illustrates how to use the SLG47004 to implement an adjustable analog filter and describes different ways to adjust the filter`s cutoff frequency SLG47004 Adjustable Analog Filter, Analog Multiplexer, Analog Filters, Sallen-Key Filter

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


 

Heisen wrote:

Got it working. Accurate frequency from 300Hz to 1,600Hz with (100Hz steps)

Here is the code for atmega328p running at 16MHz, it uses 16bit (timer 1) and PB2 pin as the PWM pin.

---

Pass value from 1 to 14 to change_freq function to get your desired frequency, pass 0 to turn it off.

Add appropriate filters to get sinewave.

This is the best possible proposal, and there is the passive filter:

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My first try was a square wave oscillator and converting to sinewave with RC filters. But there ate too many harmonics and it will take many extra components to clean.

So why good now?  No explanation given!!

 

Amplitude should not change too much. Let's say no more than 10%. 

What is the result??  You have a 5:1 freq range; you say it is steady output  level over that wide amount (300--1600 Hz)??

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!