Functions / library functions running 'in background'

Hi all,

I'm a moderately experienced programmer - but I generally learn as I need to while hacking my way through projects, and I never extensively learned C++ - so I expect that the answer to my question is something I've failed to understand about programming the Arduino.

I just recently needed to use the tone() function, and set out to crate a double beep with a rising tone, eg:

1000hz for 80ms 1400hz for 80ms

And discovered that if I used:

tone(9, 1000, 80);
tone(9, 1400, 80);

I only hear the 1400hz beep. This, I learned, is because the second call to tone() simply changes the frequency to the new setting. But I'm intrigued by how the second line is executed while the first hasn't completed. For example, I know that if I created a function called MyTone() which did some trickery with PWM to create tones, the behaviour would be different (i.e. the first function call would be executed, and when it returned the second would).

So can someone explain what's going on here? Ultimately, it would be very handy to make simple functions for example this one:

void DoubleFlash()
{
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
  digitalWrite(ledPin, HIGH);
  delay(500);
  digitalWrite(ledPin, LOW);
  delay(500);
}

which would be executed 'in the background' so to speak, allowing the program to move on while the LED blinking occurs.

Thanks in advance!

Write non blocking code using the technique found in the example sketch Blink Without Delay BWD.

Robin2 has a thread you may want to look at: http://forum.arduino.cc/index.php?topic=223286.0

So can someone explain what's going on here?

tone(9, 1000, 80);
tone(9, 1400, 80);

Try some different time spans. The only way it could possibly work as you describe it, that I can think of, would be if the first tone( ) call started outputting a PWM signal at 1000 Hz, and immediately returned. That is, it didn't tie up the processor for 80 ms.

So then you get the second tone( ) function call straight away.

Put, if that is how it works, it's a bit hard to see what will stop the tone after 80 ms.

It's because all the tone library does is set an appropriate time for the interrupt. The tone is generated by the interrupt so indeed, a new call to tone will just set the new values.

The non blocking way is to use the Blink without delay. I would set the time is the first tone call high (like 1 sec) and let the the blinkwithoutdelay end the first call. Because if you set the interval in tone the same as the interval with millis you might get a short pause between the tones because the tone library is instant (interrupt driven) en millis is not.