In the experiment, Buzzer TMB12A05 was used.

// Playing melodies.
// Arduino tone() function - note frequencies.
// Notes:
// note   frequency
// c      262 Hz
// d      294 Hz
// e      330 Hz
// f      349 Hz
// g      392 Hz
// a      440 Hz
// b      494 Hz
// C      523 Hz

const int buzzerPin = 9;
// The length is the sum of the notes and pauses
const int songLength = 18;
// characters are notes and space is a pause
char notes[] = "cdfda ag cdfdg gf "; 

// Setting up the rhythm.
int beats[] = {1,1,1,1,1,1,4,4,2,1,1,1,1,1,1,4,4,2};

// "tempo" melody speed. The smaller the tempo, the faster the speed.
int tempo = 150;

void setup() 
{
  pinMode(buzzerPin, OUTPUT);
}

void loop() 
{
  int i, duration;
  for (i = 0; i < songLength; i++)
  {
    duration = beats[i] * tempo;
    // if there is no note
    if (notes[i] == ' ')
    {
      delay(duration);          
    }
    else                         
    {
      tone(buzzerPin, frequency(notes[i]), duration);
      delay(duration);          
    }
    // short pause between notes
    delay(tempo / 10);
  }
  // stop the loop once the song is played
  while(true){}
}

int frequency(char note) 
{
  int i;
  // number of notes
  const int numNotes = 8;
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523};
  
  // if the note exists, return its frequency
  for (i = 0; i < numNotes; i++)  
  {
    if (names[i] == note)       
    {
      return(frequencies[i]);    
    }
  }
  return(0); 
}
  • const int buzzerPin: the buzzer is connected to pin 9.
  • const int songLength: the total number of notes and pauses.
  • char notes[] = "cdfda ag cdfdg gf ";: An array of characters where each character represents a musical note, and spaces represent pauses.
  • int beats[] = {1,1,1,1,1,1,4,4,2,1,1,1,1,1,1,4,4,2};: Array defining the duration of each note or pause.
  • int tempo = 150;: Sets the tempo of the melody. Smaller values result in a faster melody.
  • Setup Function:
    • void setup(): Initializes the buzzer pin as an output.
    • pinMode(buzzerPin, OUTPUT);: configures the buzzer pin for output.
  • Loop Function:
    • void loop(): Main function to play the melody.
    • duration = beats[i] * tempo;: calculates the duration for each note/pause.
    • if (notes[i] == ' '): checks if the current character is a space (pause).
    • delay(duration);: pauses for the calculated duration if it’s a space.
    • else: If it’s a note, plays the note using the tone() function.
    • tone(buzzerPin, frequency(notes[i]), duration);: plays the note at the specified frequency and duration.
    • delay(duration);: Waits for the duration of the note.
    • delay(tempo / 10);: Adds a short pause between notes.
    • while(true){}: Stops the loop once the song is played.
  • Frequency Function:
    • int frequency(char note): Function to return the frequency of a given note.
    • char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };: array of note characters.
    • int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523};: corresponding frequencies for each note.
    • The for loop checks if the note exists in the names array.
    • return(frequencies[i]);: Returns the frequency if the note is found.
    • return(0);: Returns 0 if the note is not found (although this case should not occur).

Melody Player

#include <LiquidCrystal.h>

LiquidCrystal lcd(11, 12, 2, 3, 4, 5);
const int buttonPin = 7;
const int buzzerPin = 9;

// the "Happy Birthday" melody and note durations
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_C5 523

int happyBirthdayM[] = {
  NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4, // "Happy Birthday to You"
  NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4, // --*--
  NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4, // "Happy Birthday dear [Name]"
  NOTE_AS4, NOTE_AS4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_F4 // --*--
};
int happyBirthdayND[] = {
  4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 2
};

// the "Jingle Bells" melody and note durations
int JingleBellsM[] = {
  NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_G4, NOTE_C4, NOTE_D4, NOTE_E4,
  NOTE_F4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_G4
};
int JingleBellsND[] = {
  8, 8, 4, 8, 8, 4, 8, 8, 8, 8, 2, 8, 8, 8, 8, 4, 8, 8, 8, 8, 4, 8, 8, 8, 2
};

// the melodies into arrays
int* melodyArray[] = { 
  happyBirthdayM, JingleBellsM,
};
int* noteDurations[] = {
  happyBirthdayND, JingleBellsND,
};

// names of the melodies
const char* melodyNames[] = {
  "Happy Birthday",
  "Jingle Bells"
};

void setup() {
  lcd.begin(16, 2);
  pinMode(buttonPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600);

  // display the initial melody name on the LCD
  lcd.setCursor(0, 0);
  lcd.print(melodyNames[0]);
}

void loop() {
  static int cur_element = 0;
  static bool buttonPressed = false;
  
  // read button state
  int btnState = digitalRead(buttonPin);
  
  // button press
  if (btnState == HIGH && !buttonPressed) {
    buttonPressed = true;
    
    // move to the next melody
    cur_element = playNextMelody(cur_element);
    
    // display the name of the melody on the LCD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(melodyNames[cur_element]);

    // play the selected melody
    play(melodyArray[cur_element], noteDurations[cur_element], (cur_element == 0) ? sizeof(happyBirthdayM) / sizeof(happyBirthdayM[0]) : sizeof(JingleBellsM) / sizeof(JingleBellsM[0]));
  } else if (btnState == LOW) {
    buttonPressed = false;
  }
}

int playNextMelody(int cur_element) {
  cur_element++;
  if (cur_element >= 2) {
    cur_element = 0;
  }
  return cur_element;
}

void play(int melody[], int noteDurations[], int size) {
  // iterate over the notes of the melody
  for (int thisNote = 0; thisNote < size; thisNote++) {
    // calculate the note duration
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);

    // set a minimum time between notes
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);

    // stop the tone playing
    noTone(buzzerPin);
  }
}

Arduino melody player
  • #include <LiquidCrystal.h>: includes the library for controlling the LCD.
  • LiquidCrystal lcd(11, 12, 2, 3, 4, 5);: initializes the LCD with the specified pins.
  • const int buttonPin = 7;: the pin connected to the button.
  • const int buzzerPin = 9;: the pin connected to the buzzer.
  • #define NOTE_C4 262 to #define NOTE_C5 523: fefines the frequencies of the notes used in the melodies
  • Melody Definitions:
    • Arrays happyBirthdayM and happyBirthdayND: the notes and durations for the “Happy Birthday” melody.
    • Arrays JingleBellsM and JingleBellsND: the notes and durations for the “Jingle Bells” melody.
  • Melody Arrays:
    • int* melodyArray[] = {..};: Array of pointers to the melodies.
    • int* noteDurations[] = {..};: Array of pointers to the note durations.
    • const char* melodyNames[] = {..};: Array of melody names.
  • Setup Function:
    • lcd.begin(16, 2);: Sets the LCD dimensions
    • lcd.setCursor(0, 0); lcd.print(melodyNames[0]);: Displays the name of the first melody.
  • Loop Function:
    • cur_element: Keeps track of the current melody.
    • buttonPressed: Tracks the button press state.
    • int btnState = digitalRead(buttonPin);: Reads the state of the button.
    • if (btnState == HIGH && !buttonPressed): Checks if the button is pressed.
    • buttonPressed = true;: Marks the button as pressed.
    • cur_element = playNextMelody(cur_element);: Moves to the next melody
    • lcd.clear(); lcd.setCursor(0, 0); lcd.print(melodyNames[cur_element]);: Displays the new melody name
    • play(...): Plays the selected melody
    • else if (btnState == LOW): Resets the button press state when released
  • Play Next Melody Function:
    • int playNextMelody(int cur_element): increments the melody index and reset it if it exceeds the number of melodies.
    • return cur_element;: returns the updated melody index
  • Play Function:
    • void play plays the notes of the selected melody
    • Iterates through each note, calculates its duration, and plays it using tone(buzzerPin, melody[thisNote], noteDuration)
    • Adds a delay between notes and stops the tone after each note