tone() does not work as expected

Hello all,

I'm playing with an UNO since a while.... well, not for fun, it'll be the 'main controller' :) of a new machine in the company.

I encountered a problem with tone().

I need a 'tone' with 1 Hz frequency and 5 Sek. duration, to generate an intermittent BEEP on a connected buzzer (which does the audio tone itself). Results not as expected, not 1 Hz but much more, and not 5 sec duration but much less. I changed 'duration' in my tone() statement to 50000, and the duration is just 1 sec.

Arduinos reference sais: "Use of the tone() function will interfere with PWM output on pins 3 and 11"

I DO have a PWM output running, but on pin 9.

So, tone() should not be affected? I also switched of the PWM but no change. Maybe 1 Hz is not allowed?

Thanks for help!

I'm not sure what has happened, but the tone documentation used to say that it didn't work below about 32Hz. (can't remember the exact figure) I don't think I'd even consider it for such a low frequency anyway

Oh… I was reading here: http://arduino.cc/en/Reference/Tone

and there is no hint about f<32 Hz. Maybe you have a different reference I should better use?

…anyway my idea does NOT seem to be the right way to generate a (hardware-supported) BEEP BEEP BEEP !
Sure I could connect an external timer but not very ‘stylish’ !

My next idea was to use a PWM output of 500Hz to generate an interrupt… interrupt increases a counter… and then outputs the 1 Hz wave. Not so stylish also.
Not sure also if an interrupt every 2ms overloads the CPU.

Thanks!

Blink Without Delay. You will have to adjust the code for your hardware and add something to stop the beeping...

const uint8_t BeepPin = 7;
const unsigned long BeepToggle = 1000;
static unsigned long BeepPrevious;

void setup( void )
{
  pinMode( BeepPin, OUTPUT );
}

void loop( void )
{
  unsigned long Now;
  
  Now = millis();

  if ( Now - BeepPrevious >= BeepToggle )
  {
    digitalWrite( BeepPin, ! digitalRead( BeepPin ) );
    BeepPrevious += BeepToggle;
  }
}

IF the buzzer does the tone itself, don't you want to just turn a digital output on for 1 sec and off for 1 sec lasting 5 sec? Tone is overkill. Check out BlinkWithoutDelay in the examples.

Thanks guys!

well, I thought tone() to be a really fancy solution: just one function call and the hardware does the rest. Nothing in my main loop!

But as it seems that tone() won't work, I'll use your suggestion. Thanks!

Probably the reference should be updated to reflect the limits of tone(). But I'm just the newbie who won't talk to the gods.. :)

works perfectly using 'blink w/o delay'. Thanks!

Glad you have it working. Thank you for the follow-up.