DKARDU
Published © CC0

How to Make MP3 player w/ LCD using Arduino & DFPlayer Mini

Today we will make a MP3 player with LCD using Arduino and DFPlayer mini MP3 Player Module.

IntermediateFull instructions provided2 hours12,222

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
MP3-TF-16P mini mp3 player
×1
1K and 3 of 100Ω Resistors
×1
RGB LED Bulb
×1
1.3 inch oled display
×1
3 Switch buttons
×1
Jumper wires
×1
Breadboard
×1

Story

Read more

Schematics

circuit_diagram_U8SRYsuZXD.jpg

Code

AudioPlayer.ino

Arduino
// starts to play the actual file in the actual folder
void startFolderPlay() {
  filecounts = myDFPlayer.readFileCountsInFolder(folder);
  myDFPlayer.playFolder(folder, file);
  playing = false;
}

//Battery management

void batteryReader()
{
  if((millis() -  lastTimepassed) > 60000)
  {
  mins++;
  Serial.println("One min");
  lastTimepassed = millis();
  }

  if(mins > 5 || mins == 0)
  {
   /*Add battery logic here*/
  mins = 1;
  updateScreen = true;
  }
}

dispaly.ino

Arduino
void settings()
{
   sideMenu();
   topMenu();
   u8g2.setFont(u8g2_font_glasstown_nbp_tf);
   
   u8g2.setCursor(65,13);
   u8g2.print(F("Setting"));

   u8g2.setFontMode(0);
      
   u8g2.setCursor(47,40);
   u8g2.print(F("Volume"));
   if(selection == 1 && !inSideMenuSelection)
    {
    u8g2.setFont(u8g2_font_open_iconic_arrow_1x_t);
    if(volume > 0)
    u8g2.drawGlyph(85,40,77);
    if(volume < 30)
    {
    if(volume < 10)
    u8g2.drawGlyph(100,40,78);
    else
    u8g2.drawGlyph(105,40,78);
    }
    }
   u8g2.setFont(u8g2_font_glasstown_nbp_tf);
   u8g2.setCursor(95,40);
   u8g2.print(volume);
   u8g2.setDrawColor(1);
   
   u8g2.setCursor(67,60);
   u8g2.print(F("EQ"));
   if(selection == 2 && !inSideMenuSelection)
    {
    u8g2.setFont(u8g2_font_open_iconic_arrow_1x_t);
    if(eq > 0)
    u8g2.drawGlyph(85,60,77);
    if(eq < 5)
    u8g2.drawGlyph(100,60,78);
    }
   u8g2.setFont(u8g2_font_glasstown_nbp_tf);
   u8g2.setCursor(95,60);
   u8g2.print(eq);
   u8g2.setDrawColor(1);
   
    if(selection == 4 && !inSideMenuSelection)
    {
    u8g2.setDrawColor(0);
    }
   u8g2.setFont(u8g2_font_open_iconic_arrow_1x_t);
   u8g2.drawGlyph(120,60,83);
   u8g2.setDrawColor(1);
}

void flashPage()
{
  drawIcon(u8g2_font_open_iconic_play_4x_t,u8g2.getDisplayWidth()/2-12,u8g2.getDisplayHeight()-22,64); 
  u8g2.setFont(u8g2_font_glasstown_nbp_tf);
  u8g2.setCursor(50,55);
  u8g2.print(F("Soundpod"));
//  u8g2.drawStr(50,u8g2.getDisplayHeight()-5,"Soundpod"); 
}

void topMenu()
{
    u8g2.setFont(u8g2_font_open_iconic_play_1x_t);
    
    if(volume > 20)
    u8g2.drawGlyph(119,9,79);
    
    if(volume <= 20)
    u8g2.drawGlyph(119,9,80);
    
    if(volume < 10)
    u8g2.drawGlyph(119,9,81);
//
//    u8g2.setFont(u8g2_font_glasstown_nbp_tf);
//    u8g2.setCursor(25,9);
//    u8g2.print(batteryLevel);
//    u8g2.setCursor(35,9);
//    u8g2.print("%");
}

void sideMenu()
{
    uint16_t menuList[3][2] = {{77,u8g2_font_open_iconic_play_2x_t},{64,u8g2_font_open_iconic_mime_2x_t},};

    u8g2.setFontMode(0);//,u8g2_xxx_tX,0,

    //Audio player selection
    if(abs(sMenuSelection) == 1 && inSideMenuSelection)
    {
    u8g2.drawRBox(0,12,20,21,3);  //u8g2.drawRBox(,,,,);
    u8g2.setDrawColor(0);//0 1    0,1
    }

    //Audio player
    drawIcon(menuList[0][1],2,30,menuList[0][0]);
    
    u8g2.setDrawColor(1);

    //About Selection
    if(abs(sMenuSelection) == 2 && inSideMenuSelection)
    {
    u8g2.drawRBox(0,33,20,19,3);
    u8g2.setDrawColor(0);
    }
    //About
    drawIcon(menuList[1][1],2,52,menuList[1][0]);
    
    u8g2.setDrawColor(1);
    u8g2.drawLine(22,0,22,68);   

    //u8g2.drawHLine(x, y, w); //  w
    //u8g2.drawVLine(x, y, h);    //  h
    //u8g2.drawLine(x1, y1, x2, y2);    //  x1y11 x2y22
}

void player()
{
  sideMenu();
  topMenu();
  
  u8g2_uint_t midOriginX = 64;
  u8g2_uint_t midOriginY = 44;

  u8g2.setFontMode(0);
  u8g2.setCursor(45,25);
  u8g2.setFont(u8g2_font_glasstown_nbp_tf);
  u8g2.print("Track : ");
  u8g2.setCursor(78,25);
  u8g2.print(file);
  u8g2.setCursor(88,25);
  u8g2.print('/');
  u8g2.setCursor(95,25);
  u8g2.print(filecounts);
  
  if(selection == 1 && !inSideMenuSelection)
    {
    u8g2.drawRBox(midOriginX-7,midOriginY-5,11,9,2);
    u8g2.setDrawColor(0);
    }    
    u8g2.setFont( u8g2_font_open_iconic_play_1x_t);
    u8g2.drawGlyph(midOriginX-5,midOriginY+4,73);
    u8g2.setDrawColor(1);

    if(selection == 2 && !inSideMenuSelection)
    {
    u8g2.drawRBox(midOriginX+7.5,midOriginY-8.5,16.5,15,3);
    u8g2.setDrawColor(0);
    }
    u8g2.setFont(u8g2_font_open_iconic_play_2x_t);
    if(playing)
    {
      u8g2.drawGlyph(midOriginX+7.5,midOriginY+7.5,68);    // ()
    }
    else
    {
     u8g2.drawGlyph(midOriginX+7.5,midOriginY+7.5,69);
    }
    u8g2.setDrawColor(1);

    if(selection == 3 && !inSideMenuSelection)
    {
    u8g2.drawRBox(midOriginX+25,midOriginY-5,12,9,2);
    u8g2.setDrawColor(0);
    }
    u8g2.setFont(u8g2_font_open_iconic_play_1x_t);
    u8g2.drawGlyph(midOriginX+27,midOriginY+4,74);
    u8g2.setDrawColor(1);

     if(selection == 4 && !inSideMenuSelection)
    {
    u8g2.setDrawColor(0);
    }
    u8g2.setFont(u8g2_font_open_iconic_arrow_1x_t);
    u8g2.drawGlyph(120,60,80 );
    u8g2.setDrawColor(1);
}

void drawIcon(const uint8_t* iconName,u8g2_uint_t  x,u8g2_uint_t  y,uint16_t  glyph)
{
    u8g2.setFont(iconName);
    u8g2.drawGlyph(x,y,glyph);
}

Input.ino

Arduino
void led_UP(){
 if(volume==0){
       setColor(0,0,0);
  }
      if(volume==1){
      setColor(255,0,255);
     }
        if(volume==4){
       setColor(0,0,255);
        }
    if(volume == 9){
       setColor(0,255,0);
  }
      if(volume == 14){
       setColor(255,255,0);
  }
   if(volume == 19){
       setColor(0,255,255);
  }
   if(volume == 24){
       setColor(255,0,0);
  }
   if(volume==29){
       setColor(0,0,255);
   }
}

void led_DOWWN(){
 if(volume== 0){
       setColor(0,0,0);
  }
      if(volume== 4){
      setColor(255,0,255);
     }
        if(volume == 9){
       setColor(0,0,255);
        }
    if(volume == 14){
       setColor(0,255,0);
  }
      if(volume ==19){
       setColor(255,255,0);
  }
   if(volume == 24){
       setColor(0,255,255);
  }
   if(volume == 29){
       setColor(255,0,0);
  }
 
}
void leftButtonISR()
{
  led_UP();
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 150ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 150)
 {
  updateScreen = true;  
  if(inSideMenuSelection && sMenuSelection < 2)
  {
   sMenuSelection++;
  }
  else if(selection < 4 && sMenuSelection == 1)
  {
     selection++; 
  }
  else if(selection == 1 && volume < 30 &&sMenuSelection == 2 && !inSideMenuSelection)
  {
     volume++; 
  }
  else if(selection == 2 && eq < 5 && sMenuSelection == 2 && !inSideMenuSelection)
  {
     eq++; 
  }
 }
 last_interrupt_time = interrupt_time;
}

void rightButtonISR()
{
  led_DOWWN();
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 150, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 150)
 {
  updateScreen = true;  
  if(inSideMenuSelection && sMenuSelection > 1)
  {
   sMenuSelection--;  
  }
  else if(selection > 1 && sMenuSelection == 1)
  {
    selection--;  
  }
  else if(selection == 1 && volume > 0 &&sMenuSelection == 2)
  {
     volume--; 
  }
  else if(selection == 2 && eq > 0 && sMenuSelection == 2)
  {
     eq--; 
  }
 }
 last_interrupt_time = interrupt_time;
}

soundpod.ino

Arduino
#include <Arduino.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <EEPROM.h>

#define led1 11
#define led2 10
#define led3 6

SoftwareSerial customSoftwareSerial(12,13);
DFRobotDFPlayerMini myDFPlayer;

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

const uint8_t leftButton = 2;
const uint8_t selectionButton = 5;
const uint8_t rightButton = 3;

volatile uint8_t sMenuSelection = 2;
volatile uint8_t selection = 1;
volatile bool updateScreen = true;

boolean playing = false;
boolean inSideMenuSelection = true;

// Variables
uint8_t filecounts;                     // total number of files in current folder
uint8_t foldercounts;                   // total number of folders on sd-card

uint8_t volume = 20;                    // current volume (0 .. 30)
uint8_t folder = 1;                     // current sd-card folder
uint8_t file   = 1;                     // curent file in current folder
uint8_t eq = 0;

uint8_t batteryLevel = 0;
float resistor_ratio_factor = 3.91;
uint8_t mins = 0;
unsigned long lastTimepassed = 0;

void setup(void) {
    //Initializing u8g2 library
    Serial.begin(9200);
  u8g2.begin();  
  u8g2.firstPage(); 
  do{
    flashPage();    
  }while(u8g2.nextPage());
  pinMode(leftButton,INPUT_PULLUP);
  pinMode(rightButton,INPUT_PULLUP);
  pinMode(selectionButton,INPUT_PULLUP);

  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(leftButton),leftButtonISR, FALLING);
  attachInterrupt(digitalPinToInterrupt(rightButton),rightButtonISR, FALLING);
  
  //being hardware serial for debugging
  Serial.begin(9600);
  //Initializing software serial
  customSoftwareSerial.begin(9600);

  if (!myDFPlayer.begin(customSoftwareSerial)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Please insert the SD card!")); 
  }
  volume = EEPROM.read(0);
  if(volume > 30)
  volume = 30;
  
  eq     = EEPROM.read(1);
  if(eq > 5)
  eq = 5;
  
  file   = EEPROM.read(2);
  if(file >= 255)
  file = 1;
  
  delay(1000);
  myDFPlayer.volume(volume);  //Set volume value. From 0 to 30
  delay(500);
  foldercounts = myDFPlayer.readFolderCounts();
  startFolderPlay();
//  
}

void setColor(int red,int green,int blue)

{

  analogWrite(led1,255-red);

  analogWrite(led2,255-green);

  analogWrite(led3,255-blue);

}
void loop() {
  batteryReader();
//Selection button
  if(!digitalRead(selectionButton) && inSideMenuSelection)
  {
      inSideMenuSelection = false;
      updateScreen = true;
      delay(200);
  }
  else if(!digitalRead(selectionButton) && !inSideMenuSelection && sMenuSelection == 1)
  {
       if(selection == 1)
       {
        if(file > 1)
        {
         //previous audio
         myDFPlayer.previous();
         file--;
         if(!playing)
            playing = true;
         EEPROM.write(2, file);
        }
       }
       else if(selection == 2)
       {
         //pause / play
         if(playing)
         {
          myDFPlayer.pause();
         }
         else
         {
          myDFPlayer.start();
         }
         playing = !playing;
       }
       else if(selection == 3)
       {
          //next audio
          file++;
            myDFPlayer.next(); 
           if(!playing)
            playing = true;
            EEPROM.write(2, file);
       }
       else if(selection == 4)
       {
         //back to side menu
         selection = 1;
         inSideMenuSelection = true;
       }
       updateScreen = true;
       delay(200);
  }else if(!digitalRead(selectionButton) && !inSideMenuSelection && sMenuSelection == 2)
  {
     if(selection == 1)
     {
         selection = 2;
         myDFPlayer.volume(volume);
         EEPROM.write(0, volume);
     }
     else if(selection == 2)
     {
        selection = 4;
        myDFPlayer.EQ(eq);
        EEPROM.write(1, eq);
     }
     else if(selection == 4)
     {
         //back to side menu
         selection = 1;
         inSideMenuSelection = true;
     }
     updateScreen = true;
     delay(200);
  }

//Updating the dispaly
  if(updateScreen)
  {
    u8g2.firstPage();  
    do {
      int ch = (sMenuSelection);
      switch(ch){
          case 1:
            player();
            break;
          case 2:
            settings();
            break; 
          default:
            Serial.println(F("Default Screen"));
        }
      updateScreen = false;
      }while ( u8g2.nextPage() );
  }

   // check player status
  if (myDFPlayer.available()) {
    uint8_t type = myDFPlayer.readType();
    int value = myDFPlayer.read();

    switch (type) {
      case DFPlayerPlayFinished:
        if (file < filecounts) {
          file++;
          myDFPlayer.playFolder(folder, file);
          EEPROM.write(2, file);
          updateScreen = true;
        }
        break;
      default:
        break;
    }
  } 
}

Credits

DKARDU

DKARDU

22 projects • 44 followers
Arduino

Comments