Remove wait time before playing audio track using millis()

I am working on a neat little personal project and I have the setup working almost 100%. I am really excited about the whole thing. This is my first time messing with audio, and I have been working hard to learn the code to put this all together and have progressed a lot these last couple weeks. However, I can’t figure out the last little bits. Let me explain the situation:

I am using an Arduino Uno, three 10k ohm potentiometers, a 16 led Neopixel ring, and a DFPlayerMini mp3 player.

When you turn the dials (potentiometers) they change color of the associated section of leds on the Neopixel ring. There are 8 colors to choose from. Each dial is mapped to correspond with each color and update the leds accordingly.

When each dial is set to a specified color (in this case, teal, which is the int 4) an audio track will play.

Here is where I have trouble.

The tracks do play, but there is a delay before they do so. I understand it is because of the if(millis() - timer > 10000){…} and that it won’t play the song until that if statement is true, after which is will play the track for 10 seconds repeatedly until the dial changes. So, my question is this: how can I get rid of this wait time before a track will play?

Here is my code:

#include <Adafruit_NeoPixel.h>
#include <avr/power.h>
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);

#define PIN            3
#define NUMPIXELS      16

Adafruit_NeoPixel gemA = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int dialPinA = A0;    // Potentiometer for Gem A
int currentStateA;
int previousStateA = 10;

int dialPinB = A1;    // Potentiometer for Gem B
int currentStateB;
int previousStateB = 10;

int dialPinC = A2;    // Potentiometer for Gem C
int currentStateC;
int previousStateC = 10;

int arrayRed[] = {255,255,255,0,0,0,85,200};  //Red, Orange, Yellow, Green, Teal, Blue, Indigo, Violet
int arrayGreen[] = {0,70,150,255,255,0,0,0};
int arrayBlue[] = {0,0,0,0,50,255,255,255};
//int volumeArray[] = {0,5,10,15,20,25,30}; // Not in use yet

static unsigned long timer = millis();

void setup() { 
mySoftwareSerial.begin(9600);
 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(mySoftwareSerial)) {  //Use softwareSerial 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);
  }
  Serial.println(F("DFPlayer Mini online."));
  
  myDFPlayer.volume(18);  //Set volume value. From 0 to 30
}

void loop() { 
  int dialA = analogRead(dialPinA); //Reads potentiometers
  int dialB = analogRead(dialPinB);
  int dialC = analogRead(dialPinC);
  dialA = map(dialA, 0, 1026, 0, 8); //Maps dial to number of color options in the array
  dialB = map(dialB, 0, 1026, 0, 8);
  dialC = map(dialC, 0, 1026, 0, 8);
  
  if (dialA != previousStateA){ //Checks to see if color has changed and if so, updates the leds according to the mapped setting
    gemA.begin();
    for (int x = 0; x < 5; x++)
    {
    gemA.setPixelColor(x, arrayRed[dialA], arrayGreen[dialA], arrayBlue[dialA]);
        previousStateA = dialA;
    }
    gemA.show();
  }
  
  if (dialB != previousStateB){
    gemA.begin();
    for (int x = 5; x < 11; x++)
    {
    gemA.setPixelColor(x, arrayRed[dialB], arrayGreen[dialB], arrayBlue[dialB]);
        previousStateB = dialB;
    }
    gemA.show();
  }

  if (dialC != previousStateC){
    gemA.begin();
    for (int x = 11; x < 16; x++)
    {
    gemA.setPixelColor(x, arrayRed[dialC], arrayGreen[dialC], arrayBlue[dialC]);
        previousStateC = dialC;
    }
    gemA.show();
  }

  //How can I get rid of the inital delay!?!?
  if(dialA == 4 && dialB != 4 && dialC != 4){if (millis() - timer > 10000) {timer = millis();myDFPlayer.play(1);}}       // When each dial, or combo of dials, is set to color 3 play a track, or play mixed tracks (ie. dialA+dialC plays tracks 6
  else if(dialA != 4 && dialB == 4 && dialC != 4){if (millis() - timer > 10000) {timer = millis();myDFPlayer.play(2);}}  // which are a single track with the combined sounds of track 1 and track 3
  else if(dialA != 4 && dialB != 4 && dialC == 4){if (millis() - timer > 10000) {timer = millis();myDFPlayer.play(3);}}
  else if(dialA == 4 && dialB == 4 && dialC != 4){if (millis() - timer > 10000) {timer = millis();myDFPlayer.play(4);}}
  else if(dialA != 4 && dialB == 4 && dialC == 4){if (millis() - timer > 10000) {timer = millis();myDFPlayer.play(5);}}
  else if(dialA == 4 && dialB != 4 && dialC == 4){if (millis() - timer > 10000) {timer = millis();myDFPlayer.play(6);}}
  else if(dialA == 4 && dialB == 4 && dialC == 4){if (millis() - timer > 10000) {timer = millis();myDFPlayer.play(7);}}
  else if(dialA == 5 && dialB == 0 && dialC == 7){if (millis() - timer > 42000) {timer = millis();myDFPlayer.play(8);}} //507; special combo for the bonus track
  else {myDFPlayer.pause();} // When none of the settings are true, pause all tracks
}

If you want to get rid of it, why is it there in the first place? So, get rid of it. It's your program.

Paul

+1 You put it in ..........

Mark

As the timer test is the same for all, you can remove it from the if-else-if statements to the front of them. Before reaching that new test, check a flag that determines if this is the first time through or the loop. If first time, skip the timer test, clear the flag and process your song. At the end of the ten second play, reset the flag. And no, I won't post code for you to do that. If my explanation isn't clear, I'll try again. The logic is there so see first what you come up with and let us know, we move forward from there.