My buzzer don't want to stop midway

So I have a project and my buzzer needs to play music. When the button is pressed the first time, it will play, and the second time, the buzzer will stop. The problem is that my buzzer won't stop playing on the second button push or is delayed. Why is that?

int buz2 = 6;
int on = 7;
int ons;
int val = 0;

//tunes
int c = 262;
int d = 294;
int e = 330;
int f = 349;
int g = 392;
int a = 440;
int b = 494;
int C = 523;

void setup() {
  pinMode(buz2, OUTPUT);
}
void loop() {
  ons = digitalRead(on);
  if(ons == LOW){
    val++;
    delay(50);
  }

  if (val == 1) {
    buzzer();
    delay(100);
  }
  else {
    val = 0;
    noTone(buz2);
    digitalWrite(buz2, LOW);
  }
}

void buzzer() {

  tone(buz2, f, 120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, f, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, f, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, f, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, f, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, f, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  //new
  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  //new
  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, e, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, e, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, e, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, e, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, e, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, a, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, c, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, e, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  //new
  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, g, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, b, 120);
  delay(120);
  noTone(buz2);
  delay(120);

  tone(buz2, d, 120);
  delay(120);
  noTone(buz2);
  delay(120);
}

The buzzer() function has numerous delay()s in it so it takes a long time to return to the loop() function where you read the buttons

Yo need to think about a different way to play the sequence of notes so that you can read the input more frequently, at least between each note

One very clumsy way would be to call a function to read the input before playing each note. This would increase the amount of code considerably

A better strategy would be to do the same but have the note data held in an array so that you can iterate through them using a for loop. This would require considerably less code than even your current sketch

2 Likes

To expand on this, you could do the timing with millis() so the process of playing the tune doesn't block execution of other code.

In the example below you would call play_tune() in each iteration of the loop. The play_tune() function goes from one note to the next, pausing between notes. It does this by keeping track of which note it is playing, as well as how long ago a note was started or stopped.

The function will return true while it is playing the tune. As soon as it returns false, you know the tune is done and you don't need to call the function anymore. (In fact, I did not keep into account the situation where the function is called after it has returned false once. You'd have to catch that if you intend to do this).

If you want to restart the tune, set the tune_current_note to 0 and call play_tune(). It should then start over the whole cycle.

#define a    440
#define b    494
#define c    262
#define d    294
(etc...)

#define NOTE_DURATION 120
#define PAUSE_BETWEEN_NOTES 120

int tune[] = {f, a, c, ...};
int tune_current_note = 0;
bool tone_playing = false;
unsigned long tune_last_event;

void setup () {
    [insert setup code here]
}

void loop () {
   [loop code goes here]
   if (play_tune()) {
     //Tune still playing because it returned true
   }
   else {
     //Tune is done because the function returned false
   }
}

bool play_tune () {
  if (tone_playing) {
    if (millis() - tune_last_event > NOTE_DURATION) {
      noTone(buz2);  //End of tone; silence the buzzer
      tone_playing = false;
      tune_last_event = millis();
      tune_current_note ++;  //Next note
      if (tune_current_note >= sizeof(tune)/sizeof(tune[0])) {
        return false; //Done playing this tune
      }
      else {
        return true; //There's another note coming in our tune
      }
    }
    else {
      return true; //Waiting for tone to finish
    }
  }
  else { //This is the pause between notes, or the start of the first note
     if (millis() - tune_last_event > PAUSE_BETWEEN_NOTES || tune_current_note == 0) {
       //Pause is over; start next note
       tone (buz1, tune[tune_current_note]);
       tone_playing = true;
       tune_last_event = millis();
    }
  }
  return true;
}

Note: the above is for illustration purposes and the code is untested and is virtually guaranteed to contain bugs. It is only intended to show the logic behind doing this in a non-blocking way. To make it work, you'd have to debug and test it - or (better) adopt this logic or whatever parts you like about it and write your own version that does exactly what you want/need.

1 Like

So which is it...............?

No button... just the tune...

int buz2 = 6;
int a3 = 220, b3 = 247, c4 = 262, d4 = 294, e4 = 330, f4 = 349, g4 = 392, a4 = 440, b4 = 494, c5 = 523, d5 = 587;

int aria[] = { // key
  a3, c4, e4,  // Am
  b3, d4, f4,  // B
  c4, e4, g4,  // C
  d4, f4, a4,  // Dm
  e4, g4, b4,  // Em
  f4, a4, c5,  // F
  g4, b4, d5,  // G
};

void setup() {
  Serial.begin(115200);
  pinMode(buz2, OUTPUT);
}

void loop() {
  for (int key = 0; key < 7; key++) {
    for (int j = 0; j < 6; j++) {
      for (int note = 0; note < 3; note++) {
        tone(buz2, aria[key * 3 + note], 120);
        delay(120);
        noTone(buz2);
        delay(120);
      }
    }
  }
}

Files for WOKWI.com.

sketch.ino (click me)
// https://forum.arduino.cc/t/my-buzzer-dont-want-to-stop-midway/1251863/3

int buz = 6, red = 5, grn = 3, blu = 2;
int a3 = 220, b3 = 247, c4 = 262, d4 = 294, e4 = 330, f4 = 349, g4 = 392, a4 = 440, b4 = 494, c5 = 523, d5 = 587;

int aria[] = { // key
  a3, c4, e4,  // Am
  b3, d4, f4,  // B
  c4, e4, g4,  // C
  d4, f4, a4,  // Dm
  e4, g4, b4,  // Em
  f4, a4, c5,  // F
  g4, b4, d5,  // G
};

void setup() {
  Serial.begin(115200);
  pinMode(buz, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(grn, OUTPUT);
  pinMode(blu, OUTPUT);
}

void loop() {
  for (int key = 0; key < 7; key++) {
    for (int j = 0; j < 6; j++) {
      for (int note = 0; note < 3; note++) {
        digitalWrite(red, note == 0);
        digitalWrite(grn, note == 1);
        digitalWrite(blu, note == 2);
        tone(buz, aria[key * 3 + note], 120);
        delay(120);
        noTone(buz);
        delay(120);
      }
    }
  }
}
diagram.json (click me)
{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    {
      "type": "wokwi-arduino-nano",
      "id": "nano",
      "top": -6.6,
      "left": -75.3,
      "rotate": 90,
      "attrs": {}
    },
    {
      "type": "wokwi-buzzer",
      "id": "bz1",
      "top": -41.1,
      "left": 71.7,
      "rotate": 90,
      "attrs": { "volume": "0.1" }
    },
    {
      "type": "wokwi-pushbutton",
      "id": "btn1",
      "top": 63.8,
      "left": 67.2,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-rgb-led",
      "id": "rgb1",
      "top": 4.8,
      "left": 63.3,
      "rotate": 90,
      "attrs": { "common": "cathode" }
    }
  ],
  "connections": [
    [ "nano:GND.2", "btn1:2.l", "black", [ "h19.2", "v28.6" ] ],
    [ "nano:6", "bz1:2", "#8f4814", [ "h0" ] ],
    [ "nano:7", "btn1:1.l", "orange", [ "h9.6", "v28.8" ] ],
    [ "nano:GND.2", "bz1:1", "black", [ "h19.2", "v-71.7" ] ],
    [ "nano:GND.2", "rgb1:COM", "black", [ "h19.2", "v-48.9" ] ],
    [ "rgb1:B", "nano:2", "green", [ "h0" ] ],
    [ "nano:3", "rgb1:G", "green", [ "v0", "h38.4" ] ],
    [ "rgb1:R", "nano:5", "green", [ "v0" ] ]
  ],
  "dependencies": {}
}

123

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