Piezo Buzzer: Playing melody without using delay

Many newbies got trouble playing the melody using the piezo buzzer because the example code from Arduino IDE uses the delay() function. Playing melody in that way blocks other code. Therefore, I have made a ezBuzzer library that supports beeping and playing melody without using delay().

The below example code uses two buttons: one to start playing the melody, the other to stop playing the melody.

#include <ezBuzzer.h> // ezBuzzer library

const int START_BUTTON_PIN = 7;
const int STOP_BUTTON_PIN  = 8;
const int BUZZER_PIN = 3;

int lastStartButtonState = HIGH; // the previous state from the input pin
int lastStopButtonState  = HIGH; // the previous state from the input pin

ezBuzzer buzzer(BUZZER_PIN); // create ezBuzzer object that attach to a pin;

// notes in the melody:
int melody[] = {
  NOTE_E5, NOTE_E5, NOTE_E5,
  NOTE_E5, NOTE_E5, NOTE_E5,
  NOTE_E5, NOTE_G5, NOTE_C5, NOTE_D5,
  NOTE_E5,
  NOTE_F5, NOTE_F5, NOTE_F5, NOTE_F5,
  NOTE_F5, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_E5,
  NOTE_E5, NOTE_D5, NOTE_D5, NOTE_E5,
  NOTE_D5, NOTE_G5
};

// note durations: 4 = quarter note, 8 = eighth note, etc, also called tempo:
int noteDurations[] = {
  8, 8, 4,
  8, 8, 4,
  8, 8, 8, 8,
  2,
  8, 8, 8, 8,
  8, 8, 8, 16, 16,
  8, 8, 8, 8,
  4, 4
};

void setup() {
  Serial.begin(9600);
  pinMode(START_BUTTON_PIN, INPUT_PULLUP);
  pinMode(STOP_BUTTON_PIN,  INPUT_PULLUP);
}

void loop() {
  buzzer.loop(); // MUST call the buzzer.loop() function in loop()

  int startButtonState = digitalRead(START_BUTTON_PIN);
  int stopButtonState  = digitalRead(STOP_BUTTON_PIN);

  if (lastStartButtonState == HIGH && startButtonState == LOW) {
    Serial.println("The START button is pressed");
    if (buzzer.getState() == BUZZER_IDLE) {
      int length = sizeof(noteDurations) / sizeof(int);
      buzzer.playMelody(melody, noteDurations, length); // playing
    }
  }

  if (lastStopButtonState == HIGH && stopButtonState == LOW) {
    Serial.println("The STOP button is pressed");
    if (buzzer.getState() != BUZZER_IDLE) {
      buzzer.stop() ; // stop
    }
  }

  lastStartButtonState = startButtonState;
  lastStopButtonState  = stopButtonState;
}

And this is another example: Keypad - beeping on key press

hmmm looks good, I will try it out. Btw what you have used instead of delays in Arduino IDE ??

I used millis() instead of delay()

vishkas:
Interesting work. Keep it up

Thank you

You don't have to put that extra cast of (unsigned long) in it.
These are okay:

if ((millis() - _startTime) >= _delayTime) {
if (millis() - _startTime >= _delayTime) {

Which IDE or editor do you use ?

I put a link on this page at the bottom: GitHub - Koepel/Fun_with_millis: Small Arduino examples using the millis() function..

Can you extend it to accept melodies in PROGMEM ?

Dear @Koepel,

Thank you.
I just used notepad++ for coding and Arduino IDE for compiling and uploading.
For extending it to accept melodies in PROGMEM, This is a great idea. I will added in the next version.
Best regards,

The library looks great. Will try it at some point in time. Really will be useful to many of the Arduino enthusiasts. What is Flexible PCB? Definition, Material & Manufacturing - The Engineering Projects

Great project. Can you explain the things that are used on brief

vishkas:
Great project. Can you explain the things that are used on brief

I used millis() function instead of delay() to avoid blocking other code. You can take a look to my source code on GitHub to see the detail

Thank you very much for this decision! It helped me a lot!

Tell me, how can I set the pause I need after playing the melody, so that it will be played again later? Is there a function for this?

Also, can I set the speed of the melody without changing the duration of the notes?

Thank you.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.