Arduino Software Tone Generator
This is something really trivial, but I have not actually googled out a recipe so I thought I’d post it anyway for the googlers out there. Sometimes, you discover the Arduino tune() function does not really work – in our case, it was since we have ethernet shield attached and apparently, some other piece of the software drives the timer (not surprising at all) – besides, the tune() function may silently abuse other pins than the chosen one, AIUI, due to its timer usage.
Therefore, it may be useful to manually generate sounds. The code snippet really is simple, with play-by-melody code thrown in for good measure too:
#include "pitches.h" /* Cue Star Wars - Darth Vader theme, opening notes! */ int melody_nak[] = { NOTE_G5, NOTE_G5, NOTE_G5, NOTE_DS5, NOTE_AS5, NOTE_G5, NOTE_DS5, NOTE_AS5, NOTE_G5}; int noteDurations_nak[] = { 330, 330, 330, 250, 120, 330, 250, 120, 500 }; int melody_ack[] = { NOTE_D6, NOTE_A6, NOTE_C7, NOTE_A6 }; int noteDurations_ack[] = { 120, 500, 120, 500 }; void toneManual(int pin, int frequency, int duration) { unsigned long period = 1000000/frequency; unsigned long length; boolean state = false; for (length = 0; length < (long) duration * 1000; length += period) { state = !state; digitalWrite(pin, state); /* The 50uS correspond to the time the rest of the loop body takes. * It seems about right, but has not been tuned precisely for * a 16MHz ATMega. */ delayMicroseconds(period - 50); } } void playMelody(int *melody, int *noteDurations, int notes) { int i; for (i = 0; i < notes; i++) { toneManual(8, melody[i], noteDurations[i]); delay(noteDurations[i] * 6/10); } } void playMelodyAck() { playMelody(melody_ack, noteDurations_ack, sizeof(melody_ack)/sizeof(melody_ack[0])); } void playMelodyNak() { playMelody(melody_nak, noteDurations_nak, sizeof(melody_nak)/sizeof(melody_nak[0])); }
Grab pitches.h from the digital -> tone generator example sketches, i.e. /usr/share/arduino*/examples/2.Digital/toneMelody/pitches.h
.
There is one important point. With tone(), you did not need to correctly set pin mode of the pin to output – you do need to do that with this routine! This took me quite a while to debug…
hi,
I try to compile your code but i dont get “pitches.h” file. How to get this file. thank you for your tutorial.
just made it run on my arduino…
it took me researching on the problem.. al i have to do is to put the playMelodyAck(); on void loop.. am i correct,,,