1

I would like to change the delay() into a nonblocking function in the code below. I've implemented it (a part of a tutorial from arduino.cc) in my code, but the delay() is blocking the rest of my code. Can anyone help me to change this?

void speelMelodie(int melodie){

if(melodie == 1){

      for (int thisNote = 0; thisNote < 8; thisNote++) {

      int noteDuration = 1000 / noteDurations1[thisNote];
      tone(speaker, melody1[thisNote], noteDuration);

      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes); // <-- this one has to be changed

      noTone(speaker);
      }
  }

else if (melodie == 2) {
      // the same part as previous part (for loop)
  }


else if (melodie == 3) {
      // the same part as previous part (for loop)
  }
}
5
  • 1
    Look at the Arduino example program, BlinkWithoutDelay (File | Examples | Digital | BlinkWithoutDelay). It uses millis() to time the length of the 'on' and 'off' periods of the LED - just what you want to do with the tone. – JRobert Mar 30 '20 at 19:18
  • Have you looked into examples and tutorials about millis()? Did you understand them? What exactly prevents you from changing your code to millis()? – chrisl Mar 30 '20 at 19:34
  • Yes I have, but I don't know how to implement this in my code. I've 5 different melodies like above fragments. – Joost Mar 30 '20 at 21:03
  • What are you trying to achieve? From your code, it looks like you play a tone and then you pause for some milliseconds (i.e. silence) and then play the next tone. If that is the case, how millis() will help or what delay is blocking? – Fahad Mar 31 '20 at 8:39
  • @Fahad , I have a lot of other code, I call this function. but due to the delay in this function I can't do with the rest of my inputs outside of this function. – Joost Mar 31 '20 at 13:15
0

Define global vars befor setup()

unsigned long timeStamp = 0; 
bool pauseOn = false;

and use it

void speelMelodie(int melodie) {

  if (melodie == 1) {

    for (int thisNote = 0; thisNote < 8; thisNote++) {

      int noteDuration = 1000 / noteDurations1[thisNote];
      if (millis() - timeStamp < noteDuration && pauseOn == false) {
         tone(speaker, melody1[thisNote], noteDuration);
      } else { // reset value and change pauseOn to true
        pauseOn = true;
        timeStamp = millis();
      }
      int pauseBetweenNotes = noteDuration * 1.30;

      //delay(pauseBetweenNotes); // <-- this one has to be changed
      if (millis() - timeStamp < pauseBetweenNotes && pauseOn == true) {
          noTone(speaker);
      } else {
         pauseOn = false;
         timeStamp = millis();
      }
    }
  }
}

We need the state variable pauseOn to differentiate between the two states play note or silence. The code compiles, but you have to finetune in your program.
A final tip Tutorials using delay() other than

  • for debuging or
  • in setup for initializing hardware

are of very low quality
-> Its like a blind person talking about color composition.

10
  • Thanks for this, but I get only two notes now. – Joost Mar 31 '20 at 9:49
  • 1
    Post your code completely by editing your question -its hard to find errors in fragments perhaps unrelated to the real problem – Codebreaker007 Mar 31 '20 at 9:54
  • This is a part of a function that I call elsewhere, so it should be in this part. The whole code is very big. – Joost Mar 31 '20 at 9:58
  • Then you have to find it on your own. Now the function is non blocking and as we do not know the rest code it can be caused anywhere (check for other delay() and get rid of them) aso at least give the complete function if you want any further help (and the libs needed - just the include part and the global vars used in the function) – Codebreaker007 Mar 31 '20 at 10:27
  • Allright. I will try it by myself first. Otherwise, when i'm stucking, I'll ask you for help. – Joost Mar 31 '20 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.