Code

Here is my latest code to copy and paste into the arduino mega . It will change over time. It may also contain features that are not in use yet (and may give the result I though it would. Grok and Chatgtp are great assistants to explain what is going on with it.

This code will work to create a music player .

The name of this code is mega29.

below is the code– Uses Arduino Mega, has 2 dfmini players

*********************************************************************

 *  PINBALL ARCADE – 4-PLAYER TOURNAMENT EDITION

 *  Version will automatically show the sketch filename

 *  NOW WITH FULL PIN → MP3 TRACK MAP AT STARTUP

 *********************************************************************/

#include<DFRobotDFPlayerMini.h>

DFRobotDFPlayerMini dfPlayerMusic;

DFRobotDFPlayerMini dfPlayerFX;

constint pinCount = 44;

constintpins[pinCount] = {

2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,

22, 23, 24, 25, 26, 27, 28, 29, 30, 31,

32, 33, 34, 35, 36, 37, 38, 39, 40, 41,

42, 43, 44, 45,

46, 47, 48, 49, 50, 51, 53

};

constint ledPin = 52;

bool ledShouldBlink = false;

unsignedlong lastBlinkTime = 0;

unsignedlong ledBlinkStartTime = 0;

bool ledState = LOW;

booltriggered[pinCount];

unsignedlonglastTriggerTime[pinCount];

bool musicPlaying = false;

constint originalVolume = 25;

constint totalTracks = 8;

intplaylist[totalTracks];

int currentTrackIndex = 0;

constint busyPin = 53;

constunsignedlong debounceInterval = 80;

constunsignedlong setupDelay = 2000;

bool setupDelayComplete = false;

longplayerScore[5] = {0, 0, 0, 0, 0};  // 1-4 used

int activePlayer = 0;

bool fadingOut = false;

unsignedlong fadeStartTime = 0;

constunsignedlong fadeDuration = 5000;

// ———- COMPLETE STARTUP INFO WITH PIN → MP3 MAP ———-

voidprintStartupInfo() {

Serial.println(F(“”));

Serial.println(F(“╔══════════════════════════════════════════════════════════╗”));

Serial.println(F(“║     PINBALL ARCADE – 4-PLAYER TOURNAMENT EDITION        ║”));

Serial.print  (F(“║               Version: “));

Serial.print  (__FILE__);

Serial.println(F(”      ║”));

Serial.println(F(“║                     by Zory + Grok                      ║”));

Serial.println(F(“╚══════════════════════════════════════════════════════════╝”));

Serial.println(F(“”));

Serial.println(F(“CONTROL PINS:”));

Serial.println(F(”   Pin 2  → Start New Game / Music”));

Serial.println(F(”   Pin 3  → Game Over (5-sec fade + final scores)”));

Serial.println(F(”   Pin 46 → PLAYER 4 active”));

Serial.println(F(”   Pin 47 → PLAYER 3 active”));

Serial.println(F(”   Pin 48 → PLAYER 2 active”));

Serial.println(F(”   Pin 49 → PLAYER 1 active”));

Serial.println(F(”   Pin 51 → Hurry-Up mode (8-sec LED blink + 10k jackpot on Pin 44)”));

Serial.println(F(”   Pin 52 → Hurry-Up LED”));

Serial.println(F(”   Pin 53 → DFPlayer BUSY line”));

Serial.println(F(“”));

Serial.println(F(“SCORING PINS → MP3 SOUND FX MAP:”));

Serial.println(F(”   Pin   | MP3 Track | Points     | Notes”));

Serial.println(F(”   ——+———–+————+——————“));

  // Group 1: Pins 4–12 → tracks 001–009

for (int p = 4; p <= 12; p++) {

int track = p – 3;

Serial.print(F(”   “)); Serial.print(p < 10 ? ” ” : “”); Serial.print(p);

Serial.print(F(”   |   “)); Serial.print(track < 100 ? (track < 10 ? “00” : “0”) : “”); Serial.print(track); Serial.print(F(“.mp3”));

Serial.print(F(”   | “));

if (p == 8)  Serial.print(F(”     +10″));

elseif (p == 9) Serial.print(F(”    +100″));

elseSerial.print(F(”     +100″));

Serial.println(p == 8 || p == 9 ? F(”       Special”) : F(“”));

  }

  // Group 2: Pins 22–45 → tracks 010–033

for (int p = 22; p <= 45; p++) {

int track = p – 12;

Serial.print(F(”   “)); Serial.print(p);

Serial.print(F(”   |   “)); Serial.print(track < 100 ? “0” : “”); Serial.print(track); Serial.print(F(“.mp3”));

Serial.print(F(”   | “));

if (p == 31) Serial.print(F(”   +1000″));

elseif (p == 44) Serial.print(F(” +100 / +10k”));

elseSerial.print(F(”     +100″));

Serial.println(p == 31 ? F(”       Special”) : (p == 44 ? F(”     JACKPOT target”) : F(“”)));

  }

  // Group 3: Pins 50–53

Serial.println(F(”   50   |   035.mp3   |     +100″));

Serial.println(F(”   51   |   036.mp3   | Hurry-Up trigger”));

Serial.println(F(”   53   |   038.mp3   | (used as BUSY pin)”));

Serial.println(F(“”));

Serial.println(F(“MUSIC TRACKS (shuffled): 001.mp3 → 008.mp3”));

Serial.println(F(“”));

}

// ———- SHOW ALL 4 SCORES ———-

voidshowAllScores() {

Serial.println(“════════════════════════════════════”);

Serial.print(”     PLAYER 1 SCORE: “); Serial.println(playerScore[1]);

Serial.print(”     PLAYER 2 SCORE: “); Serial.println(playerScore[2]);

Serial.print(”     PLAYER 3 SCORE: “); Serial.println(playerScore[3]);

Serial.print(”     PLAYER 4 SCORE: “); Serial.println(playerScore[4]);

Serial.println(“════════════════════════════════════”);

}

// ———- SHOW CURRENT PLAYER ———-

voidshowActivePlayer() {

if (activePlayer >= 1 && activePlayer <= 4) {

Serial.print(“>>> CURRENTLY SCORING: PLAYER “);

Serial.println(activePlayer);

  } else {

Serial.println(“>>> NO PLAYER SELECTED <<<“);

  }

}

// ———- LED FLASH ———-

voidflashLED(int times, int d = 200) {

for (int i = 0; i < times; i++) {

digitalWrite(ledPin, HIGH); delay(d);

digitalWrite(ledPin, LOW);  if (i < times – 1) delay(d);

  }

}

// ———- SETUP ———-

voidsetup() {

Serial.begin(9600);

randomSeed(analogRead(0));

pinMode(ledPin, OUTPUT);

for (int i = 0; i < pinCount; i++) pinMode(pins[i], INPUT_PULLUP);

pinMode(busyPin, INPUT);

Serial1.begin(9600);

if (!dfPlayerMusic.begin(Serial1, true, false)) while(1) flashLED(1);

dfPlayerMusic.volume(originalVolume);

Serial2.begin(9600);

if (!dfPlayerFX.begin(Serial2, true, false)) while(1) flashLED(2);

dfPlayerFX.volume(19);

printStartupInfo();

flashLED(5);

shufflePlaylist();

Serial.println(“4-PLAYER SYSTEM READY!”);

showActivePlayer();

showAllScores();

}

// ———- PLAYLIST ———-

voidshufflePlaylist() {

for (int i = 0; i < totalTracks; i++) playlist[i] = i + 1;

for (int i = 0; i < totalTracks; i++) {

int r = random(i, totalTracks);

int temp = playlist[i]; playlist[i] = playlist[r]; playlist[r] = temp;

  }

}

voidplayNextTrack() {

if (digitalRead(busyPin) == LOW || currentTrackIndex >= totalTracks) return;

dfPlayerMusic.play(playlist[currentTrackIndex++]);

  musicPlaying = true;

}

// ———- FADE OUT ———-

voidstartFadeOutAndGameOver() {

if (fadingOut) return;

  fadingOut = true;

  fadeStartTime = millis();

Serial.println(“Pin 3 → GAME OVER! Fading music…”);

}

voidupdateFadeOut() {

if (!fadingOut) return;

unsignedlong elapsed = millis() – fadeStartTime;

if (elapsed >= fadeDuration) {

dfPlayerMusic.stop();

    musicPlaying = false;

    fadingOut = false;

Serial.println(“════════════════════════════════════”);

Serial.println(”            FINAL SCORES”);

Serial.print(”       PLAYER 1: “); Serial.println(playerScore[1]);

Serial.print(”       PLAYER 2: “); Serial.println(playerScore[2]);

Serial.print(”       PLAYER 3: “); Serial.println(playerScore[3]);

Serial.print(”       PLAYER 4: “); Serial.println(playerScore[4]);

Serial.println(“════════════════════════════════════”);

Serial.println(“All scores reset!”);

for (int i = 1; i <= 4; i++) playerScore[i] = 0;

    activePlayer = 0;

showActivePlayer();

  } else {

int vol = originalVolume * (fadeDuration – elapsed) / fadeDuration;

dfPlayerMusic.volume(max(vol, 0));

  }

}

// ———- FX MAP ———-

intpinToFxTrack(int pin) {

if (pin >= 4 && pin <= 12)  return pin – 3;

if (pin >= 22 && pin <= 45) return pin – 12;

if (pin >= 46 && pin <= 53) return pin – 15;

return1;

}

// ———- ADD POINTS ———-

voidaddPoints(int points, constchar* msg = “”) {

if (activePlayer >= 1 && activePlayer <= 4) {

playerScore[activePlayer] += points;

Serial.print(“P”); Serial.print(activePlayer); Serial.print(” “);

Serial.print(msg); Serial.print(” +”); Serial.print(points);

Serial.print(”  →  “); Serial.println(playerScore[activePlayer]);

  } else {

Serial.println(“NO PLAYER ACTIVE – points ignored!”);

  }

}

// ———- MAIN LOOP ———-

voidloop() {

unsignedlong now = millis();

if (!setupDelayComplete && now >= setupDelay) { dfPlayerMusic.stop(); setupDelayComplete = true; }

if (!setupDelayComplete) return;

updateFadeOut();

for (int i = 0; i < pinCount; i++) {

int pin = pins[i];

int state = digitalRead(pin);

if (state == LOW && !triggered[i] && (now – lastTriggerTime[i] >= debounceInterval)) {

triggered[i] = true;

lastTriggerTime[i] = now;

if      (pin == 49 && activePlayer != 1) { activePlayer = 1; Serial.println(“\n>>> NOW PLAYING: PLAYER 1 <<<“); showActivePlayer(); showAllScores(); }

elseif (pin == 48 && activePlayer != 2) { activePlayer = 2; Serial.println(“\n>>> NOW PLAYING: PLAYER 2 <<<“); showActivePlayer(); showAllScores(); }

elseif (pin == 47 && activePlayer != 3) { activePlayer = 3; Serial.println(“\n>>> NOW PLAYING: PLAYER 3 <<<“); showActivePlayer(); showAllScores(); }

elseif (pin == 46 && activePlayer != 4) { activePlayer = 4; Serial.println(“\n>>> NOW PLAYING: PLAYER 4 <<<“); showActivePlayer(); showAllScores(); }

elseif (pin == 2) {

if (digitalRead(busyPin) == HIGH && !fadingOut) {

Serial.println(“Pin 2 → Starting music”);

dfPlayerMusic.volume(originalVolume);

          currentTrackIndex = 0;

shufflePlaylist();

playNextTrack();

        }

      }

elseif (pin == 3) startFadeOutAndGameOver();

else {

dfPlayerFX.play(pinToFxTrack(pin));

if      (pin == 8)  addPoints(10, “Score”);

elseif (pin == 9)  addPoints(100, “Score”);

elseif (pin == 31) addPoints(1000, “Score”);

elseif (pin ==  44) addPoints(ledShouldBlink ? 10000 : 100, ledShouldBlink ? “JACKPOT” : “Score”);

elseaddPoints(100, “Hit”);

      }

if (pin == 51) {

Serial.println(“Pin 51 → Hurry-Up ON”);

        ledShouldBlink = true;

        ledBlinkStartTime = now;

      }

    }

if (state == HIGH) triggered[i] = false;

  }

if (ledShouldBlink && now – lastBlinkTime >= 100) {

    lastBlinkTime = now;

    ledState = !ledState;

digitalWrite(ledPin, ledState);

if (now – ledBlinkStartTime > 8000) {

      ledShouldBlink = false;

digitalWrite(ledPin, LOW);

Serial.println(“Hurry-Up ended.”);

    }

  }

staticbool wasBusy = false;

bool isBusy = (digitalRead(busyPin) == LOW);

if (musicPlaying && wasBusy && !isBusy && !fadingOut) {

Serial.println(“Track ended → Playing next”);

playNextTrack();

  }

  wasBusy = isBusy;

}