tone generator code

HI I an building a simple tone generator using the tone follower code in the arduino digital examples it works great from 50HZ on up I can not get it to work anything under 50HZ I need from 0 To 500 HZ here is the code I am using. I replaced the photo resistor with a 10K pot. and also tried a 0 to 5 Volt supply all the same result nothing under 50HZ

Plays a pitch that changes based on a changing analog input

circuit: * 8-ohm speaker on digital pin 8 * photoresistor on analog 0 to 5V * 4.7K resistor on analog 0 to ground

created 21 Jan 2010 by Tom Igoe


void setup() { // initialize serial communications (for debugging only): Serial.begin(9600); }

void loop() { // read the sensor: int sensorReading = analogRead(0); // print the sensor reading so you know its range Serial.println(sensorReading); // map the pitch to the range of the analog input. // change the minimum and maximum input numbers below // depending on the range your sensor's giving: int thisPitch = map(sensorReading, 0, 1023, 0, 500);

// play the pitch: tone(8, thisPitch, 10);

what Am I doing wrong any suggestions


First thing is I would put a 200ohm resistor in series with the speaker as the 8 ohm speaker voice coil resistance is much too low and pin damage could result from too much current draw to the speaker. This will limit the volume some so if you need more volume you will have to look for some kind of audio amplifier to drive the speaker.


Its dubious whether anything below 50 Hz could actually be reproduced with square wave from a microcontroller. I haven't tried it but I suspect it would sound like a series of clicks rather than a tone. 50 Hz is a very low hum, the limit of human hearing is around 20 Hz so I suspect you're not missing much.... ;).

I'd say its a deliberate action by the arduino authors to limit it to 50Hz

Having had a play with tone at low frequencies, it does sort of work, but it gives unpredictable results below 30 Hz. I tried this code :

unsigned long time;
unsigned long count;
int freq;
boolean toneon = false;

void setup() {

  freq = 2;

void loop() {
  if (freq > 100){freq =2;};
  time = millis();
  if (time >= count){
    count = time + 500;
    //if (toneon){
    Serial.print("  ");
    tone(8, freq, 500); 
    //toneon = false;
    Serial.print("  ");
    freq = freq + 2;

It gives half a second of tones between 2 and 100 Hz in 2 Hz steps before repeating. It produces an 'interesting' serious of pops, clicks and squeaks before settling down to the expected behaviour above 30 Hz. It sounds like what it is (crap) though..... :)

The lower limit on the built-in tone() is 31 Hz for the 8 bit timer, timer 2. If you use the Tone library, you can get down to 1 Hz on the 16 bit timer(s).