// 2 voices on 1 Arduino // demo by John Harrison // Nov 28, 2011 // public domain // v 1.0 // for the demo to work unmodified, hook up a 1Kish resistor to pin 11 and a 1Kish resistor to pin 12. // tie the other ends of the resistors together and hook those up to an amp and speaker. // or you could skip the resistors and hook up pin 11 to one side of a stereo amp and pin 12 to the other side // You have to included pitches.h. Below shows the path on my computer. Yours will be similar #include "C:\Documents and Settings\John\Desktop\arduino-0021\examples\2.Digital\toneKeyboard\pitches.h" // as stated above, // connect amp/speaker to FIRST_TONE_PIN and subsequent. // for example, if FIRST_TONE_PIN is 11 and NUM_OF_VOICE is 2, // connect amp/speaker to arduino pin 11 and pin 12. // if using the same amp/speaker for both pins, have each // pin go through a 1Kish resistor before being summed together #define FIRST_TONE_PIN 11 #define NUM_OF_VOICES 2 // a future version will support more than 2 simultaneous voices // notes in the melody: int melody1[] = { NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_A4, 0, NOTE_C5, NOTE_E5, NOTE_A5, NOTE_B5, 0, NOTE_E5, NOTE_GS5, NOTE_B5, NOTE_C6, 0, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_A4, 0, NOTE_C5, NOTE_E5, NOTE_A5, NOTE_B5, 0, NOTE_E5, NOTE_C6, NOTE_B5, NOTE_A5}; // melody note lengths in milliseconds int mel1Durations[] = { 200, 200, 200, 200, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400, 200, 200, 200, 200, 200, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400 }; // notes in the harmony: int harmony1[] = { NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_A4, 0, NOTE_C5, NOTE_E5, NOTE_A5, NOTE_B5, 0, NOTE_E5, NOTE_GS5, NOTE_B5, NOTE_C6, 0, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_DS5, NOTE_E5, NOTE_B4, NOTE_D5, NOTE_C5, NOTE_A4, 0, NOTE_C5, NOTE_E5, NOTE_A5, NOTE_B5, 0, NOTE_E5, NOTE_C6, NOTE_B5, NOTE_A5}; // harmony note lengths in milliseconds int harm1Durations[] = { 200, 200, 200, 200, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400, 200, 200, 200, 200, 200, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400, 200, 200, 200, 200, 400 }; void setup() { Serial.begin(9600); for (unsigned char i = 0; i < NUM_OF_VOICES; i++) { pinMode(i+FIRST_TONE_PIN,OUTPUT); } // in this test example, the harmony and the melody are initially the same // so we raise the harmony up an octave and slow it down to 1/2 speed for (int j = 0; j < (sizeof(harmony1) / sizeof(int)); j++) { harmony1[j] = harmony1[j] << 1; harm1Durations[j] = harm1Durations[j] << 1; } // call magic function to play both voices playTune(melody1, sizeof(melody1)/sizeof(int), mel1Durations, harmony1, sizeof(harmony1)/sizeof(int), harm1Durations); } void loop() { // if we get here, we played the melody // all we can do is pee in corner of circular room while (1) ; } // no need to modify anything below for basic use void playTune(int melody[], int melLength, int melDurations[], int harmony[], int harmLength, int harmDurations[]) { unsigned int Counts[] = { 0, 0}; unsigned int Periods[] = { 0, 0}; unsigned char States[] = { 0, 0}; unsigned long stopTimeNote1 = 0; unsigned long stopTimeNote2 = 0; unsigned char TimedPin = 0; unsigned int CurrentCount = 0; unsigned char i; unsigned char indexMel = 0, indexHarm = 0; while (1) { CurrentCount = Counts[0]; TimedPin = 0; for (i=1;i 3) delayMicroseconds(CurrentCount); if (Periods[TimedPin] < 65535) States[TimedPin] = !States[TimedPin]; digitalWrite(FIRST_TONE_PIN+TimedPin,States[TimedPin]); if (millis() >= stopTimeNote1) { if (indexMel >= melLength) break; stopTimeNote1 = millis() + melDurations[indexMel]; Periods[0] = 1000000 / melody[indexMel++]; } if (millis() >= stopTimeNote2) { if (indexHarm >= harmLength) break; stopTimeNote2 = millis() + harmDurations[indexHarm]; Periods[1] = 1000000 / harmony[indexHarm++]; } for (i = 0; i < NUM_OF_VOICES; i++) { Counts[i] = Counts[i] - CurrentCount; } Counts[TimedPin] = Periods[TimedPin]; } }