When .WAV Sound is Playing, My Clock is Stopping

Hello everyone. I am new here. So I hope I can choose the right topic for my problem.

My project is ringing clock with using lcd display, sd card, rtc and speaker.

I want to play the .wav sound for example when clock is 18.00 pm. Until 18.00 on my lcd display the clock is normally working. But when the sound begining to play, clock is freezing and not working until the sound finishes. After the sound finish, clock is working normally again.

I hope I can explain clearly. Sorry for my English :slight_smile:

So how can I fix this guys?

Here is my code:

#include <SimpleSDAudio.h>
#include <virtuabotixRTC.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

int CLK_PIN = 6;
int DAT_PIN = 7;
int RST_PIN = 8;

virtuabotixRTC myRTC(CLK_PIN, DAT_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
//myRTC.setDS1302Time(00,47,16,2,14,04,2020);
lcd.begin();

SdPlay.setSDCSPin(4);
if(!SdPlay.init(SSDA_MODE_HALFRATE | SSDA_MODE_MONO | SSDA_MODE_AUTOWORKER)){
while(1);
}

}

void loop() {

myRTC.updateTime();

lcd.clear();
lcd.setCursor(0,0);
lcd.print(myRTC.dayofmonth);
lcd.print("/");
lcd.print(myRTC.month);
lcd.print("/");
lcd.print(myRTC.year);
lcd.setCursor(0,1);
lcd.print(myRTC.hours);
lcd.print(":");
lcd.print(myRTC.minutes);
lcd.print(":");
lcd.print(myRTC.seconds);
delay(1000);

if(myRTC.hours == 17 && myRTC.minutes == 30){
if(!SdPlay.setFile("ezan.wav")){
while(1);
}
SdPlay.play();
myRTC.updateTime();

while(!SdPlay.isStopped()){
;
}
}

}

When .WAV Sound is Playing, My Clock is Stopping

That doesn't surprise me... The processor can only execute one instruction at a time and playing sound is very software-intensive, especially on a microcontroller without a DAC.

There might be possible to update the clock between audio samples but it would be tricky and I'm not sure if the Arduino is fast enough for that. I assume you'd have to modify the sound library.

The tone() function will run in the background and there is plenty of time between notes to update the clock. Plus, you'd get better sound quality.


...On a computer with a multitasking operating system, quick bursts of audio are written to a buffer (dedicated memory, like a storage tank or like a long-pipe). The audio data comes out of the buffer and into the DAC at a smooth-constant rate while the processor does something else. The soundcard has it's own independent clock so it doesn't have to rely on the processor. When the operating system gets around to it, the buffer is re-filled. (There is also a recording buffer which works the opposite way... The audio data comes-in at a smooth-constant rate and it's read in a quick burst.)

An audio shield for the Arduino will do everything (even more than a computer soundcard) so all the Arduino has to do is start & stop the sound.

This is an easy one, don't block waiting for the playing to end, ie remove this bit:

  if(myRTC.hours == 17 && myRTC.minutes == 30){
   if(!SdPlay.setFile("ezan.wav")){ 
         while(1);
      }
      SdPlay.play();
      myRTC.updateTime();

      while(!SdPlay.isStopped()){
        ;
      }
  }

and replace it with a non-blocking version:

  static bool playing = false ;
  if(!playing && myRTC.hours == 17 && myRTC.minutes == 30)
  {
    if(!SdPlay.setFile("ezan.wav"))
    { 
      while(1)
      {}
    }
    SdPlay.play();
    playing = true ;
  }
  if (playing && SdPlay.isStopped())
  {
    playing = false ;
  }

No blocking so the clock code gets to run as loop is still being called over and over as its supposed to.