Home > hardware, software > Arduino Software Tone Generator

Arduino Software Tone Generator

February 20th, 2011 Leave a comment Go to comments

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…

Categories: hardware, software Tags: ,
  1. March 10th, 2011 at 06:19 | #1

    hi,
    I try to compile your code but i dont get “pitches.h” file. How to get this file. thank you for your tutorial.

  2. noob on arduino
    November 11th, 2013 at 03:34 | #2

    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,,,

  3. October 14th, 2014 at 02:32 | #3

    Woah! I’m really enoying the template/theme of this blog.It’s simple, yet effective.
    A lot of times it’s very difficult to get
    that “perfect balance” between usability and visual appearance.
    I must say you’ve done a amazing job with this.
    Also, the blog loads very ast for me on Firefox. Exceptional Blog!

  1. February 20th, 2011 at 05:29 | #1