tinyAVR DAC Tone Generator on Slow Clock Speed

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

Hello! I am using an ATtiny416, and have imported this project:  https://github.com/MicrochipTech/TB3210_Getting_Started_with_DAC/blob/master/Generating_Sine_Wave_Signal/main.c

 

It uses the on board DAC to generate an audio tone. My end goal is to do just that - make a couple of audible beeps between 500Hz-2000Hz. I have the code running great, at a 3.33MHz system clock as shown in the project.

 

The issue is, I want to run the system clock at a very low 8KHz. When I change to this, I get no sound. Presumably this is something to do with it using the _delay_us() function and the smallest delay you can achieve with certain clock speeds. Can someone verify this?

 

Or does anyone know of a better way to generate these audio tones at such a low clock speed?

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

At 8KHz system clock, stop using the DAC to make sine waves.  Just toggle a pin between Vcc and Gnd with a two-resistor voltage divider ( pinX --- 10K ohms ---Audio Out --- 2.2K ohms ---- Ground) to get a ~1 volt Audio Line-In signal.

 

If, for some reason, there must be a sine audio output, run the CPU in deep-sleep mode for all the times that it is not generating beeps.  Run the beeping code at 3.3MHz standard system clock.

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

Simonetta wrote:

At 8KHz system clock, stop using the DAC to make sine waves.  Just toggle a pin between Vcc and Gnd with a two-resistor voltage divider ( pinX --- 10K ohms ---Audio Out --- 2.2K ohms ---- Ground) to get a ~1 volt Audio Line-In signal.

 

If, for some reason, there must be a sine audio output, run the CPU in deep-sleep mode for all the times that it is not generating beeps.  Run the beeping code at 3.3MHz standard system clock.

 

What type of signal would the voltage divider method produce? And how would I go about doing that?

 

For the project, none of the clocks can be above 8KHz at any point - otherwise I wouldn't have this problem in the first place.

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

What would ever be a good use of using an 8kHz clock speed for an AVR?

Just run the thing at a few MHz and put it to sleep when it has nothing to do.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

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

Paulvdh wrote:

What would ever be a good use of using an 8kHz clock speed for an AVR?

Just run the thing at a few MHz and put it to sleep when it has nothing to do.

 

Avoiding FCC classification as a digital device for an otherwise extremely simple project handling a couple switches and LEDs.

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

Many years ago I did this same thing on an FPGA

and discovered that pure sine waves don't sound

very good.  I found triangle waves to be easier to

produce and pleasant to listen to.  Square waves

are a bit harsher and louder but also sound better

than sine waves.

 

--Mike

 

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

avr-mike wrote:

Many years ago I did this same thing on an FPGA

and discovered that pure sine waves don't sound

very good.  I found triangle waves to be easier to

produce and pleasant to listen to.  Square waves

are a bit harsher and louder but also sound better

than sine waves.

 

--Mike

 

 

In the end it doesn't matter what type of wave it is, as long as it isn't annoying to listen to. I would agree that triangle waves aren't bad - they don't sound terribly different from a sine wave.

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

But with an 8kHz clock you'll not be making 500Hz - 2kHz sinewaves directly.

 

A simple sinewave lookalike needs about 32 samples per cycle. So for 2kHz you need to output samples to the DAC at 64kHz. You could output a simple squarewave from a timer and filter it to remove the upper harmonics but to make a 500Hz sinewave you'll need a 500Hz filter and for 2kHz you'll need a 2kHz filter. Using a 2kHz filet for 500Hz means the 3rd harmonic will still be present.

 

If all you want is a tone then a squarewave will be fine though.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "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." - Heater's ex-boss

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

Brian Fairchild wrote:

But with an 8kHz clock you'll not be making 500Hz - 2kHz sinewaves directly.

 

A simple sinewave lookalike needs about 32 samples per cycle. So for 2kHz you need to output samples to the DAC at 64kHz. You could output a simple squarewave from a timer and filter it to remove the upper harmonics but to make a 500Hz sinewave you'll need a 500Hz filter and for 2kHz you'll need a 2kHz filter. Using a 2kHz filet for 500Hz means the 3rd harmonic will still be present.

 

If all you want is a tone then a squarewave will be fine though.

 

Square wave is probably the least preferable, but a triangle wave would suffice. Would that be any easier to do? If some external filtering components are absolutely necessary then that is ok, but not preferred.

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

 Triangles are very easy to do in software.

Just take a variable, and add a constant to it, and then output the variable to the DAC.

At some time (depending on the constant) your variable will overflow, and the triangle starts again.

For a sine wave (or any other waveform for that matter) you can use the same procedure combined with a look up table [array] of the resolution you want.

 

Brian Fairchild wrote:
A simple sinewave lookalike needs about 32 samples per cycle.

Meh, overkill. With 4 samples per period and a bit of filtering afterwards reconstruction of a sine is pretty easy.

Did some experiments with a DDS chip some time ago, and distortion started increasing significantly when the sine contained less than 3.6 samples/period.

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

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

Paulvdh wrote:

 Triangles are very easy to do in software.

Just take a variable, and add a constant to it, and then output the variable to the DAC.

At some time (depending on the constant) your variable will overflow, and the triangle starts again.

For a sine wave (or any other waveform for that matter) you can use the same procedure combined with a look up table [array] of the resolution you want.

 

I think I've gotten that concept. For example, 4 samples between 0 and 255 would be outputting 0, 85, 170, 255, 170, 85, 0, etc? But how do you determine the frequency of the triangle wave? Say, if I wanted to output a 1kHz triangle wave with 4 samples per period.

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

Isn't that called a ramp wave?  Similar to a

triangle but a triangle goes up, then back

down, not simply using overflow.  I would

guess that a ramp wave sounds a bit more

harsh than a triangle wave, but less harsh

than a square wave.  Easier to produce,

though, so a good candidate to try.

 

--Mike

 

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

There are some situations where you just cannot avoid running into FCC rules. Or, its technically really hard. Unfortunately, this is one.

 

Think about the ramifications of an 8KHz clock. This means that your highest tone frequency only has 4 MCU clocks per period. If you have 4 samples per period, at the top end, then you are creating a new output sample every 2 MCU clock cycles. You can hardly output to a DAC in 2 cycles, let alone increment a variable, or check a switch, or manage an LED.

 

Sleeping won't help! You need SOMETHING to periodically wake the chip. That something will probably involve a clock that runs faster than 8KHz.

 

Simple fact is: sometimes, those things that, at first look, seem "so simple" just are not so simple.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

ka7ehk wrote:

There are some situations where you just cannot avoid running into FCC rules. Or, its technically really hard. Unfortunately, this is one.

 

Agreed. I'm not expecting this to be very easy, but if there is any way to accomplish it I want to find it. The FCC is the easy, but expensive, road and a last resort.

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

Well, I've got it clocked at 8kHz and have it producing some kind of tone on the DAC. I'm not sure what wave type it is or what frequency exactly, but it sure sounds above 1kHz to me. I've got the simple code below with an RTC interrupt that every 100ms causes a 200ms delay. So I've got a bunch of quick beep-beep-beeps.

 

DAC0.DATA = 0;
DAC0.DATA = 85;
DAC0.DATA = 170;
DAC0.DATA = 255;

 

And doing this produces a lower tone:

DAC0.DATA = 0;
DAC0.DATA = 85;
DAC0.DATA = 170;
DAC0.DATA = 255;
DAC0.DATA = 170;
DAC0.DATA = 85;

 

Last Edited: Mon. Apr 22, 2019 - 06:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd think that if one was generating an audio tone using a low frequency clock one might set up a timer/counter in CTC mode with a prescaler of 1.

Then let the T/C toggle the output bit to generate the tone.

The output will be a square wave, but you've tied one hand behind your back with the low clock, so accept the square wave and move on with your project.

 

You didn't mention what the output will be:

micro directly driving a speaker

micro driving a small D-Class audio amp chip, which then drives a speaker

micro driving an op-amp, which then drives a speaker.

 

It is certainly possible to put a simple RC filter in the output if the micro will be driving an amp chip or an op-amp, to attenuate some of the square waves higher frequency harmonics, if you feel that that makes for a more pleasing tone.

 

JC

 

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

DocJC wrote:

You didn't mention what the output will be:

micro directly driving a speaker

micro driving a small D-Class audio amp chip, which then drives a speaker

micro driving an op-amp, which then drives a speaker.

 

Your only options are driving a speaker. :) It will not drive a speaker through any circuitry in the device. Just outputting a mic-level signal in the order of .001 to .01 volts.

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

Hello,

  The signal produced by toggling a port pin between 0V  (ground) and 1V (voltage divided Vcc: 1V peak-to-peak is the amplitude of an audio line-in signal) is a square wave.  The square wave sounds like a clarinet while a sine wave sounds like a flute.  If the audio only needs to be a beep to notify the user of an event's completion, then it doesn't really matter if the beep is a sine or a square wave.  As jt274 noted,  the signal coming from a microphone will be in the .001 to 0.01 volt range.  Do not connect a Vcc/gnd signal (that would come directly from a toggled AVR port pin) to an audio amplifier input: reduce it to the 1v peak-to-peak range first with an op-amp or a simple resistor pair.

 

  The square wave is the sum of the sinusoidal odd harmonics of a sine tone, and these harmonics may be attenuated as well.  For example, a 220 Hz square wave (MIDI note A2) will have a sine wave of 220 Hz, plus combinations of the 1st harmonic at 440 Hz, the 3rd harmonic at 660 Hz, the 5th harmonic at 1100 Hz, etc...

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

Simonetta wrote:

For example, a 220 Hz square wave (MIDI note A2) will have a sine wave of 220 Hz, plus combinations of the 1st harmonic at 440 Hz, the 3rd harmonic at 660 Hz, the 5th harmonic at 1100 Hz, etc...

 

There wouldn't be any 440 Hz (which is the

second harmonic) in the frequency spectrum

of a 220 Hz square wave.

 

--Mike

 

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

Perhaps you can generate the 2kHz sinewave you want with only 100Hz clock to the AVR.

It is so simple to build a 2kHz sine oscillator with two transistors or op-amps, and the AVR just triggering it on/off as needed via a single port pin.

 

Why complicate things? ;)

 

I wonder how much code is compiled just for the function sin() from the match.h included, on the #1, in order to create the sin table.

 

Wagner Lipnharski
Orlando Florida USA

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

jt274 wrote:

Paulvdh wrote:

What would ever be a good use of using an 8kHz clock speed for an AVR?

Just run the thing at a few MHz and put it to sleep when it has nothing to do.

 

Avoiding FCC classification as a digital device for an otherwise extremely simple project handling a couple switches and LEDs.

How do you generate the 8kHz for the AVR ?

 

Google finds this link, which also mentions 1.7MHz for battery powered devices ?

https://hackaday.com/2016/09/19/preparing-your-product-for-the-fcc/

 

jt274 wrote:

Well, I've got it clocked at 8kHz and have it producing some kind of tone on the DAC.

And doing this produces a lower tone: 

If you want kHz tones from a 8kHz clock, you will likely have to code in assembler.

 

For fun, we once did a commercial Timer app that used a SysCLK of 100Hz from mains, was interesting exercise, mostly to prove it could be done... & to get good timing precision.

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

How do you get an 8KHz clock? That is, how do you actually generate it?

 

A 555 running at 8KHz? An 8KHz RC oscillator? Some faster clock divided down to 8KHz? If it is the latter, then no-no! The FCC is concerned about the clock frequency for logic generally, not just the MCU. So, if there is any clock, anywhere, in your system and it is faster than 8KHz, you are not meeting the no-test criterion.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net