Part 3: DF Player Mini Tinkering with Arduino Nano and LCD

Introduction

To explore more with the functionalities of DF Player Mini, an LCD display is good added feature for this project. To save pin connection, we will use an I2C LCD. Since this is Part 3 of the series in tinkering with DF Player Mini, you may visit:

Bill Of Materials

  1. DF Player mini board
  2. Arduino Nano
  3. I2C 16×2 LCD
  4. Micro SD card with mp3 files inside
  5. Some tactile switch
  6. LED
  7. Resistor
  8. Power supply of 3.3V to 5.0V
  9. A speaker
  10. Breadboard (or a perfboard)
  11. Some jumper wires

Hardware Instruction

  1. Insert the micro SD card to the DF player mini.
  2. Place the DF player mini to the breadboard.
  3. Connect power supply +5V to VCC pin (pin 1, please refer to below picture)
  4. Connect power supply ground to GND pin (pin 7 and pin 10).
  5. Connect the speaker – pin to SPK_1 (pin 6) and speaker + pin to SPK_2 pins (pin 8).
  6. Connect 1K Ohm resistor in between Arduino Nano Tx pin (pin 11) and DFP Rx pin (pin 2). This is very important since DF Player Mini is 3.3V compliant while our Arduino Nano is 5.0V compliant.
  7. Connect the Arduino Nano Rx pin (pin 10) to DF Player Mini Tx pin (pin 3).
  8. Connect 1K Ohm resistor and an LED in busy pin (pin 16). BUSY pin works as follows: Logic HIGH: not busy Logic LOW : busy, something is playing
  9. All other pins of DF Player is not used (pin 4, 5, 9, 11, 12, 13, 14, and 15).
  10. Connect SDA of I2C LCD to A4 of Arduino Nano.
  11. Connect SCL of I2C LCD to A5 of Arduino Nano.
  12. Now that our setup is ready, connect the Arduino Nano to the computer with Arduino IDE installed.
  13. Make sure that the port selected is correct.
  14. Select “Arduino Nano” under Tools > Board.
  15. Select “ATMega328P (Old Bootloader)” under Tools > Processor when you are using a clone copy of Arduino Nano.
  16. Upload the sketch (please refer to the source code provided below).
  17. Enjoy. If you find this lesson useful, consider supporting my blogs:

Schematic Diagram

Video demonstration

j

Source Code

  1///              MP3 PLAYER PROJECT
  2/// https://educ8s.tv/arduino-mp3-player/
  3//////////////////////////////////////////
  4
  5
  6#include "SoftwareSerial.h"
  7#include "Wire.h"
  8#include "LiquidCrystal_I2C.h"
  9
 10
 11uint8_t bPLAY[8] = {0x00, 0x00, 0x08, 0x0C, 0x0E, 0x0C, 0x08, 0x00};
 12uint8_t bPAUSE[8] = {0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00};
 13uint8_t bNEXT[8] = {0x00, 0x00, 0x11, 0x19, 0x1D, 0x19, 0x11, 0x00};
 14uint8_t bPREVIOUS[8] = {0x00, 0x00, 0x11, 0x13, 0x17, 0x13, 0x11, 0x00};
 15uint8_t bUPVOLUME[8] = {0x00, 0x00, 0x04, 0x04, 0x0E, 0x04, 0x04, 0x00};
 16uint8_t bDOWNVOLUME[8] = {0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00};
 17
 18// Set the LCD address to 0x27 for a 16 chars and 2 line display
 19LiquidCrystal_I2C lcd(0x27, 16, 2);
 20
 21
 22SoftwareSerial dfpSerial(10, 11);
 23
 24/*************************
 25DF Player Serial Format:
 26  1. START_BYTE     0x7E
 27  2. VERSION        0xFF
 28  3. LENGTH         0x06
 29  4. COMMAND        CMD / operation
 30  5. FEEDBACK       1: with Feedback, 0: no feedback
 31  6. PARAMETER_1    Parameter of Command (High data byte)
 32  7. PARAMETER_2    Parameter of Command (Low data byte)
 33  8. CHECKSUM   
 34  9. CHECKSUM  
 35  10. END_BYTE      0xEF
 36
 37*/
 38# define START_BYTE 0x7E
 39# define VERSION    0xFF
 40# define LENGTH     0x06
 41# define FEEDBACK   0x00
 42# define END_BYTE   0xEF
 43
 44
 45# define ACTIVATED LOW
 46
 47const byte buttonPin = A3;
 48
 49int buttonNext = A2;
 50int buttonPause = A1;
 51int buttonPrevious = A0;
 52boolean isPlaying = false;
 53
 54unsigned long buttonTimerL = 0;
 55unsigned long longPressTimeL = 250;
 56boolean buttonActiveL = false;
 57boolean longPressActiveL = false;
 58
 59unsigned long buttonTimerR = 0;
 60unsigned long longPressTimeR = 250;
 61boolean buttonActiveR = false;
 62boolean longPressActiveR = false;
 63
 64byte currVolume = 25;
 65
 66
 67void setup () {
 68  pinMode(buttonPause, INPUT_PULLUP);
 69  pinMode(buttonNext, INPUT_PULLUP);
 70  pinMode(buttonPrevious, INPUT_PULLUP);
 71  pinMode(buttonPin, INPUT_PULLUP);
 72
 73  Serial.begin(9600);
 74
 75  dfpSerial.begin (9600);
 76  delay(1000);
 77  //playFirst();
 78  isPlaying = false;
 79
 80  setVolume(currVolume);
 81  delay(500);
 82
 83
 84  lcd.begin();
 85  lcd.backlight();
 86
 87  lcd.createChar(0, bPLAY);
 88  lcd.createChar(1, bPAUSE);
 89  lcd.createChar(2, bNEXT);
 90  lcd.createChar(3, bPREVIOUS);
 91  lcd.createChar(4, bUPVOLUME);
 92  lcd.createChar(5, bDOWNVOLUME);
 93
 94  lcd.home();
 95  lcd.print(" tech-to-tinker");
 96  
 97  lcd.setCursor(0, 1);
 98  lcd.print("MP3 PLAYER");
 99
100  Serial.println("Setup Completed.");
101}
102
103// display all keycodes
104void displayKeyCodes(void) {
105  uint8_t i = 0;
106
107 // while (1) {
108    lcd.clear();
109    lcd.print("Codes 0x");
110    lcd.print(i, HEX);
111    lcd.print("-0x");
112    lcd.print(i + 16, HEX);
113    lcd.setCursor(0, 1);
114
115    for (int j = 0; j < 16; j++) {
116      lcd.write(i + j);
117    }
118    i += 16;
119
120    delay(4000);
121 // }
122}
123
124void loop () { 
125  // Button PREVIOUS / Volume DOWN
126  if (digitalRead(buttonPrevious) == LOW) {
127    if (buttonActiveL == false) {
128      buttonActiveL = true;
129      buttonTimerL = millis();
130    }
131    //if ((millis() - buttonTimerL > longPressTimeL) && (longPressActiveL == false)) {
132    if (millis() - buttonTimerL > longPressTimeL) { // multiple long press
133      longPressActiveL = true;
134      volumeDown();
135      Serial.println("Volume DOWN: ");
136      Serial.println(currVolume);
137    }
138  } 
139  else {
140    if (buttonActiveL == true) {
141      if (longPressActiveL == true) {
142        longPressActiveL = false;
143      } else {
144        playPrevious();
145        Serial.println("Playing PREVIOUS song");
146      }
147      buttonActiveL = false;
148    }
149  }
150
151  // Button PLAY / PAUSE
152  if (digitalRead(buttonPause) == ACTIVATED)
153  {
154    Serial.println("Button PLAY");
155    if(isPlaying)
156    {
157      pause();
158      isPlaying = false;
159      Serial.println("Pause");
160    }else
161    {
162      isPlaying = true;
163      play();
164      Serial.println("Play");
165    }
166  }
167
168  // Button NEXT / Volume UP
169  if (digitalRead(buttonNext) == LOW) {
170    if (buttonActiveR == false) {
171      buttonActiveR = true;
172      buttonTimerR = millis();
173    }
174
175    //if ((millis() - buttonTimerR > longPressTimeR) && (longPressActiveR == false)) {
176    if (millis() - buttonTimerR > longPressTimeR) { // Try multiple long press
177      longPressActiveR = true;
178      volumeUp();
179      Serial.println("Volume UP: ");
180      Serial.println(currVolume);
181    }
182
183  } 
184  else {
185    if (buttonActiveR == true) {
186      if (longPressActiveR == true) {
187        longPressActiveR = false;
188      } else {
189        playNext();
190        Serial.println("Playing NEXT song");
191      }
192      buttonActiveR = false;
193    }
194  }
195}
196
197
198void play() {
199  // Playback
200  execute_CMD(0x0D,0,1); 
201  lcd.setCursor(14, 1);
202  lcd.write(0);
203  delay(500);
204}
205
206void pause() {
207  execute_CMD(0x0E,0,0);
208  lcd.setCursor(14, 1);
209  lcd.write(1);
210  delay(500);
211}
212
213void playNext() {
214  // Next
215  execute_CMD(0x01,0,1);
216  lcd.setCursor(14, 1);
217  lcd.write(2);
218  delay(500);
219}
220
221void playPrevious() {
222  // Previous
223  execute_CMD(0x02,0,1);
224  lcd.setCursor(14, 1);
225  lcd.write(3);
226  delay(500);
227}
228
229void volumeUp() {
230  if (currVolume < 30) {
231    currVolume++;
232    setVolume(currVolume);
233    lcd.setCursor(14, 1);
234    lcd.write(4);
235    delay(500);
236  }
237}
238
239void volumeDown() {
240  if (currVolume > 0){
241    currVolume--;
242    setVolume(currVolume);
243    lcd.setCursor(14, 1);
244    lcd.write(5);
245    delay(500);
246  }
247}
248
249void setVolume(int volume) {
250  execute_CMD(0x06, 0, volume); // Set the volume (0x00~0x30)
251  delay(2000);
252}
253
254void execute_CMD(byte CMD, byte Par1, byte Par2) {
255  // Excecute the command and parameters
256
257  // Calculate the checksum (2 bytes)
258  word checksum = -(VERSION + LENGTH + CMD + FEEDBACK + Par1 + Par2);
259
260  // Build the command line
261  byte Command_line[10] = { START_BYTE, VERSION, LENGTH, CMD, FEEDBACK,
262                            Par1, Par2, highByte(checksum), lowByte(checksum), END_BYTE};
263
264  //Send the command line to the module
265  for (byte k = 0; k < 10; k++) {
266    dfpSerial.write(Command_line[k]);
267  }
268}

Call To Action

That’s all folks. If you have any question or suggestion, please feel free to leave your comment box. Thank you and have a good day. Happy tinkering!

1. techtotinker.com
2. TechToTinker Youtube Channel.

References And Credits

  1. Part 2: DF Player Mini Tinkering with Arduino Nano

  2. Part 1: DF Player Mini – a mini cheap mp3 player



Posts in this series



No comments yet!

GitHub-flavored Markdown & a sane subset of HTML is supported.