Here is the code! Go get it, Luigi! Orignal work by John Harrison that the following code was based on: http://cratel.wichita.edu/blogs/engr101fall2010/2010/11/29/2-voices-simultaneously-on-1-arduino/
// 2 voices on 1 Arduino // demo by John Harrison // Nov 28, 2011 // public domain // Modified by Dipto Pratyaksa // Added Mario tunes by Dipto Pratyaksa // Apr 3, 2013 // v 1.1 // 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 include pitches.h in the same folder as your .ino or .pde skecth file #include "pitches.h" // as stated above, // connect amp/speaker to FIRST_TONE_PIN and subsequent. // for example, if FIRST_TONE_PIN is 8 and NUM_OF_VOICE is 2, // connect amp/speaker to arduino pin 8 and pin 9. // 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 8 #define NUM_OF_VOICES 2 #define LED_PIN 13 // a future version will support more than 2 simultaneous voices // notes in the melody: int melody1[] = { NOTE_E7, NOTE_E7,0,NOTE_E7, 0, NOTE_C7, NOTE_E7,0, NOTE_G7,0,0,0, NOTE_G6,0,0,0, NOTE_C7, 0, 0,NOTE_G6, 0, 0,NOTE_E6,0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G7, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0,NOTE_C7, NOTE_D7, NOTE_B6, 0,0, NOTE_C7, 0, 0,NOTE_G6, 0, 0,NOTE_E6,0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G7, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0,NOTE_C7, NOTE_D7, NOTE_B6, 0,0, }; int harmony1[] = { NOTE_FS6, NOTE_FS6,0,NOTE_FS6, 0, NOTE_FS6, NOTE_FS6,0, NOTE_B6,0,0,0, NOTE_G6,0,0,0, NOTE_E6, 0, 0,NOTE_C6, 0, 0,NOTE_G5,0, 0, NOTE_C6, 0, NOTE_D6, 0, NOTE_CS6, NOTE_C6, 0, NOTE_C6, NOTE_G6, NOTE_B6, NOTE_C7, 0, NOTE_A6, NOTE_B6, 0, NOTE_A6, 0,NOTE_E6, NOTE_F6, NOTE_D6, 0,0, NOTE_E6, 0, 0,NOTE_C6, 0, 0,NOTE_G5,0, 0, NOTE_C6, 0, NOTE_D6, 0, NOTE_CS6, NOTE_C6, 0, NOTE_C6, NOTE_G6, NOTE_B6, NOTE_C7, 0, NOTE_A6, NOTE_B6, 0, NOTE_A6, 0,NOTE_E6, NOTE_F6, NOTE_D6, 0,0, }; int underworld_melody[] = { NOTE_C5, NOTE_C6, NOTE_A4, NOTE_A5, NOTE_AS4, NOTE_AS5, 0, 0, NOTE_C5, NOTE_C6, NOTE_A4, NOTE_A5, NOTE_AS4, NOTE_AS5, 0, 0, NOTE_F4, NOTE_F5, NOTE_D4, NOTE_D5, NOTE_DS4, NOTE_DS5, 0, 0, NOTE_F4, NOTE_F5, NOTE_D4, NOTE_D5, NOTE_DS4, NOTE_DS5, 0, 0, NOTE_DS5, NOTE_D5, NOTE_CS5, NOTE_C5, NOTE_DS5, NOTE_DS5, NOTE_GS4, NOTE_G4, NOTE_CS5, NOTE_C5, NOTE_FS5,NOTE_F5, NOTE_E4, NOTE_AS5, NOTE_A5, NOTE_GS5, NOTE_DS5, NOTE_B4, NOTE_AS4, NOTE_A4, NOTE_GS4, 0, 0, 0 }; int underworld_melody1[] = { NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4, NOTE_AS3, NOTE_AS4, 0, 0, NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4, NOTE_AS3, NOTE_AS4, 0, 0, NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4, NOTE_DS3, NOTE_DS4, 0, 0, NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4, NOTE_DS3, NOTE_DS4, 0, 0, NOTE_DS4, NOTE_D4, NOTE_CS4, NOTE_C4, NOTE_DS4, NOTE_DS4, NOTE_GS3, NOTE_G3, NOTE_CS4, NOTE_C4, NOTE_FS4,NOTE_F4, NOTE_E3, NOTE_AS4, NOTE_A4, NOTE_GS4, NOTE_DS4, NOTE_B3, NOTE_AS3, NOTE_A3, NOTE_GS3, 0, 0, 0 }; //melody notes in miliseconds int underworld_tempo[] = { 200, 200, 200, 200, 200, 200, 400, 800, 200, 200, 200, 200, 200, 200, 400, 800, 200, 200, 200, 200, 200, 200, 400, 800, 200, 200, 200, 200, 200, 200, 400, 400, 133, 133, 133, 400, 400, 400, 400, 400, 400, 133, 133, 133,133, 133, 133, 267, 267, 267, 267, 267, 267, 800, 800, 800 }; int mel1Durations[] = { 150, 150, 150,150, 150, 150, 150,150, 150, 150,150,150, 150, 150,150,150, 150, 150,150,150, 150, 150,150,150, 150, 150, 150,150, 150, 150, 150,150, 200, 200, 200, 150, 150,150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 200, 200, 200, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, }; int harm1Durations[] = { 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, 150, 150, 150,150, }; void setup() { Serial.println("play"); Serial.begin(9600); for (unsigned char i = 0; i < NUM_OF_VOICES; i++) { pinMode(i+FIRST_TONE_PIN,OUTPUT); Serial.println(i); } //led indicator pinMode(LED_PIN,OUTPUT); Serial.println("play"); } void loop() { // if we get here, we played the melody // all we can do is pee in corner of circular room // OPTIONAL. 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] *2; // harm1Durations[j] = harm1Durations[j] * 2; // Serial.println(harmony1[j]); //} //for (int j = 0; j < (sizeof(melody1) / sizeof(int)); j++) { // melody1[j] = melody1[j] *2; // mel1Durations[j] = mel1Durations[j] * 2; // Serial.println(melody1[j]); //} // call magic function to play both voices playTune(melody1, sizeof(melody1)/sizeof(int), mel1Durations, harmony1, sizeof(harmony1)/sizeof(int), mel1Durations); playTune(underworld_melody, sizeof(underworld_melody)/sizeof(int), underworld_tempo, underworld_melody1, sizeof(underworld_melody1)/sizeof(int), underworld_tempo); } // 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<NUM_OF_VOICES;i++) { if (Counts[i] < CurrentCount) { TimedPin = i; CurrentCount = Counts[i]; } // for } if (CurrentCount > 3) delayMicroseconds(CurrentCount); if (Periods[TimedPin] < 65535) States[TimedPin] = !States[TimedPin]; digitalWrite(LED_PIN, HIGH); digitalWrite(FIRST_TONE_PIN+TimedPin,States[TimedPin]); digitalWrite(LED_PIN, LOW); 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]; } }
(Visited 5,507 times, 1 visits today)
8 thoughts on “Play Mario Bros theme song on Arduino and 2 piezo buzzer / speakers in Stereo Harmonies”
Comments are closed.
this is bad ass ! wonderful demonstration.
Thank you Andre!
Have you tried programming any other theme songs that you can share with us in LinuxCircle?
yes. I did make a little gamebox, with 4 games, I used yours for one and I made “Impossible Mission” myself. I also did it with one speaker using two digital outs plus I changed the play tone function to work while other code is executed. I would like to contribute and share, where should I put the source ?
Hi Andre,
I have created a contributor account for you, so you can write and publish the article here. Please check your email for your username and password.
Thanks for sharing!
Hy Dipto,
It may take a few days till I will contribute a working / compiling stand alone version, as it is part of my “game engine”. But I´m looking forward to make it as fast as possible. Thanks for the account.
Hi Am new to Arduino Uno..can you please share the pin diagram with components.?
Here it is:
http://www.princetronics.com/wp-content/uploads/2014/06/buzzeruno.jpg
Thank you sir