Decremental period piezo buzzer without delay

I am making a C4 prop and I want to create decremental beeps. However, I would like to do this without using delay.

  int beepDelay = 1000;
  while (beepDelay > 46) {
    Serial.println(beepDelay);
    tone(buzzerPin, 2500);
    ledRed();
    delay(100);
    ledOff();
    noTone(buzzerPin);
    delay(beepDelay);
    beepDelay -= 15;
  }

Currently this is how I got it to work, but I really could not figure out how to do this with the millis() function.

I have avoided the built-in duration capability of the tone() function since, for example, if you wanted a 100ms long beep with 15ms gaps,

tone(buzzerPin, 2500, 100);
delay(15);
tone(buzzerPin, 2500, 100);
delay(15);
tone(buzzerPin, 2500, 100);
.
.
.

does not work since the program doesn't pause for the beep, so the next beep is already triggered before 115 ms passes. This has caused problems when I attempted to implement this with the millis() function as well.

Any help is greatly appreciated.

Welcome

Did you look at the Blink Without Delay example ?

Here is an example using a simple "finite state machine" : t1121651 - Wokwi Arduino and ESP32 Simulator

The trick is to dump the while loops, dump delay() entirely, use the actual loop() function as your loop, and keep track of times. I cheat a bit using timeObj library because I hate dealing with all the millis() nonsense myself.

-jim lee

Hello selimkaraca

Welcome to the worldbest forum.

Do you are able to provide a small sound example?

I might have a look into my sketch box to find an example for you.

Have a nice day and enjoy coding in C++.

Thanks, that looks good.
Would it be possible to do this without using loop() as my main loop though?

Hey Paul, @jimLee recreated exactly what I wanted in wokwi. You can have a listen on there.
https://wokwi.com/projects/363497028428189697

Consider

constexpr uint8_t BuzzerPins{8};
constexpr uint32_t IntervalMillis[] {15,100};
constexpr uint32_t Frequency[] {0,2500};
uint32_t previousMillis;
uint8_t selector;
void setup() {}
void loop() 
{
  if (millis()-previousMillis >= IntervalMillis[selector])
  {
    previousMillis=millis();
    selector=selector?LOW:HIGH;
    tone(BuzzerPins,Frequency[selector]);
  }
}