Previous, low voltage sleep
This commit is contained in:
parent
5814a73f50
commit
83b5e1c5e9
|
|
@ -1,11 +1,11 @@
|
|||
#include "DirectoryNode.h"
|
||||
|
||||
|
||||
DirectoryNode::DirectoryNode(const String &nodeName)
|
||||
: name(nodeName), currentPlaying(nullptr) {
|
||||
id = DirectoryNode::idCounter;
|
||||
DirectoryNode::idCounter++;
|
||||
}
|
||||
: name(nodeName), currentPlaying(nullptr)
|
||||
{
|
||||
id = DirectoryNode::idCounter;
|
||||
DirectoryNode::idCounter++;
|
||||
}
|
||||
|
||||
DirectoryNode::~DirectoryNode()
|
||||
{
|
||||
|
|
@ -15,7 +15,6 @@ DirectoryNode::~DirectoryNode()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const uint16_t DirectoryNode::getId() const
|
||||
{
|
||||
return id;
|
||||
|
|
@ -39,8 +38,10 @@ const std::vector<String> &DirectoryNode::getMP3Files() const
|
|||
void DirectoryNode::setCurrentPlaying(const String *mp3File)
|
||||
{
|
||||
currentPlaying = mp3File;
|
||||
for (int i=0;i<mp3Files.size();i++) {
|
||||
if (mp3Files[i] == *mp3File && ids.size()>i) {
|
||||
for (int i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (mp3Files[i] == *mp3File && ids.size() > i)
|
||||
{
|
||||
currentPlayingId = ids[i];
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +57,8 @@ const uint16_t DirectoryNode::getCurrentPlayingId() const
|
|||
return currentPlayingId;
|
||||
}
|
||||
|
||||
uint16_t DirectoryNode::getNextId() {
|
||||
uint16_t DirectoryNode::getNextId()
|
||||
{
|
||||
uint16_t next = DirectoryNode::idCounter;
|
||||
DirectoryNode::idCounter++;
|
||||
return next;
|
||||
|
|
@ -70,14 +72,16 @@ void DirectoryNode::addSubdirectory(DirectoryNode *subdirectory)
|
|||
void DirectoryNode::addMP3File(const String &mp3File)
|
||||
{
|
||||
mp3Files.push_back(mp3File);
|
||||
ids.push_back(getNextId());
|
||||
ids.push_back(getNextId());
|
||||
}
|
||||
|
||||
void DirectoryNode::setSecondsPlayed(const uint32_t seconds) {
|
||||
void DirectoryNode::setSecondsPlayed(const uint32_t seconds)
|
||||
{
|
||||
secondsPlayed = seconds;
|
||||
}
|
||||
|
||||
uint32_t DirectoryNode::getSecondsPlayed() {
|
||||
uint32_t DirectoryNode::getSecondsPlayed()
|
||||
{
|
||||
return secondsPlayed;
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +96,7 @@ void DirectoryNode::buildDirectoryTree(const char *currentPath)
|
|||
break;
|
||||
}
|
||||
|
||||
if (entry.isDirectory() && entry.name()[0] != '.' && strcmp(entry.name(),sys_dir.c_str()))
|
||||
if (entry.isDirectory() && entry.name()[0] != '.' && strcmp(entry.name(), sys_dir.c_str()))
|
||||
{
|
||||
DirectoryNode *newNode = new DirectoryNode(entry.name());
|
||||
subdirectories.push_back(newNode);
|
||||
|
|
@ -153,20 +157,23 @@ DirectoryNode *DirectoryNode::findFirstDirectoryWithMP3s()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void DirectoryNode::advanceToFirstMP3InThisNode() {
|
||||
if (mp3Files.size()>0) {
|
||||
void DirectoryNode::advanceToFirstMP3InThisNode()
|
||||
{
|
||||
if (mp3Files.size() > 0)
|
||||
{
|
||||
setCurrentPlaying(&mp3Files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DirectoryNode* DirectoryNode::advanceToMP3(const uint16_t id) {
|
||||
for (auto subdir : subdirectories)
|
||||
DirectoryNode *DirectoryNode::advanceToMP3(const uint16_t id)
|
||||
{
|
||||
for (auto subdir : subdirectories)
|
||||
{
|
||||
if (subdir->getId()==id) {
|
||||
if (subdir->getId() == id)
|
||||
{
|
||||
subdir->advanceToFirstMP3InThisNode();
|
||||
return subdir;
|
||||
}
|
||||
}
|
||||
|
||||
// Have each subdirectory advance its song
|
||||
for (size_t i = 0; i < subdir->ids.size(); i++)
|
||||
|
|
@ -179,8 +186,7 @@ for (auto subdir : subdirectories)
|
|||
subdir->currentPlaying = &subdir->mp3Files[i];
|
||||
subdir->currentPlayingId = id;
|
||||
return subdir;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -191,14 +197,15 @@ for (auto subdir : subdirectories)
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
DirectoryNode* DirectoryNode::advanceToMP3(const String* currentGlobal) {
|
||||
DirectoryNode *DirectoryNode::advanceToMP3(const String *currentGlobal)
|
||||
{
|
||||
for (auto subdir : subdirectories)
|
||||
{
|
||||
if (subdir->getName()==*currentGlobal) {
|
||||
if (subdir->getName() == *currentGlobal)
|
||||
{
|
||||
subdir->advanceToFirstMP3InThisNode();
|
||||
return subdir;
|
||||
}
|
||||
}
|
||||
|
||||
// Have each subdirectory advance its song
|
||||
for (size_t i = 0; i < subdir->mp3Files.size(); i++)
|
||||
|
|
@ -210,8 +217,7 @@ DirectoryNode* DirectoryNode::advanceToMP3(const String* currentGlobal) {
|
|||
{
|
||||
subdir->setCurrentPlaying(&subdir->mp3Files[i]);
|
||||
return subdir;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -222,7 +228,50 @@ DirectoryNode* DirectoryNode::advanceToMP3(const String* currentGlobal) {
|
|||
return this;
|
||||
}
|
||||
|
||||
DirectoryNode* DirectoryNode::advanceToNextMP3(const String* currentGlobal)
|
||||
/**
|
||||
* Moves to the previous MP3 file in the directory.
|
||||
* If the current song has been playing for more than a specific threshold, restarts the current song.
|
||||
* If the current song has just started, or it's the first song, moves to the previous song in the directory.
|
||||
*
|
||||
* @param thresholdSeconds The number of seconds to decide whether to restart the current song or go to the previous song.
|
||||
* @return A pointer to the DirectoryNode where the new current song is located, or nullptr if there's no previous song.
|
||||
*/
|
||||
DirectoryNode *DirectoryNode::goToPreviousMP3(uint32_t thresholdSeconds)
|
||||
{
|
||||
if (secondsPlayed > thresholdSeconds || currentPlaying == nullptr)
|
||||
{
|
||||
// Restart the current song if it's been playing for more than thresholdSeconds
|
||||
// Or if there is no current song (at the start of the list)
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the previous song
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (currentPlaying != nullptr && *currentPlaying == mp3Files[i] && i > 0)
|
||||
{
|
||||
// Move to the previous song
|
||||
setCurrentPlaying(&mp3Files[i - 1]);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// If the first song in the directory or no song was playing, move to the previous directory, if any
|
||||
for (auto subdir : subdirectories)
|
||||
{
|
||||
DirectoryNode *previousNode = subdir->goToPreviousMP3(thresholdSeconds);
|
||||
if (previousNode != nullptr)
|
||||
{
|
||||
return previousNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
// No previous song available
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DirectoryNode *DirectoryNode::advanceToNextMP3(const String *currentGlobal)
|
||||
{
|
||||
bool useFirst = false;
|
||||
Serial.println(currentGlobal->c_str());
|
||||
|
|
@ -230,7 +279,7 @@ DirectoryNode* DirectoryNode::advanceToNextMP3(const String* currentGlobal)
|
|||
{
|
||||
for (size_t i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
if (*currentGlobal==mp3Files[i])
|
||||
if (*currentGlobal == mp3Files[i])
|
||||
{
|
||||
// Found the current playing MP3 file
|
||||
if (i < mp3Files.size() - 1)
|
||||
|
|
@ -245,14 +294,14 @@ DirectoryNode* DirectoryNode::advanceToNextMP3(const String* currentGlobal)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// We are either not playing, or we've exhausted all the MP3 files in this directory.
|
||||
// Therefore, we need to recursively look in our subdirectories.
|
||||
for (auto subdir : subdirectories)
|
||||
{
|
||||
|
||||
if (useFirst && subdir->mp3Files.size()>0) {
|
||||
if (useFirst && subdir->mp3Files.size() > 0)
|
||||
{
|
||||
subdir->setCurrentPlaying(&subdir->mp3Files[0]);
|
||||
return subdir;
|
||||
}
|
||||
|
|
@ -268,7 +317,9 @@ DirectoryNode* DirectoryNode::advanceToNextMP3(const String* currentGlobal)
|
|||
// Advance to the next MP3 file in the same directory
|
||||
subdir->setCurrentPlaying(&subdir->mp3Files[i + 1]);
|
||||
return subdir;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
useFirst = true;
|
||||
}
|
||||
// Reached the end of the MP3 files in the directory
|
||||
|
|
@ -287,24 +338,27 @@ String DirectoryNode::getDirectoryStructureHTML() const
|
|||
{
|
||||
String html;
|
||||
html.reserve(1024); // Reserve memory for better performance
|
||||
if (name=="/") {
|
||||
if (name == "/")
|
||||
{
|
||||
html += "<ul>\n";
|
||||
}
|
||||
|
||||
if (name!="/") {
|
||||
html += "<li data-id=\""+String(id)+"\"><b>" + name + "</b></li>\n";
|
||||
|
||||
if (name != "/")
|
||||
{
|
||||
html += "<li data-id=\"" + String(id) + "\"><b>" + name + "</b></li>\n";
|
||||
}
|
||||
|
||||
for (int i=0;i<mp3Files.size();i++)
|
||||
for (int i = 0; i < mp3Files.size(); i++)
|
||||
{
|
||||
html += "<li data-id=\""+String(ids[i])+"\">" + mp3Files[i] + "</li>\n";
|
||||
html += "<li data-id=\"" + String(ids[i]) + "\">" + mp3Files[i] + "</li>\n";
|
||||
}
|
||||
|
||||
for (DirectoryNode *childNode : subdirectories)
|
||||
{
|
||||
html += childNode->getDirectoryStructureHTML();
|
||||
}
|
||||
if (name=="/") {
|
||||
if (name == "/")
|
||||
{
|
||||
html += "</ul>\n";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
void printDirectoryTree(int level = 0) const;
|
||||
DirectoryNode* advanceToMP3(const String* currentGlobal);
|
||||
DirectoryNode* advanceToNextMP3(const String* currentGlobal);
|
||||
DirectoryNode* goToPreviousMP3(uint32_t thresholdSeconds = 3);
|
||||
DirectoryNode* advanceToMP3(const uint16_t id);
|
||||
void advanceToFirstMP3InThisNode();
|
||||
String getDirectoryStructureHTML() const;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const char index_html[] PROGMEM = R"rawliteral(
|
|||
<span id="uid"></span><br/>
|
||||
|
||||
<div>
|
||||
<button class="prev-button" onclick="simpleGetCall('prev');""></button>
|
||||
<button class="prev-button" onclick="simpleGetCall('previous');""></button>
|
||||
<button class="play-button" onclick="simpleGetCall('toggleplaypause');"></button>
|
||||
<button class="next-button" onclick="simpleGetCall('next');"></button><br/><br/>
|
||||
</div>
|
||||
|
|
|
|||
56
src/main.cpp
56
src/main.cpp
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
#define VOLTAGE_LOOP_INTERVAL 5000
|
||||
|
||||
#define VOLTAGE_THRESHOLD 3800
|
||||
|
||||
#include "globals.h"
|
||||
#include "WebContent.h"
|
||||
#include "css.h"
|
||||
|
|
@ -82,6 +84,8 @@ bool asyncNext = false;
|
|||
|
||||
bool asyncPrev = false;
|
||||
|
||||
uint16_t voltage_threshold_counter = 0;
|
||||
|
||||
/*
|
||||
std::map<String, String> rfid_map{{"67 152 204 14", "01-The_Box_Tops-The_Letter.mp3"},
|
||||
{"67 175 148 160", "068-Der_Schatz_im_Bergsee"}};
|
||||
|
|
@ -360,6 +364,37 @@ void next()
|
|||
lastInteraction = millis();
|
||||
}
|
||||
|
||||
void previous()
|
||||
{
|
||||
if (currentNode != nullptr) {
|
||||
|
||||
const String* curr = currentNode->getCurrentPlaying();
|
||||
DirectoryNode* newNode = currentNode->goToPreviousMP3();
|
||||
|
||||
if (newNode != nullptr) {
|
||||
if (curr == newNode->getCurrentPlaying()) {
|
||||
// reset to 0 seconds playtime:
|
||||
audio.setAudioPlayPosition(0);
|
||||
} else {
|
||||
// Update the current node and start playing the previous song
|
||||
Serial.println("");
|
||||
Serial.print("Playing previous song: ");
|
||||
Serial.println(currentNode->getCurrentPlayingFilePath());
|
||||
currentNode = newNode;
|
||||
stop();
|
||||
deactivateRFID();
|
||||
activateSD();
|
||||
playSongByPath(currentNode->getCurrentPlayingFilePath());
|
||||
deactivateSD();
|
||||
activateRFID();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
lastInteraction = millis();
|
||||
}
|
||||
|
||||
void audio_eof_mp3(const char *info)
|
||||
{
|
||||
Serial.println("audio file ended.");
|
||||
|
|
@ -511,6 +546,12 @@ void setup()
|
|||
request->send(200, "text/plain", "next");
|
||||
next(); });
|
||||
|
||||
server.on("/previous", HTTP_GET, [](AsyncWebServerRequest *request)
|
||||
{
|
||||
|
||||
request->send(200, "text/plain", "previous");
|
||||
previous(); });
|
||||
|
||||
server.on("/playbyid", HTTP_GET, id_song_action);
|
||||
|
||||
server.on("/progress", HTTP_POST, progress_action);
|
||||
|
|
@ -663,7 +704,8 @@ void loop()
|
|||
else if (asyncPrev)
|
||||
{
|
||||
asyncPrev = false;
|
||||
Serial.println("Previous not yet implemented!");
|
||||
Serial.println("Previous");
|
||||
previous();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -682,6 +724,18 @@ void loop()
|
|||
if (loopCounter % VOLTAGE_LOOP_INTERVAL == 0)
|
||||
{
|
||||
lastVoltage = getBatteryVoltageMv();
|
||||
if (lastVoltage<VOLTAGE_THRESHOLD) {
|
||||
if (voltage_threshold_counter>3) {
|
||||
Serial.println("entering deep sleep due to low voltage...");
|
||||
lastInteraction = millis() - sleepMessageDelay;
|
||||
voltage_threshold_counter = 0;
|
||||
} else {
|
||||
voltage_threshold_counter++;
|
||||
}
|
||||
} else {
|
||||
voltage_threshold_counter = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loopCounter++;
|
||||
|
|
|
|||
Loading…
Reference in New Issue