Description
General description
On AVR chips, the tone() function allowed for the introduction of pauses by using a frequency of 0 (see toneMelody.ino example). While this leads to a division by 0 both in the AVR and SAMD implementations of that function, the SAMD platform appears to handle divisions by 0 differently. This causes the sketch to crash.
Expected behavior
The frequency of 0 should result in silence/produce a pause.
Actual behavior
Calling the tone() function with a frequency of 0 results in a crash.
Steps to reproduce
Run the toneMelody.ino example or any other sketch resulting in passing frequency 0 to the tone() function.
Additional information
Adafruit solves this by substituting a frequency of 1 for every instance 0 is passed, see Adafruit's version of ArduinoCore-samd Tone.cpp:
//if it's a rest, set to 1Hz (below audio range)
frequency = (frequency > 0 ? frequency : 1);
This, however, only works for tones shorter than ~500 milliseconds. If the tone duration is longer than that, the sketch produces a high-pitched whine. Using libraries that rely on or interfere with timer interrupts (such as FastLED or the Servo library) can cause additional audio glitches if a frequency of 1 is being used.
Tested on Arduino Nano 33 IoT and Adafruit Metro M0 Express.
Workarounds
Choosing a frequency above, instead of below the audible range, seems to produce more reliable results. 30000 appears to be a number that causes the least noticeable audible artifacts, based on very rudimentary testing.
A better solution, however, is to use noTone() to introduce a pause.