// === OVERVIEW === // Tape Deck player replacement // // VU meter --> OLED display // Cassette player --> MP3 player // === MP3 PLAYER === /*************************************************** DFPlayer - A Mini MP3 Player For Arduino *************************************************** This example shows the basic function of library for DFPlayer. Created 2016-12-07 By [Angelo qiao](Angelo.qiao@dfrobot.com) GNU Lesser General Public License. See for details. All above must be included in any redistribution ****************************************************/ /***********Notice and Trouble shooting*************** 1.Connection and Diagram can be found here 2.This code is tested on Arduino Uno, Leonardo, Mega boards. ****************************************************/ #include "Arduino.h" #include "SoftwareSerial.h" #include "DFRobotDFPlayerMini.h" #include "EEPROM.h" #define PIN_EQ A1 #define PIN_CHROME 6 #define PIN_FORWARD 10 #define EEPROM_SONG_INDEX 1 #define SKIP_LIMIT 250 #define EEPROM_SKIP 2 SoftwareSerial mySoftwareSerial(9, 8); // RX, TX DFRobotDFPlayerMini myDFPlayer; void printDetail(uint8_t type, int value); int song_index = 0; unsigned long song_started = 0; int files_max = -1; bool skipping = false; void setup_player() { pinMode(PIN_EQ, INPUT); pinMode(PIN_CHROME, INPUT); pinMode(PIN_FORWARD, INPUT); analogReference(DEFAULT); Serial.begin(9600); while (!Serial && millis() < 2000) { delay(10); } song_index = EEPROM.read(EEPROM_SONG_INDEX); unsigned int song_skip = EEPROM.read(EEPROM_SKIP); if (song_skip > SKIP_LIMIT) { song_skip = 0; } song_index += song_skip; if (song_index >= 255) { song_index = 0; } Serial.println(); Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)")); mySoftwareSerial.begin(9600); if (!myDFPlayer.begin(mySoftwareSerial)) { 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); } } Serial.println(F("DFPlayer Mini online.")); myDFPlayer.volume(20); //Set volume value. From 0 to 30 myDFPlayer.play(song_index+1); //Play the first mp3 do { delay(100); files_max = myDFPlayer.readFileCounts(); } while (files_max <= -1); if (digitalRead(PIN_FORWARD) == 1) { // FastForward skipping = true; while (true) { delay(500); if (digitalRead(PIN_FORWARD) == 1) { song_skip = min(song_skip + 1, SKIP_LIMIT); EEPROM.update(EEPROM_SKIP, song_skip); Serial.print("Skipping +1 ... "); } else { Serial.print("Skipping +0 ... "); } if (song_index + song_skip >= files_max) { song_index = 0; song_skip = 0; } myDFPlayer.play(song_index + song_skip + 1); } } myDFPlayer.EQ(DFPLAYER_EQ_NORMAL); if (files_max > 0 && song_index >= files_max) { Serial.println("Song index out of bounds, skipping to next."); nextSong(); } song_started = millis(); } int eq_now = DFPLAYER_EQ_NORMAL; void loop_player() { static unsigned long eq_timer = millis(); if (millis() - eq_timer > 100) { eq_timer = millis(); int eq_next = eq_now; int eqChrome = digitalRead(PIN_CHROME); if (eqChrome == 0) { //analogReference(DEFAULT); int eqRaw = analogRead(PIN_EQ); //Serial.print("EQ: "); //Serial.println(eqRaw); if (eqRaw < 512) { eq_next = DFPLAYER_EQ_BASS; //Serial.println("EQ: Bass"); } else if (eqRaw < 900) { eq_next = DFPLAYER_EQ_NORMAL; //Serial.println("EQ: Normal"); } else { eq_next = DFPLAYER_EQ_POP; //Serial.println("EQ: POP"); } } else { eq_next = DFPLAYER_EQ_ROCK; //Serial.println("EQ: Rock"); } if (eq_now != eq_next) { eq_now = eq_next; myDFPlayer.EQ(eq_now); } } if (myDFPlayer.available()) { printDetail(myDFPlayer.readType(), myDFPlayer.read()); } } void nextSong() { int files_max = myDFPlayer.readFileCounts(); song_index = (song_index + 1) % files_max; EEPROM.update(EEPROM_SONG_INDEX, song_index); EEPROM.update(EEPROM_SKIP, 0); myDFPlayer.play(song_index + 1); song_started = millis(); Serial.println("Next song..."); } 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!")); myDFPlayer.stop(); break; case DFPlayerCardOnline: Serial.println(F("Card Online!")); myDFPlayer.start(); 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!")); nextSong(); 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")); delay(1000); song_index = 0; myDFPlayer.play(song_index + 1); break; case FileMismatch: Serial.println(F("Cannot Find File")); break; case Advertise: Serial.println(F("In Advertise")); break; default: break; } break; default: break; } } // === DISPLAY === #include #include #include #include #define PIN_VU A0 #define VU_SCALE 1 #define VU_WARN 700 #define VU_CRIT 900 #define VU_SLOWDOWN 10 #define VU_ATTACK 1 /* Uncomment the initialize the I2C address , uncomment only one, If you get a totally blank screen try the other*/ #define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's //#define i2c_Address 0x3d //initialize with the I2C addr 0x3D Typically Adafruit OLED's #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET -1 // QT-PY / XIAO Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void setup_display() { //Serial.begin(9600); delay(250); // wait for the OLED to power up display.begin(i2c_Address, true); // Address 0x3C default display.setContrast (0); // dim display // Clear the buffer. display.clearDisplay(); display.display(); display.setTextSize(2); display.setTextColor(SH110X_WHITE); display.setCursor(0, 20); display.println(" UNIVERSUM"); display.setTextSize(1); display.display(); delay(500); display.clearDisplay(); } void loop_display() { display.clearDisplay(); display.setTextSize(2); display.setTextColor(SH110X_WHITE); display.setCursor(35, 20); unsigned long song_time = (millis() - song_started) / 1000; char song_time_text[16]; sprintf(song_time_text, "%02d", song_time / 60); display.print(song_time_text); display.print(":"); sprintf(song_time_text, "%02d", song_time % 60); display.println(song_time_text); display.setTextSize(1); display.setCursor(37, 50); char song_index_text[16]; sprintf(song_index_text, "%03d", song_index+1); display.print(song_index_text); display.print(" / "); char song_count_text[16]; sprintf(song_count_text, "%03d", files_max); display.print(song_count_text); display.display(); } // === MAIN === void setup() { setup_player(); setup_display(); } void loop() { loop_player(); loop_display(); }