Part 3: DF Player Mini Tinkering with Arduino Nano and LCD
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:
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
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.
Schematic Diagram:
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.
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:
1. tech-to-tinker.blogspot.com
2. tech-to-tinker Youtube Channel.
Video demonstration:
You may also visit previous videos:
Source Code:
/// MP3 PLAYER PROJECT
/// https://educ8s.tv/arduino-mp3-player/
//////////////////////////////////////////
#include "SoftwareSerial.h"
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
uint8_t bPLAY[8] = {0x00, 0x00, 0x08, 0x0C, 0x0E, 0x0C, 0x08, 0x00};
uint8_t bPAUSE[8] = {0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00};
uint8_t bNEXT[8] = {0x00, 0x00, 0x11, 0x19, 0x1D, 0x19, 0x11, 0x00};
uint8_t bPREVIOUS[8] = {0x00, 0x00, 0x11, 0x13, 0x17, 0x13, 0x11, 0x00};
uint8_t bUPVOLUME[8] = {0x00, 0x00, 0x04, 0x04, 0x0E, 0x04, 0x04, 0x00};
uint8_t bDOWNVOLUME[8] = {0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00};
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial dfpSerial(10, 11);
/*************************
DF Player Serial Format:
1. START_BYTE 0x7E
2. VERSION 0xFF
3. LENGTH 0x06
4. COMMAND CMD / operation
5. FEEDBACK 1: with Feedback, 0: no feedback
6. PARAMETER_1 Parameter of Command (High data byte)
7. PARAMETER_2 Parameter of Command (Low data byte)
8. CHECKSUM
9. CHECKSUM
10. END_BYTE 0xEF
*/
# define START_BYTE 0x7E
# define VERSION 0xFF
# define LENGTH 0x06
# define FEEDBACK 0x00
# define END_BYTE 0xEF
# define ACTIVATED LOW
const byte buttonPin = A3;
int buttonNext = A2;
int buttonPause = A1;
int buttonPrevious = A0;
boolean isPlaying = false;
unsigned long buttonTimerL = 0;
unsigned long longPressTimeL = 250;
boolean buttonActiveL = false;
boolean longPressActiveL = false;
unsigned long buttonTimerR = 0;
unsigned long longPressTimeR = 250;
boolean buttonActiveR = false;
boolean longPressActiveR = false;
byte currVolume = 25;
void setup () {
pinMode(buttonPause, INPUT_PULLUP);
pinMode(buttonNext, INPUT_PULLUP);
pinMode(buttonPrevious, INPUT_PULLUP);
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
dfpSerial.begin (9600);
delay(1000);
//playFirst();
isPlaying = false;
setVolume(currVolume);
delay(500);
lcd.begin();
lcd.backlight();
lcd.createChar(0, bPLAY);
lcd.createChar(1, bPAUSE);
lcd.createChar(2, bNEXT);
lcd.createChar(3, bPREVIOUS);
lcd.createChar(4, bUPVOLUME);
lcd.createChar(5, bDOWNVOLUME);
lcd.home();
lcd.print(" tech-to-tinker");
lcd.setCursor(0, 1);
lcd.print("MP3 PLAYER");
Serial.println("Setup Completed.");
}
// display all keycodes
void displayKeyCodes(void) {
uint8_t i = 0;
// while (1) {
lcd.clear();
lcd.print("Codes 0x");
lcd.print(i, HEX);
lcd.print("-0x");
lcd.print(i + 16, HEX);
lcd.setCursor(0, 1);
for (int j = 0; j < 16; j++) {
lcd.write(i + j);
}
i += 16;
delay(4000);
// }
}
void loop () {
// Button PREVIOUS / Volume DOWN
if (digitalRead(buttonPrevious) == LOW) {
if (buttonActiveL == false) {
buttonActiveL = true;
buttonTimerL = millis();
}
//if ((millis() - buttonTimerL > longPressTimeL) && (longPressActiveL == false)) {
if (millis() - buttonTimerL > longPressTimeL) { // multiple long press
longPressActiveL = true;
volumeDown();
Serial.println("Volume DOWN: ");
Serial.println(currVolume);
}
}
else {
if (buttonActiveL == true) {
if (longPressActiveL == true) {
longPressActiveL = false;
} else {
playPrevious();
Serial.println("Playing PREVIOUS song");
}
buttonActiveL = false;
}
}
// Button PLAY / PAUSE
if (digitalRead(buttonPause) == ACTIVATED)
{
Serial.println("Button PLAY");
if(isPlaying)
{
pause();
isPlaying = false;
Serial.println("Pause");
}else
{
isPlaying = true;
play();
Serial.println("Play");
}
}
// Button NEXT / Volume UP
if (digitalRead(buttonNext) == LOW) {
if (buttonActiveR == false) {
buttonActiveR = true;
buttonTimerR = millis();
}
//if ((millis() - buttonTimerR > longPressTimeR) && (longPressActiveR == false)) {
if (millis() - buttonTimerR > longPressTimeR) { // Try multiple long press
longPressActiveR = true;
volumeUp();
Serial.println("Volume UP: ");
Serial.println(currVolume);
}
}
else {
if (buttonActiveR == true) {
if (longPressActiveR == true) {
longPressActiveR = false;
} else {
playNext();
Serial.println("Playing NEXT song");
}
buttonActiveR = false;
}
}
}
void play() {
// Playback
execute_CMD(0x0D,0,1);
lcd.setCursor(14, 1);
lcd.write(0);
delay(500);
}
void pause() {
execute_CMD(0x0E,0,0);
lcd.setCursor(14, 1);
lcd.write(1);
delay(500);
}
void playNext() {
// Next
execute_CMD(0x01,0,1);
lcd.setCursor(14, 1);
lcd.write(2);
delay(500);
}
void playPrevious() {
// Previous
execute_CMD(0x02,0,1);
lcd.setCursor(14, 1);
lcd.write(3);
delay(500);
}
void volumeUp() {
if (currVolume < 30) {
currVolume++;
setVolume(currVolume);
lcd.setCursor(14, 1);
lcd.write(4);
delay(500);
}
}
void volumeDown() {
if (currVolume > 0){
currVolume--;
setVolume(currVolume);
lcd.setCursor(14, 1);
lcd.write(5);
delay(500);
}
}
void setVolume(int volume) {
execute_CMD(0x06, 0, volume); // Set the volume (0x00~0x30)
delay(2000);
}
void execute_CMD(byte CMD, byte Par1, byte Par2) {
// Excecute the command and parameters
// Calculate the checksum (2 bytes)
word checksum = -(VERSION + LENGTH + CMD + FEEDBACK + Par1 + Par2);
// Build the command line
byte Command_line[10] = { START_BYTE, VERSION, LENGTH, CMD, FEEDBACK,
Par1, Par2, highByte(checksum), lowByte(checksum), END_BYTE};
//Send the command line to the module
for (byte k = 0; k < 10; k++) {
dfpSerial.write(Command_line[k]);
}
}
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!
Many errors when compiling your code, any suggestions? Try compiling the code you listed.