Dfplayer + 4x4 keypad help

#include "Keypad.h"

#include "Arduino.h"

#include "SoftwareSerial.h"

#include "DFRobotDFPlayerMini.h"

 

SoftwareSerial mySoftwareSerial(10, 11);  // RX, TX

DFRobotDFPlayerMini myDFPlayer;




const byte ROWS = 4;  //four rows

const byte COLS = 4;  //four columns

 

char keys[ROWS][COLS] = {

  { '1', '2', '3', 'A' },

  { '4', '5', '6', 'B' },

  { '7', '8', '9', 'C' },

  { '*', '0', '#', 'D' }

};

 

byte rowPins[ROWS] = { 9, 8, 7, 6 };  //connect to the row pinouts of the keypad

byte colPins[COLS] = { 5, 4, 3, 2 };  //connect to the column pinouts of the keypad

 

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

 

String keypadKeys = "1234567890*#ABCD";

 

void setup() {

 

 mySoftwareSerial.begin(9600);

  Serial.begin(9600);

 

  if (!myDFPlayer.begin(mySoftwareSerial)) {  //Use softwareSerial to communicate with mp3.

    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)

      ;

  }

 

  myDFPlayer.volume(10);  //Set volume value. From 0 to 30

}

 

void loop() {

 

  char keyPressed = keypad.getKey();

 

  if (keyPressed) {

    Serial.println(keyPressed);

    int sampleIndex = 1 + keypadKeys.indexOf(keyPressed);  //Convert pressed key (1234567890*#ABCD) to sample index (1-16)

    Serial.println(sampleIndex);

    myDFPlayer.play(sampleIndex);

  }  //Play the chosen mp3

}

This is the code i use to play halloween sounds using dfplayer + 4x4 keypad. It works great but only for 16 tracks (16 buttons). What should i add to code to play 17-999 selections?

Write the sketch so you need a # or a * to enter the track you want.

Example

To play track 123: press 1, press 2, press 3, press #.

To play track 34: press 3, press 4, press #.

To play track 4: press 4, press #.

My code to receive multiple digit numbers from a keypad. Maybe will be helpful.

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] =
{
   {'1', '2', '3', 'A'},
   {'4', '5', '6', 'B'},
   {'7', '8', '9', 'C'},
   {'.', '0', '#','D'}

};
byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char keyBuffer[35];
bool newEntry = false;

void setup()
{
   Serial.begin(115200);
   Serial.println("Enter digits from keypad");
   Serial.println("# enters the number");
   Serial.println("keypad   * = .(DP), # = enter");
}

void loop()
{
   char key = keypad.getKey();

   if (key)
   {
      Serial.print(key);
      getEntry(key);
   }
   if (newEntry == true)
   {
      Serial.print("\nnew number entered = ");
      Serial.println(keyBuffer);

      newEntry = false;
   }
}

void getEntry(char key)
{
   static boolean entryStarted = false;
   static byte keyBufferIndex = 0;

   if (key == 'D') // delete last key entry
   {
      if (keyBufferIndex > 0)
      {
         Serial.print("\t\t");
         Serial.print(keyBuffer[keyBufferIndex - 1]);
         Serial.println("  deleted");
         keyBufferIndex --;
         return;
      }
   }
   if (entryStarted == false)
   {
      keyBufferIndex = 0;
      entryStarted = true;
      keyBuffer[keyBufferIndex] = key;
      //Serial.println(keyBuffer);
      newEntry = false;
      keyBufferIndex++;
   }
   else if (entryStarted == true && key != '#')
   {
      keyBuffer[keyBufferIndex] = key;
      //Serial.println(keyBuffer);
      keyBufferIndex++;
   }
   else if (key == '#')
   {
      keyBuffer[keyBufferIndex] = '\0';
      entryStarted = false;
      newEntry = true;
      //Serial.println(keyBuffer);
   }
}

float entryToFloat(char* entry)
{
   return (atof(entry));
}

int entryToInt(char* entry)
{
   return (atoi(entry));
}
1 Like

Pretty easy to add the capability to play the file chosen on the keypad to the previous post. Enter 1 or more digits. 'D' is backspace. # passes the number entered to a string variable. Use atoi (or atof) to convert if necessary.

#include <Keypad.h>
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"


const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] =
{
   {'1', '2', '3', 'A'},
   {'4', '5', '6', 'B'},
   {'7', '8', '9', 'C'},
   {'.', '0', '#', 'D'}
};

const byte busyPin = 10;
const byte buttonPin = 8;
const byte pinLed = 5;
const byte ssRXPin = 11;
const byte ssTXPin = 12;

byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
SoftwareSerial mp3ss(ssRXPin, ssTXPin); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

char keyBuffer[35];
bool newEntry = false;

void setup()
{
   mp3ss.begin(9600);

   Serial.begin(115200);
   Serial.println("Enter file numberthrough keypad");
   Serial.println("# enters the number and plays sound");
   Serial.println("\t Enjoy");

   myDFPlayer.begin(mp3ss);
   myDFPlayer.volume(25);
   myDFPlayer.play(3);
}

void loop()
{
   char key = keypad.getKey();

   if (key)
   {
      Serial.print(key);
      getEntry(key);
   }
   if (newEntry == true) // we heard from the keypad
   {
      Serial.print("\nnew number entered = ");
      Serial.println(keyBuffer);
// ***************
      myDFPlayer.play(atoi(keyBuffer));
// ***************
      newEntry = false;
   }
}

void getEntry(char key)
{
   static boolean entryStarted = false;
   static byte keyBufferIndex = 0;

   if (key == 'D') // delete last key entry
   {
      if (keyBufferIndex > 0)
      {
         Serial.print("\t\t");
         Serial.print(keyBuffer[keyBufferIndex - 1]);
         Serial.println("  deleted");
         keyBufferIndex --;
         return;
      }
   }
   if (entryStarted == false)
   {
      keyBufferIndex = 0;
      entryStarted = true;
      keyBuffer[keyBufferIndex] = key;
      //Serial.println(keyBuffer);
      newEntry = false;
      keyBufferIndex++;
   }
   else if (entryStarted == true && key != '#')
   {
      keyBuffer[keyBufferIndex] = key;
      //Serial.println(keyBuffer);
      keyBufferIndex++;
   }
   else if (key == '#')
   {
      keyBuffer[keyBufferIndex] = '\0';
      entryStarted = false;
      newEntry = true;
      //Serial.println(keyBuffer);
   }
}

float entryToFloat(char* entry)
{
   return (atof(entry));
}

int entryToInt(char* entry)
{
   return (atoi(entry));
}

Successfully tested on real hardware.

2 Likes

Wow!!! GroundFungus, this totally fixed my problem. I have been working on this for weeks. Thank you very much. My next move is to try and add an LCD i2c and put the 3 selections in queue on the screen. I'm going to give it my best but i'll probably be back here. Thanks to all.

Perhaps you should give a click on @groundFungus heart icon :wink:

If you use a LCD that has the hd44780 controller (1602 (16x2), 2004 (20x4) character LCD) with the PCF8574 I2C backpack, the best library is the hd44780 library. The big advantage of the hd44780 library is that it will automatically detect the I2C address and the pin mapping between the LCD and the backpack. The library is available for installation through the IDE library manager.

1 Like

Here is the hd44780 library added with a 20x4 monochrome character LCD. Displays the track number and the name of the file (4 names, I got lazy).

#include <Keypad.h>
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>

const byte numSongs = 4;
char songs[numSongs][21]    // 4 arrays of 12 chars (+ null)
{   
   {"Hello World"},
   {"Goodby Moon"},
   {"Yesterday"},
   {"Tuesday"}
};

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] =
{
   {'1', '2', '3', 'A'},
   {'4', '5', '6', 'B'},
   {'7', '8', '9', 'C'},
   {'.', '0', '#', 'D'}
};

const byte busyPin = 10;
const byte buttonPin = 8;
const byte pinLed = 5;
const byte ssRXPin = 11;
const byte ssTXPin = 12;

byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
SoftwareSerial mp3ss(ssRXPin, ssTXPin); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
hd44780_I2Cexp lcd;

char keyBuffer[35];
bool newEntry = false;

void setup()
{
   lcd.begin(20, 4);
   lcd.clear();  // the only time that you should use clear
   lcd.print("  MP3 Player test");
   lcd.setCursor(0, 1);
   lcd.print("Track # ");
   lcd.setCursor(0, 2);
   lcd.print("Track Name >> ");
   mp3ss.begin(9600);

   Serial.begin(115200);
   Serial.println("Enter file numberthrough keypad");
   Serial.println("# enters the number and plays sound");
   Serial.println("\t Enjoy");

   myDFPlayer.begin(mp3ss);
   myDFPlayer.volume(25);
   myDFPlayer.play(3);
}

void loop()
{
   char key = keypad.getKey();

   if (key)
   {
      Serial.print(key);
      getEntry(key);
   }
   if (newEntry == true) // we heard from the keypad
   {
      Serial.print("\nnew number entered = ");
      Serial.println(keyBuffer);
      // ***************
      int intKey = atoi(keyBuffer);
      myDFPlayer.play(intKey);
      lcd.setCursor(9, 1);
      lcd.print("      "); // overwrite old data
      lcd.setCursor(9, 1); // reset cursor
      lcd.print(intKey);
      if (intKey < numSongs) // must not violate array bounds
      {
         lcd.setCursor(0, 3);
         lcd.print("                    "); // overwrite old data
         lcd.setCursor(0, 3); // reset cursor
         lcd.print(songs[intKey]);
      }
      // ***************
      newEntry = false;
   }
}

void getEntry(char key)
{
   static boolean entryStarted = false;
   static byte keyBufferIndex = 0;

   if (key == 'D') // delete last key entry
   {
      if (keyBufferIndex > 0)
      {
         Serial.print("\t\t");
         Serial.print(keyBuffer[keyBufferIndex - 1]);
         Serial.println("  deleted");
         keyBufferIndex --;
         return;
      }
   }
   if (entryStarted == false)
   {
      keyBufferIndex = 0;
      entryStarted = true;
      keyBuffer[keyBufferIndex] = key;
      //Serial.println(keyBuffer);
      newEntry = false;
      keyBufferIndex++;
   }
   else if (entryStarted == true && key != '#')
   {
      keyBuffer[keyBufferIndex] = key;
      //Serial.println(keyBuffer);
      keyBufferIndex++;
   }
   else if (key == '#')
   {
      keyBuffer[keyBufferIndex] = '\0';
      entryStarted = false;
      newEntry = true;
      //Serial.println(keyBuffer);
   }
}

float entryToFloat(char* entry)
{
   return (atof(entry));
}

int entryToInt(char* entry)
{
   return (atoi(entry));
}

I leave it to you to put the song names character strings in progmem so that you don't eat up all the SRAM.

1 Like

GroundFungus, your sketch works great! I set up the LCDi2c and keyed a track and the info appeared on the screen just like you programmed, and the track played. I have the LCD 16x2. So i made the minor adjustments for that. I followed your link and ordered the 20x4 so i'm anxious to see it on the larger screen with the extra text. Now i'm going to work on getting the 1-3 selections queued on the screen to play in sequence, hopefully. Thank you again, you have saved me many hours of hair pulling. I just wish i had reached out sooner, but i did learn a lot in the process and learned even more with your help.

LarryD, thank you

Glad that i could help. I have been playing wih the mp3 player and keypad, separately. It was fun to apply what I've learned and help you.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.