Go Down

Topic: can the arduino generate frequencies accurately? (Read 1 time) previous topic - next topic


I am looking to generate timed pulses (similar application to generating tones) with PWM via delayMicroseconds.  I can get the basic code workings, but a few questions came up that rudimentary testing with my untrained ear couldn't answer.

1.  Is there an audible difference in pitch between a tone generated with a delayMicroseconds loop and one generated by a tuning fork (or other "accurate measure")?
2.  Will polling for button presses in the loop alter the tone noticably (assume the case where no buttons are depressed, i.e. if statement evaluates as false)?  There may be as many as thirteen buttons to poll.
3.  Is there a better way to exit the loop and perform an action on button press than polling all buttons on each iteration of the loop?
4.  Will delayMicroseconds be effected by the timer overflow the Arduino sometimes gets (i.e. can I use this message to generate a frequency indefinitely, or is there a limit to the runtime of such a loop)?

anyone know the answers?

thanks in advance


delayMicroseconds will not overflow, though you can't pass an argument larger than 10000 or so. If you disable interrupts then delayMicroseconds will take the same time delay for each call, but millis() will stop and your serial input will not work.

If you leave the interrupts enabled then then every 1024 microseconds the timer0 interrupt will fire and delay you an extra few microseconds. Arriving serial characters will also delay you a similar amount.

I should probably write a library or something for this, but I generally reprogram one of the hardware timers to make a stable output frequency.


May 22, 2007, 05:36 am Last Edit: May 22, 2007, 05:37 am by Johntron Reason: 1
I'm not sure how/if they'd interfere with tone generation, but interrupts are probably what you want to use for polling external components. I'm not sure if the Arduino supports these (I don't have an Arduino yet), but attachInterrupt, detachInterrupt, and interruptMode are all documented in the Wiring language reference.

Also, I've wondered if it would be possible to generate tones using the touch tone generators in telephones. Each tone on touch tone phones is comprised of two different notes. I believe the column on a phone's keypad generates one of the notes, while the row generates the other. It might be possible to use high-/low-pass filters on each note of each tone to generate at least 7 different frequencies.  You may not even need high-/low-pass filters. There's probably better ways to do this, but it would be an interesting hack.


May 22, 2007, 06:49 am Last Edit: May 22, 2007, 06:50 am by jims Reason: 1
Ok, I library-ized the timer2 frequency generator code. http://www.arduino.cc/playground/Code/FrequencyTimer2 will tell you all about it and has the code. This library lets you make absolutely stable square wave signals from 1MHz down to about 30Hz on a 16MHz Arduino.

I might mention that until 0008 comes out you might have to add a
Code: [Select]
#define clockCyclesPerMicrosecond() (16)
to the libraries I have been uploading recently.


Thanks everybody... I'll now need to look into this library.

I need a non-square wave, so I'll probably end up just borrowing from it, but it looks really useful.


If you are looking for a sine wave rather than a square wave you can run the output through a RC filter to get a good approximation.  This would allow you to use the code as is.  Even if you use some kind of D2A conversion to generate a sine wave you might want some filtering to smooth out the stair steps.


Actually, I'm looking to strobe at a chosen frequency, so the time HIGH has to be much shorter than the time spent LOW...


The hardware timers can do that. You need to pick the mode where the input capture register is the top and use the output capture register to clear the pin (it will set at bottom). Then just set the output capture register to something like 1 and you will get a short strobe with a period governed by the input capture register and the prescaler.

Go Up