Ok so I have some success with this code. The DFPlayer will now play the MP3 when called via the OLED menu I have created. But calling the function a second time freezes the program without playing the MP3.
I have used D4 and D5 for RX and TX respectively as D6 and D7 are not clear on the board I'm using. But as pointed out this should not make a difference?
I have tried "Tagging out" all the serial monitor start and print commands. I have also tried with and without the delay functions.
I even tried putting the duel play code (below) in a function and called that instead but it only played the first MP3.
Serial.println("Playing #1");
player.play(1);
Serial.println("play start");
delay(10000);
Serial.println("played");
delay(1000);
Serial.println("Playing #2");
player.play(2);
Serial.println("play start");
delay(10000);
Serial.println("played");
delay(1000);
my updated code is as follows
#include "Arduino.h"
#include <WiFi.h>
#include <esp_now.h>
#include <FastLED.h>
// Include Wire Library for I2C
#include <Wire.h>
#include "HardwareSerial.h"
#include "DFRobotDFPlayerMini.h"
// Include Adafruit Graphics & OLED libraries
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//define RGB led
#define DATA_PIN 2
#define NUM_LEDS 12
#define BRIGHTNESS 40
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
#define BUTTON_LED 18
#define BUZZER_LEDS 19
#define CORRECT_PUSH_BUTTON 25
#define INCORRECT_PUSH_BUTTON 27
#define ENTER_PUSH_BUTTON 16
#define SELECT_PUSH_BUTTON 17
// Reset pin not used but needed for library
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
const byte RXD2 = 4;
const byte TXD2 = 5;
int RedTrack = 1;
int BlueTrack = 1;
int GreenTrack = 1;
int YellowTrack = 1;
int Volume = 15;
bool StartUp = true;
bool Reset = true;
bool CorrectPushButton = false;
bool IncorrectPushButton = false;
bool EnterPushButton = false;
bool SelectPushButton = false;
bool Lockout = false;
String Contestant = "";
bool GreenLockout = false;
bool BlueLockout = false;
bool RedLockout = false;
bool YellowLockout = false;
bool GreenScore = false;
bool BlueScore = false;
bool RedScore = false;
bool YellowScore = false;
String DisplayLine1 = "RED Button";
String DisplayLine2 = "Track: ";
int Track = RedTrack;
int Cursor = 0;
bool ButtonHeld = false;
bool EnterButtonHeld = false;
int ButtonNumber = 1;
bool ScreenOn = false;
CRGB leds[NUM_LEDS];
HardwareSerial dfSD(2); // Use UART channel 1
DFRobotDFPlayerMini player;
#define UPDATES_PER_SECOND 100
void formatMacAddress(const uint8_t *macAddr, char *buffer, int maxLength)
// Formats MAC Address
{
snprintf(buffer, maxLength, "%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
}
void receiveCallback(const uint8_t *macAddr, const uint8_t *data, int dataLen)
// Called when data is received
{
// Only allow a maximum of 250 characters in the message + a null terminating byte
char buffer[ESP_NOW_MAX_DATA_LEN + 1];
int msgLen = min(ESP_NOW_MAX_DATA_LEN, dataLen);
strncpy(buffer, (const char *)data, msgLen);
// Make sure we are null terminated
buffer[msgLen] = 0;
// Format the MAC address
char macStr[18];
formatMacAddress(macAddr, macStr, 18);
// Send Debug log message to the serial port
Serial.printf("Received message from: %s - %s\n", macStr, buffer);
// Check correct answe status
if (Lockout == false) {
if ((strcmp("GREEN", buffer) == 0) && GreenLockout == false) {
broadcast("GREEN");
Contestant = "C_GREEN";
Lockout = true;
Reset = true;
GreenScore = true;
BlueScore = false;
RedScore = false;
YellowScore = false;
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Black;
FastLED.show();
}
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Green;
FastLED.show();
}
}
if ((strcmp("BLUE", buffer) == 0) && BlueLockout == false) {
broadcast("BLUE");
Contestant = "C_BLUE";
Lockout = true;
Reset = true;
GreenScore = false;
BlueScore = true;
RedScore = false;
YellowScore = false;
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Black;
FastLED.show();
}
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Blue;
FastLED.show();
}
}
if ((strcmp("RED", buffer) == 0) && RedLockout == false) {
broadcast("RED");
Contestant = "C_RED";
Lockout = true;
Reset = true;
GreenScore = false;
BlueScore = false;
RedScore = true;
YellowScore = false;
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Black;
FastLED.show();
}
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Red;
FastLED.show();
}
}
if ((strcmp("YELLOW", buffer) == 0) && YellowLockout == false) {
broadcast("YELLOW");
Contestant = "C_YELLOW";
Lockout = true;
Reset = true;
GreenScore = false;
BlueScore = false;
RedScore = false;
YellowScore = true;
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Black;
FastLED.show();
}
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Yellow;
FastLED.show();
}
}
}
}
void sentCallback(const uint8_t *macAddr, esp_now_send_status_t status)
// Called when data is sent
{
char macStr[18];
formatMacAddress(macAddr, macStr, 18);
Serial.print("Last Packet Sent to: ");
Serial.println(macStr);
Serial.print("Last Packet Send Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void broadcast(const String &message)
// Emulates a broadcast
{
// Broadcast a message to every device in range
uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
esp_now_peer_info_t peerInfo = {};
memcpy(&peerInfo.peer_addr, broadcastAddress, 6);
if (!esp_now_is_peer_exist(broadcastAddress)) {
esp_now_add_peer(&peerInfo);
}
// Send message
esp_err_t result = esp_now_send(broadcastAddress, (const uint8_t *)message.c_str(), message.length());
// Print results to serial monitor
if (result == ESP_OK) {
Serial.println("Broadcast message success");
} else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
Serial.println("ESP-NOW not Init.");
} else if (result == ESP_ERR_ESPNOW_ARG) {
Serial.println("Invalid Argument");
} else if (result == ESP_ERR_ESPNOW_INTERNAL) {
Serial.println("Internal Error");
} else if (result == ESP_ERR_ESPNOW_NO_MEM) {
Serial.println("ESP_ERR_ESPNOW_NO_MEM");
} else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
Serial.println("Peer not found.");
} else {
Serial.println("Unknown error");
}
}
// the setup function runs once when you press reset or power the board
void setup() {
// Set up Serial Monitor
Serial.begin(19200);
dfSD.begin(9600, SERIAL_8N1, RXD2, TXD2); // D4,D5
delay(5000);
if (player.begin(dfSD))
{
Serial.println("OK");
// Set volume to maximum (0 to 30).
player.volume(Volume); //30 is very loud
}
else
{
Serial.println("Connecting to DFPlayer Mini failed!");
}
Serial.println("player go");
// Start Wire library for I2C
Wire.begin();
// initialize OLED with I2C addr 0x3C
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// RGB set up
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
// Set ESP32 in STA mode to begin with
WiFi.mode(WIFI_STA);
Serial.println("ESP-NOW Broadcast Demo");
// Print MAC address
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
// Disconnect from WiFi
WiFi.disconnect();
// Initialize ESP-NOW
if (esp_now_init() == ESP_OK) {
Serial.println("ESP-NOW Init Success");
esp_now_register_recv_cb(receiveCallback);
esp_now_register_send_cb(sentCallback);
} else {
Serial.println("ESP-NOW Init Failed");
delay(3000);
ESP.restart();
}
// initialize digital pin LED_BUILTIN as an output.
pinMode(BUTTON_LED, OUTPUT);
pinMode(BUZZER_LEDS, OUTPUT);
pinMode(CORRECT_PUSH_BUTTON, INPUT_PULLUP);
pinMode(INCORRECT_PUSH_BUTTON, INPUT_PULLUP);
pinMode(ENTER_PUSH_BUTTON, INPUT_PULLUP);
pinMode(SELECT_PUSH_BUTTON, INPUT_PULLUP);
}
void displayMenu(){
// Clear the display
display.clearDisplay();
if (ScreenOn == true)
{
//Set the color - always use white despite actual display color
display.setTextColor(WHITE);
//Set the font size
display.setTextSize(1);
//Set the cursor coordinates
display.setCursor(0,0);
if (Cursor == 1)
{
display.setTextColor(BLACK, WHITE);
}
else
{
display.setTextColor(WHITE);
}
display.print(DisplayLine1);
display.setCursor(0,8);
if (Cursor == 2)
{
display.setTextColor(BLACK, WHITE);
}
else
{
display.setTextColor(WHITE);
}
display.print(DisplayLine2);
if (DisplayLine1 == "RED Button")
{
display.print(RedTrack);
}
if (DisplayLine1 == "BLUE Button")
{
display.print(BlueTrack);
}
if (DisplayLine1 == "GREEN Button")
{
display.print(GreenTrack);
}
if (DisplayLine1 == "YELLOW Button")
{
display.print(YellowTrack);
}
if (Cursor == 3)
{
display.setTextColor(BLACK, WHITE);
}
else
{
display.setTextColor(WHITE);
}
display.setCursor(0,16);
display.print("VOLUME: ");
if (Volume == 0)
{
display.print("OFF");
}
else
{
display.print(Volume/3);
}
if (Cursor == 4)
{
display.setTextColor(BLACK, WHITE);
}
else
{
display.setTextColor(WHITE);
}
display.setCursor(0,24);
display.print("PLAY");
if (Cursor == 5)
{
display.setTextColor(BLACK, WHITE);
}
else
{
display.setTextColor(WHITE);
}
display.setCursor(90,24);
display.print("<EXIT>");
}
}
// the loop function runs over and over again forever
void loop() {
if (SelectPushButton == HIGH)
{
ButtonHeld = false;
}
if (EnterPushButton == HIGH)
{
EnterButtonHeld = false;
}
EnterPushButton = digitalRead(ENTER_PUSH_BUTTON);
SelectPushButton = digitalRead(SELECT_PUSH_BUTTON);
if (SelectPushButton == LOW && ButtonHeld == false)
{
ScreenOn = true;
ButtonHeld = true;
Cursor = Cursor +1;
if (Cursor == 6)
{
Cursor = 1;
}
displayMenu();
display.display();
}
if (Cursor == 1) //Button select option
{
if (EnterPushButton == LOW && EnterButtonHeld == false)
{
EnterButtonHeld = true;
ButtonNumber ++;
if (ButtonNumber == 5)
{
ButtonNumber = 1;
}
switch (ButtonNumber)
{
case 1:
DisplayLine1 = "RED Button";
break;
case 2:
DisplayLine1 = "BLUE Button";
break;
case 3:
DisplayLine1 = "GREEN Button";
break;
case 4:
DisplayLine1 = "YELLOW Button";
break;
}
}
}
if (Cursor == 2) //Track Option linked to Button Selected
{
if (EnterPushButton == LOW && EnterButtonHeld == false)
{
EnterButtonHeld = true;
if (DisplayLine1 == "RED Button")
{
RedTrack++;
if (RedTrack >= 33)
{
RedTrack = 1;
}
}
if (DisplayLine1 == "BLUE Button")
{
BlueTrack++;
if (BlueTrack >= 33)
{
BlueTrack = 1;
}
}
if (DisplayLine1 == "GREEN Button")
{
GreenTrack++;
if (GreenTrack >= 33)
{
GreenTrack = 1;
}
}
if (DisplayLine1 == "YELLOW Button")
{
YellowTrack++;
if (YellowTrack >= 33)
{
YellowTrack = 1;
}
}
}
}
if (Cursor == 3) //VOL control option
{
if (EnterPushButton == LOW && EnterButtonHeld == false)
{
EnterButtonHeld = true;
Volume = Volume +3;
player.volume(Volume); //30 is very loud
if (Volume >= 31)
{
Volume = 0;
}
}
}
if (Cursor == 4) //Play option
{
if (EnterPushButton == LOW && EnterButtonHeld == false)
{
EnterButtonHeld = true;
if (DisplayLine1 == "RED Button")
{
player.play(RedTrack);// play track number for red button
}
if (DisplayLine1 == "BLUE Button")
{
player.play(BlueTrack);// play track number for blue button
}
if (DisplayLine1 == "GREEN Button")
{
player.play(GreenTrack);// play track number for green button
}
if (DisplayLine1 == "YELLOW Button")
{
player.play(YellowTrack);// play track number for yellow button
}
}
}
if (Cursor == 5) //Exit option
{
if (EnterPushButton == LOW)
{
Cursor = 0;
ScreenOn = false;
}
}
displayMenu();
display.display();
if (StartUp == true) {
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::White;
FastLED.show();
}
StartUp = false;
}
//Reads Push Button
CorrectPushButton = digitalRead(CORRECT_PUSH_BUTTON);
if (CorrectPushButton == LOW) {
if (GreenScore == true) {
broadcast("GREEN SCORE ADD");
GreenScore = false;
}
if (BlueScore == true) {
broadcast("BLUE SCORE ADD");
BlueScore = false;
}
if (RedScore == true) {
broadcast("RED SCORE ADD");
RedScore = false;
}
if (YellowScore == true) {
broadcast("YELLOW SCORE ADD");
YellowScore = false;
}
broadcast("RESET");
broadcast(Contestant);
Lockout = false;
GreenLockout = false;
BlueLockout = false;
RedLockout = false;
YellowLockout = false;
if (Reset == true) {
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Black;
FastLED.show();
}
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::White;
FastLED.show();
}
}
Reset = false;
}
IncorrectPushButton = digitalRead(INCORRECT_PUSH_BUTTON);
if ((IncorrectPushButton == LOW) && Reset == true) {
GreenScore = false;
BlueScore = false;
RedScore = false;
YellowScore = false;
if (Contestant == "C_GREEN") {
GreenLockout = true;
}
if (Contestant == "C_BLUE") {
BlueLockout = true;
}
if (Contestant == "C_RED") {
RedLockout = true;
}
if (Contestant == "C_YELLOW") {
YellowLockout = true;
}
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::Black;
FastLED.show();
}
for (int led = 0; led < NUM_LEDS; led++) {
leds[led] = CRGB::White;
FastLED.show();
}
Reset = false;
broadcast("LOCKOUT_RESET");
Lockout = false;
}
}