Then your expectation was unreasonable. The tone function is non-blocking, which is a good thing, since you do not want to diddle around in an ISR.
Then the interrupt happens, the tone() function is called, to start a tone sounding. Then, the ISR ends, and loop() resumes. No less than 1/5 a second later, you stop the tone that is happening, or start another tone.
Since freq is not modified in the ISR, it doesn't need to be volatile.
Thanks so much for your help. So is there another way to make this happen with an ISR?
Have one freq in the loop and when the IRQ is triggered to have the new tone for the specified time?
So is there another way to make this happen with an ISR?
Have one freq in the loop and when the IRQ is triggered to have the new tone for the specified time?
The ISR should stop the current tone, and start the new one.
loop() should NOT be using delay() to determine how long to wait before starting the next tone.
Look at the blink without delay example, without delay. Read, understand, and embrace it.
Each time a tone starts, you should note when that event occurred. Then, on each pass through loop(), determine if it is time to start a new tone. Obviously, then the ISR changes the tone, it needs to record when that happened, so loop() knows about the new lastToneStarted time.