i have a chime mp3 and bell mp3 and wanted to play chime sound at the start of a new hour and play bell sound followed by chime that equal to the number of hour in ds1307 rtc. i made a code but it plays the bell sound only once and not followed equal to the number of hour condition...
#include <Arduino.h>
#include <Wire.h>
#include "RTClib.h"
#include "AudioFileSourceSPIFFS.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"
RTC_DS1307 rtc;
AudioGeneratorMP3 *mp3;
AudioGeneratorMP3 *bell;
AudioFileSourceSPIFFS *file;
AudioFileSourceID3 *id3;
AudioOutputI2SNoDAC *out;
const char *mp3Files[] = {"/chime.mp3", "/bell.mp3"};
int currentFileIndex = 0;
int currentHour = -1; // Variable to keep track of the current hour
void setup()
{
Serial.begin(115200);
delay(1000);
Serial.printf("MP3 start\n");
Wire.begin();
rtc.begin();
// Uncomment the following line if you need to set the initial time on the RTC
// rtc.adjust(DateTime(__DATE__, __TIME__));
audioLogger = &Serial;
SPIFFS.begin();
out = new AudioOutputI2SNoDAC();
mp3 = new AudioGeneratorMP3();
bell = new AudioGeneratorMP3(); // Initialize bell sound generator
}
void loop()
{
DateTime now = rtc.now();
// Calculate the time until the next hour
int minutesUntilNextHour = 60 - now.minute();
// Check if it's the beginning of a new hour
if (now.minute() == 0 && now.second() == 0)
{
// Update the current hour
currentHour = now.hour();
// Play the chime sound at the beginning of the hour
if (currentFileIndex < sizeof(mp3Files) / sizeof(mp3Files[0]))
{
Serial.println("Playing chime sound");
const char *mp3FileName = mp3Files[currentFileIndex];
file = new AudioFileSourceSPIFFS(mp3FileName);
id3 = new AudioFileSourceID3(file);
id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
mp3->begin(id3, out);
currentFileIndex++;
}
}
// Check if audio playback is complete for chime sound
if (mp3->isRunning())
{
if (!mp3->loop())
{
mp3->stop();
delete mp3;
delete out;
delete id3;
delete file;
}
}
// Play the bell sound for the number of hours equal to the current hour
if (currentHour >= 0)
{
for (int i = 0; i < currentHour; i++)
{
Serial.println("Playing bell sound");
const char *bellFileName = mp3Files[1]; // bell.mp3
file = new AudioFileSourceSPIFFS(bellFileName);
id3 = new AudioFileSourceID3(file);
id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
bell->begin(id3, out);
// Wait for 500ms before playing the next bell sound
delay(500);
// Stop and clean up the bell sound player
bell->stop();
delete id3;
delete file;
}
// Reset the current hour
currentHour = -1;
}
// Delay until the next hour
delay(minutesUntilNextHour * 60 * 1000);
}
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
(void)cbData;
Serial.printf("ID3 callback for: %s = '", type);
if (isUnicode)
{
string += 2;
}
while (*string)
{
char a = *(string++);
if (isUnicode)
{
string++;
}
Serial.printf("%c", a);
}
Serial.printf("'\n");
Serial.flush();
}
Reading the code...... If the hour is >= zero, do this:
Loop over the number of hours for their chimes.
Serial.print.....
Pick up the pointer to chime number one regardless of the hour.....
Not picking up the pointer to chime_2, chime_3 etc.?
What is the purpose of the line currentFileIndex++;? The first time through that if, it has the value 0 and so will reference "/chime.mp3". The second time through the if, it will have the value 1 and so will reference "/bell.mp3". After that, the if will never be entered because currentFileIndex has the value 2 and is no longer less than the number of elements in mp3files. I'm getting a faint ChatGPT generated code vibe.
i am a noob in the world of Arduino coding and i am takeing the help of chatgpt to generate the code but unfortunately the code not working as my requirement. i want to play chime sound in the beginning of every hour and also wanted to play bell sound followed by chime sound and the bell sound will indicate the number of hour by playing equal number of times in rtc clock. please help me to complete this project....
No problem, I can guide you through the code. Here is an updated code that should help you achieve your desired functionality:
#include <Arduino.h>
#include <Wire.h>
#include "RTClib.h"
#include "AudioFileSourceSPIFFS.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"
RTC_DS1307 rtc;
AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioFileSourceID3 *id3;
AudioOutputI2SNoDAC *out;
const char *mp3Files[] = {"/chime.mp3", "/bell.mp3"};
int currentFileIndex = 0; // Index to keep track of the current file being processed
int currentHour = -1; // Variable to keep track of the current hour
int bellCount = 0; // Variable to keep track of the number of times the bell sound has been played
void setup()
{
Serial.begin(115200);
delay(1000);
Serial.printf("MP3 start\n");
Wire.begin();
rtc.begin();
// Uncomment the following line if you need to set the initial time on the RTC
// rtc.adjust(DateTime(__DATE__, __TIME__));
audioLogger = &Serial;
SPIFFS.begin();
out = new AudioOutputI2SNoDAC();
mp3 = new AudioGeneratorMP3();
}
void loop()
{
DateTime now = rtc.now();
// Check if it's the beginning of a new hour
if (now.minute() == 0 && now.second() == 0)
{
// Update the current hour
currentHour = now.hour();
// Reset the bell count
bellCount = 0;
// Play the chime sound at the beginning of the hour
if (currentFileIndex < sizeof(mp3Files) / sizeof(mp3Files[0]))
{
Serial.println("Playing chime sound");
const char *mp3FileName = mp3Files[currentFileIndex];
file = new AudioFileSourceSPIFFS(mp3FileName);
id3 = new AudioFileSourceID3(file);
id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
mp3->begin(id3, out);
currentFileIndex++;
}
}
// Check if audio playback is complete
if (mp3->isRunning())
{
if (!mp3->loop())
{
mp3->stop();
delete mp3;
delete id3;
delete file;
out->stop();
out->reset();
delete out;
}
}
else
{
// Check if it's time to play the bell sound
if (currentHour >= 0 && bellCount < currentHour)
{
const char *bellFileName = mp3Files[1];
file = new AudioFileSourceSPIFFS(bellFileName);
id3 = new AudioFileSourceID3(file);
id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
mp3->begin(id3, out);
bellCount++;
}
}
// Delay until the next second
delay(1000);
}
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
(void)cbData;
Serial.printf("ID3 callback for: %s = '", type);
if (isUnicode)
{
string += 2;
}
while (*string)
{
char a = *(string++);
if (isUnicode)
{
string++;
}
Serial.printf("%c", a);
}
Serial.printf("'\n");
Serial.flush();
}
The main change is that in the loop(), we added an else statement after the check for audio playback completion. We only want to play the bell sound if the chime sound is not playing. Within this else statement, we added another if statement to make sure that we only play the bell sound if it needs to be played. We also added a variable to keep track of how many times the bell sound has been played.
I hope this code helps you achieve your desired functionality. Let me know if you have any questions.
This error means that you are using a member function called reset that does not exist in the AudioOutputI2SNoDAC class. You should check the documentation and look for a different method or class that has the functionality you need. Make sure all libraries are properly included and there are no syntax errors.