Hi,
I recently gave a robot the ability to 'speak' Morse code using a small RedBot buzzer. In Morse code, the ratios between dot, dash, and spacing intervals are very critical, as it is these ratios that allow the human brain and/or Morse processing programs to correctly interpret the sound sequences.
When trying to implement this capability, I ran into problems trying to use the Arduino tone(pin, freq, duration) function. It appears that the actual duration of the output from the tone() is very much different than the desired time, resulting in completely unreadable Morse code. In the end, I wound up using tone(), delay(), and noTone() to implement the Morse code audio sequences, and this worked nicely (except that this implementation blocks during the delay period).
I also tried using the NewTone library, thinking it's duration accuracy would be better, but it is essentially identical (at least in terms of duration) to the original tone library.
In the code below, all but the NewTone() implementation is commented out. To generate the other two samples, all I did was uncomment the appropriate line(s) and comment out the rest. I have attached a ZIP file containing three .WMV files to illustrate the differences between using the tone(pin, freq, duration) non-blocking overload and the tone(pin, freq)/delay(duration)/noTone(pin) implementations.
void OutputOneDot(int dotmsec, int buzzerpin)
{
//tone(buzzerpin, BUZZER_FREQ_HZ, dotmsec);
NewTone(buzzerpin, BUZZER_FREQ_HZ, dotmsec);
//tone(buzzerpin, BUZZER_FREQ_HZ);
//delay(dotmsec);
//noTone(buzzerpin);
}
void OutputOneDash(int dotmsec, int buzzerpin)
{
//tone(buzzerpin, BUZZER_FREQ_HZ, 3 * dotmsec);
NewTone(buzzerpin, BUZZER_FREQ_HZ, 3 * dotmsec);
//tone(buzzerpin, BUZZER_FREQ_HZ);
//delay(3 * dotmsec);
//noTone(buzzerpin);
}
ToneDuration.zip (1.08 MB)