Go Down

Topic: Audio frequency generation on AtTiny85 (Read 4449 times) previous topic - next topic

MontySylver

I'm looking for a simple way to generate audio frequencies with an AtTiny85, so it plays an continuous sound (e.g. at 440hz) when an digital Input is pulled to ground. I found an frequency generation sketch in the playground that is described as simple, it also works on an AtTiny but seems to consist mostly of floating point math. And that's a little bit too hard for me since I am a bloody beginner in audio generation  :~ .
Witty text goes here, I guess.

dhenry

Try software DDS, essentially an array.

dhenry

Didn't quite finish it here.

Say that you want to generate a 400hz sine wave. Store that information in a 256 array.

Set up a timer that trips every 1/(400*256) = 10us. In the isr, increment an accumulator and output the value in the array indexed by that accumulator.

You are done.

If you point the array to other waveforms, you can generate any waveforms as you like.

256 points are a lot for even a good quality wave form. If you want to generate faster signal, you can go to 128, 64 or even 32 points, or simply change the increment to the accumulator.

The output can be anything, a r2r network, or dac or a digital pot.

Jack Christensen

Is tone() an option? OP didn't specify a sine wave.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

dhenry

In the event of square waves, you can use software or hardware pwm (50 percent duty cycle).

Hardware pwm can generate signals well into the Mhz.

prash

I want to generate pwm signal using analogwrite() in ARDUINO KIt 1.0 .I cant able to identify the pin which generates plsese help me

Jack Christensen


I want to generate pwm signal using analogwrite() in ARDUINO KIt 1.0 .I cant able to identify the pin which generates plsese help me


Have you had a look at the doc? Might have something about pins there.
http://arduino.cc/en/Reference/AnalogWrite
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

MontySylver


Didn't quite finish it here.

Say that you want to generate a 400hz sine wave. Store that information in a 256 array.

Set up a timer that trips every 1/(400*256) = 10us. In the isr, increment an accumulator and output the value in the array indexed by that accumulator.

You are done.

If you point the array to other waveforms, you can generate any waveforms as you like.

256 points are a lot for even a good quality wave form. If you want to generate faster signal, you can go to 128, 64 or even 32 points, or simply change the increment to the accumulator.

The output can be anything, a r2r network, or dac or a digital pot.



That sounds simple enough, is there an tutorial on this somewhere? The output is just a speaker and I want to generate a sine wave, so this seems just to be the right thing.
Witty text goes here, I guess.

DuaneB

#8
Oct 16, 2012, 06:07 pm Last Edit: Oct 16, 2012, 06:09 pm by DuaneB Reason: 1
Introduction here -

http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/

The sinewave is the singularly least interesting of all waveforms, the tone library will produce a far more interesting squarewave, if all you want is a tone or simple tune use the standard tone function - its what you hear in this video and sounds 100 times better than a sinewave -

http://www.youtube.com/watch?v=0_IP14gFKcI

DDS Can make a great sound, but its an awful lot more work than suggested, here is a simple synth that uses DDS

Not a single sinewave in sight, its all ramps and squares -

http://www.youtube.com/watch?v=fTmLKKLv5cE

More explanation here -

http://rcarduino.blogspot.com/2012/08/the-must-build-arduino-project-illutron.html

Duane B
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

Nantonos


Say that you want to generate a 400hz sine wave. Store that information in a 256 array.

Set up a timer that trips every 1/(400*256) = 10us. In the isr, increment an accumulator and output the value in the array indexed by that accumulator.

You are done.


I see what you did there. Getting back to the question posed by the OP, with a specific value of 440Hz (standard concert pitch A, for tuning) rather than 400 Hz (which gives 10 ?s, albeit with a 2.4% error) you would set up a timer that trips every 8.877841 ?s.

Using the formula
Code: [Select]
compare match register = [ 16,000,000Hz/ (prescaler * desired interrupt frequency) ] - 1

with a prescaler of 1, this gives
compare match register = 16,000,000 / ( 440 * 256 ) - 1 = 141.045454545454545 = 141, as an 8-bit integer.
The error from integer roundoff is a pretty reasonable 0.03%.
I'm not sure what the allowable error is in the 16MHz Arduino clock oscillator (pointer, anyone)?

But that looks as if it would be suitable for tuning an instrument.

dhenry

The approach I outlined can generate a sine or any other waveform. You can buffer it to drive a speaker.

There is also another approach: to generate a sine wave via pwm: you will need to load the compare register with the right value to produce a desired wave form. It has the advantage of being very fast but is more difficult to program.

Go Up