Premetto qualche nota relativamente "secondaria", diciamo di "stile" ma comunque utili.
Primo, per favore cerca di indentare bene il codice. Non è una questione "estetica" ma rende il codice più facile da leggere, sia per te sia per noi. Se premi Ctrl-T l'IDE te lo riformatta lui automaticamente (e da allora cerca di mantenere quel formato.
Secondo, se metti dei commenti lunghi magari anche su linee lunghe, mettili prima dell'istruzione o blocco che vuoi commentare, perché altrimenti il commento stesso può "uscire" dall'area di testo e quindi non lo si può leggere se non scrollando a destra.
Ad esempio non:
printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
ma meglio:
//Print the detail message from DFPlayer to handle different errors and states.
printDetail(myDFPlayer.readType(), myDFPlayer.read());
Terzo, tutto ciò che riguarda millis() (timers, durate, eccetera) devono essere unsigned long! Quindi non int randomPausa ma unsigned long randomPausa
Per finire, usa più commenti, anche dentro al codice. Ti aiuterà a verificare meglio se ciò che scrivi corrisponde a quanto implementi (ed a noi per capire meglio cosa intendi).
Passiamo ora al resto.
Perdonami, ma i miei consigli li hai letti e compresi, e cercato di implementarli? A parte il primo (usare un solo seed, e ok, ma era facile limitarsi a togliere una riga), per il secondo consiglio, che era questo:
Se la pausa è un valore random in minuti, perché fare un array di unsigned long invece di limitarti a generare un intero tra 1 e 15 e moltiplicarlo per 60.000 e usarlo per impostare la pausa?
nel nuovo codice hai fatto:
int pausa[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; // Pause tra una traccia ed un'altra da 1 a 15 Minuti
Scusa, ma a cosa serve fare un array il cui valore corrisponde all'indice (+1 ma è irrilevante)?
Se, come ti consigliavo, generi un numero random da 1 a 15 hai risolto, no?
Ad esempio togliendo del tutto quell'array e le altre variabili inutili, nelle global te ne bastano due:
// Durata della pausa tra i brani
unsigned long Pausa;
// Timer per inizio conteggio della pausa tra i brani
unsigned long tmrPausa;
E quando devi calcolare la pausa ti basta fare semplicemente:
Pausa= 60000UL * random(1, 16); // Numero casuale tra 1 e 15, moltiplicato per 60000
tmrPausa = millis();
e quindi quando devo vedere se la pausa è finita:
void loop() {
if (millis() - tmrPausa > Pausa) {
La stessa cosa anche per "canti":
int canti[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
Imposta solo una costante per definire il numero massimo di canti ed usa quella nella funzione random():
...
const byte NUM_CANTI = 8;
...
// Nuovo canto
int numCanto = random(1, NUM_CANTI+ 1); // valore tra 1 e NUM_CANTI
myDFPlayer.play(numCanto );
Poi vedo che fai ancora:
void loop() {
int randomIndex = random(cantiElements);
int randomCanti = canti[randomIndex];
int randomIndexPausa = random(pausaElements);
int randomPausa = pausa[randomIndexPausa];
e questo non corrisponde con quanto ti avevo scritto:
ad ogni iterazione generi un valore di pausa casuale: a che serve farlo migliaia di volte al secondo? Devi farlo solo una volta quando c'è la riproduzione e poi aspettare solo la pausa
Dato che avevo concluso con:
Prova a fare qualche correzione, fai qualche test, e posta qui il tuo nuovo codice. Se poi non riesci, allora appena avrò tempo (forse stasera...) proverò a modificarti lo sketch per proporti le mie modifiche.
Devo quindi immaginare che tu non abbia recepito il mio primo suggerimento.
Se ora quanto ti ho descritto lo hai letto e compreso, prova questa versione che ti ho modificato (verificase compila bene e se funziona perché l'ho scritta al volo quindi non l'ho provata perché non avevo tempo e comunque non ho sottomano un player...) e vedi quanto è più semplice e comprensibile, in particolare i commenti e la funzione "ImpostaCanto()":
#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"
#if (defined(ARDUINO_AVR_UNO) || defined(ESP8266)) // Using a soft serial port
#include <SoftwareSerial.h>
SoftwareSerial softSerial(/*rx =*/6, /*tx =*/7);
#define FPSerial softSerial
#else
#define FPSerial Serial1
#endif
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
// Numero di canti presenti
const byte NUM_CANTI = 8;
// Durata della pausa tra i cnti
unsigned long Pausa;
// Timer per conteggio della pausa tra i canti
unsigned long tmrPausa;
// Funzione che imposta il canto e fa partire la pausa
void ImpostaCanto() {
int numCanto = random(1, NUM_BRANI + 1); // valore tra 1 e NUM_BRANI
myDFPlayer.play(numCanto);
Serial.print("Canto: "); Serial.println(numCanto);
// Prossima pausa
Pausa= 60000UL * random(1, 16); // Numero casuale tra 1 e 15, moltiplicato per 60000
Serial.print("Pausa: "); Serial.println(Pausa);
tmrPausa = millis();
}
void setup() {
#if (defined ESP32)
FPSerial.begin(9600, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
FPSerial.begin(9600);
#endif
Serial.begin(115200);
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
if (!myDFPlayer.begin(FPSerial, /*isACK = */ true, /*doReset = */ true)) { //Use serial to communicate with mp3.
Serial.println(F("Unable to begin:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
while (true) {
delay(0); // Code to compatible with ESP8266 watch dog.
}
}
Serial.println(F("DFPlayer Mini online."));
myDFPlayer.volume(30); //Set volume value. From 0 to 30
randomSeed(analogRead(A0));
ImpostaCanto();
}
void loop() {
// Finita la pausa?
if (millis() - tmrPausa > Pausa) {
// Si, ora metto in riproduzione un altro canto
ImpostaCanto();
}
if (myDFPlayer.available()) {
printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
}
void printDetail(uint8_t type, int value) {
switch (type) {
case TimeOut:
Serial.println(F("Time Out!"));
break;
case WrongStack:
Serial.println(F("Stack Wrong!"));
break;
case DFPlayerCardInserted:
Serial.println(F("Card Inserted!"));
break;
case DFPlayerCardRemoved:
Serial.println(F("Card Removed!"));
break;
case DFPlayerCardOnline:
Serial.println(F("Card Online!"));
break;
case DFPlayerUSBInserted:
Serial.println("USB Inserted!");
break;
case DFPlayerUSBRemoved:
Serial.println("USB Removed!");
break;
case DFPlayerPlayFinished:
Serial.print(F("Number:"));
Serial.print(value);
Serial.println(F(" Play Finished!"));
break;
case DFPlayerError:
Serial.print(F("DFPlayerError:"));
switch (value) {
case Busy:
Serial.println(F("Card not found"));
break;
case Sleeping:
Serial.println(F("Sleeping"));
break;
case SerialWrongStack:
Serial.println(F("Get Wrong Stack"));
break;
case CheckSumNotMatch:
Serial.println(F("Check Sum Not Match"));
break;
case FileIndexOut:
Serial.println(F("File Index Out of Bound"));
break;
case FileMismatch:
Serial.println(F("Cannot Find File"));
break;
case Advertise:
Serial.println(F("In Advertise"));
break;
default:
break;
}
break;
default:
break;
}
}