Pages: [1]   Go Down
Author Topic: Low frequency tone issue  (Read 2392 times)
0 Members and 1 Guest are viewing this topic.
British Columbia, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm having an issue with the tone function, where if I try to produce a tone of 30 Hz or lower, the output frequency is erroneously higher.

Nothing in setup, and the only thing in the loop is:

tone(8,25);
delay(1000);


Is there a lower limit to frequency generation, or am I doing something wrong here?
Logged

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 7
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

With the Tone library supplied with arduino-0018:

Tones are generated by setting up a timer in RTC mode and toggling an output pin (in an Interrupt Service Routine) when the timer reaches a value determined by the contents of its OCR register.

With the maximum prescalar value of 1024, any frequency less than 31 Hz would require a value of greater than 255 in the timer's OCR register.

Since Tone uses Timer2 and Timer2 is an eight bit timer, frequencies less than 31 Hz are not possible.


Regards,

Dave

Footnote:
I have downloaded, but not tested, arduino-0019.  Some changes were made to Tone.cpp (disables Timer2 after the tone has ended), but they do not affect my answer to this question: Frequencies below 31 Hz do not compute.
« Last Edit: September 06, 2010, 09:10:40 am by davekw7x » Logged

0
Offline Offline
Edison Member
*
Karma: 0
Posts: 1103
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1281911346/1#1
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Tones are generated by setting up a timer in RTC mode and toggling an output pin (in an Interrupt Service Routine) when the timer reaches a value determined by the contents of its OCR register.

With the maximum prescalar value of 1024, any frequency less than 31 Hz would require a value of greater than 255 in the timer's OCR register.

Since Tone uses Timer2 and Timer2 is an eight bit timer, frequencies less than 31 Hz are not possible.
Seems like this information or some summery of it should be included on the tone() reference page...
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

British Columbia, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the great info, guys.  It really should be mentioned in the tone reference page.

I guess I'll just have to resort to the blink example to get the frequency I need.  OH, THE HUMANITY! smiley-razz
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Any updates on this problem? I am currently trying to drive a Speedometer out of a Jeep with my Arduino using the Tone() function.  I am running into the same problem, where the wrong frequency is put out if you go below 31Hz (16 MPH on this gauge).  I only need a range of about 10Hz to 220Hz to drive this gauge.  It sounds like that 16 bit timer Tone function would solve my problem, but I don't see any way of making use of it. Any suggestions?

Any help would be greatly appreciated.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
I'm kinda new, but I can get around.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

[glow]BUMP![/glow]

I am making a program that needs to play a melody. It doesn't work. The biggest problem is this.[ch8593]

When it plays a rest (0 Hz tone), all tones after that are wrong. Sometimes garbled or very low. Has anybody written a proper bit of code to solve this? PLEASE SHARE! smiley
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Instead of calling tone() with a 0 Hz frequency, you should probably generate your rests by calling noTone() and then calling delay() for the appropriate amount of time.

In other words, change this:

tone(SPK_PIN, 0, REST_LENGTH);

To this:

noTone(SPK_PIN);
delay(REST_LENGTH);

Keep in mind that delay() will stop the flow of your program until the delay is complete. If you need to continue execution while the rest is being handled, you will need to write an interrupt handler that keeps an eye on the value of millis(). I will leave this as a challenge for you if you decide to do it.
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 41
Posts: 5610
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You could tie the PWM output to a decade counter IC (like a 4017), then use the divide-by-10 output; so the lowest then you could go would be approx 3.1 Hz...
Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

Pages: [1]   Go Up
Jump to: