ESP8266 NodeMCU – Create a Melody

This tutorial will show you how to play a melody with a passive buzzer. If you need an introduction on how to start with buzzers, you can check the tutorial “ESP8266 NodeMCU – Make some noise with buzzers“. Here you will learn how to impress Mozart.

Parts Required

To build the global setup you must have the following parts:

Note: You do not need to have a NodeMCU board nor an ESP8266 to follow this tutorial. I am using this board because it is very famous and also because I will post future tutorials using wifi communications. In order to use other boards, you just have to change the pin number.

Push-Button and Pull Down Resistor

Figure 1

For a better understanding, let’s consider Figure 1. A Push-Button is a simple mechanism, that allows you to connect point A with point B. Thus, each time you press the button you connect pin D5 to GND. We will use this button, to trigger an interrupt. An interrupt is an event that occurs randomly in the middle of the program. It is just like a call you have when you are busy with some work. When the button is not pressed, the pin D5 must be connected. That’s why we activate in the code, an internal “Pull-Up” resistor. Therefore, the microcontroller always knows the logic value of the pin.

Circuit

Connect the buzzer to GPIO pin 2 (D4) and the button to GPIO pin 14 (D5) as shown in figure 2. The setup will get power from your PC using micro-USB to USB cable. The buzzer can use an external source of power, but for that, we would need more parts. In this configuration, the power came directly from the GPIO pins.

Coding

This code will use a header file with the notes and their frequencies. Such notes, go to a vector organized according to the music you want. To start and stop the melody whenever you want we will use the button, that is connected to an interrupt pin. NodeMCU based ESP8266 has an interrupt feature on its GPIO pins. This function is available on D0-D8 pins. Copy the main sketch below to your Arduino IDE project and save it.

Note: Unplug the buzzers before downloading the sketch, or place a capacitor in series with the buzzer to prevent a short-circuit while the ESP8266 is resetting. This happens because the buzzer internal resistance is low.

#include "ALL_NOTES.h"

#define buzzer 2
#define interruptPin 5
#define built_in_led 16

char Counter = 0;

// Now read the music sheet and put the notes inside the vector:
char Happy_Birthday [] = {G3, G3, A3, G3, C3, B3, G3, G3, A3, G3, D3, C3, G3, G3, G3, E3, C3, B3, A3, F3, F3, E3, C3, D3, C3};

// Build one vector for each melody with note durations: 4 = quarter note, 8 = eighth note, etc.:
char Birthday_Durations[] = { 4, 4, 3, 4, 1, 2, 4, 4, 3, 4, 2, 1, 4, 4, 5, 3, 1, 2, 3, 4, 4, 3, 1, 2, 1};

void setup() {

pinMode(buzzer,OUTPUT);
pinMode(built_in_led,OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), ISR, FALLING);
}

void loop() {

  //Led On while the buzzer is off
  digitalWrite(built_in_led,LOW);
  }

void play_melody() {

     //Led OFF while the buzzer is on
     digitalWrite(built_in_led,HIGH);

    // iterate over the notes of the melody:
  for (char NOTE_i = 0; sizeof(Happy_Birthday); NOTE_i ++) {

    // to calculate the note duration, take one second divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    
    int note_Duration = 1000 / Birthday_Durations[NOTE_i];
    tone(buzzer, Happy_Birthday[NOTE_i], note_Duration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    
    int pause_Between_Notes = note_Duration * 1.30;
    delay(pause_Between_Notes);
  }
}

void ISR() {
  
  Counter++;
  if(Counter == 1)
     play_melody();
     
  else if (Counter > 1){
    Counter = 0;
    // stop the tone playing in D4:
    noTone(buzzer);
    }
}

The code above uses a header file, ALL_NOTES.h. This file contains all the pitch values for typical notes and was based in the table originally written by Brett Hagman. Thus, each time you want to make a melody, just have to directly choose the notes from the ALL_NOTES.h file. To create this file, click on “New Tab” as shown in Figure 3.

Figure 3

That will open a blank page, then paste in the following code.

// The notes are in the "english and dutch" convention.
// For exemple: B0 is the european Si

#define B0  31
#define C1  33
#define CS1 35
#define D1  37
#define DS1 39
#define E1  41
#define F1  44
#define FS1 46
#define G1  49
#define GS1 52
#define A1  55
#define AS1 58
#define B1  62
#define C2  65
#define CS2 69
#define D2  73
#define DS2 78
#define E2  82
#define F2  87
#define FS2 93
#define G2  98
#define GS2 104
#define A2  110
#define AS2 117
#define B2  123
#define C3  131
#define CS3 139
#define D3  147
#define DS3 156
#define E3  165
#define F3  175
#define FS3 185
#define G3  196
#define GS3 208
#define A3  220
#define AS3 233
#define B3  247
#define C4  262
#define CS4 277
#define D4  294
#define DS4 311
#define E4  330
#define F4  349
#define FS4 370
#define G4  392
#define GS4 415
#define A4  440
#define AS4 466
#define B4  494
#define C5  523
#define CS5 554
#define D5  587
#define DS5 622
#define E5  659
#define F5  698
#define FS5 740
#define G5  784
#define GS5 831
#define A5  880
#define AS5 932
#define B5  988
#define C6  1047
#define CS6 1109
#define D6  1175
#define DS6 1245
#define E6  1319
#define F6  1397
#define FS6 1480
#define G6  1568
#define GS6 1661
#define A6  1760
#define AS6 1865
#define B6  1976
#define C7  2093
#define CS7 2217
#define D7  2349
#define DS7 2489
#define E7  2637
#define F7  2794
#define FS7 2960
#define G7  3136
#define GS7 3322
#define A7  3520
#define AS7 3729
#define B7  3951
#define C8  4186
#define CS8 4435
#define D8  4699
#define DS8 4978

Connect your ESP8266 NodeMCU to your PC using micro-usb to usb cable and upload the code.

1 thought on “ESP8266 NodeMCU – Create a Melody

Leave a Reply

Your email address will not be published. Required fields are marked *