Controlling DFPlayer Mini MP3 Module with Arduino

Im working on a robot using arduino mega (food serving robot) and the code was working fine until i added sound functionality. It worked till there were IR sensors array, bluetooth module, motor driver ,arduino keypad, ultrasonic sensor. but as soon as i added mp3 tf module and speaker to play sound, it started malfunctioning and not working acc to code. Im not able figure out the issue.

CODE:

#include <Keypad.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <NewPing.h> // Include the NewPing library for the ultrasonic sensor
#include <SoftwareSerial.h>
#include "DFRobotDFPlayerMini.h"


bool hasPlayed = false;
bool isStopped = false; // Flag to track if playback is stopped

#define BT_RX A8
#define BT_TX A9

SoftwareSerial btSerial(BT_RX, BT_TX); // RX, TX

// Define the trigger and echo pins for the ultrasonic sensor
#define TRIGGER_PIN 14
#define ECHO_PIN 52

NewPing sonar(TRIGGER_PIN, ECHO_PIN); // Create a NewPing object with the defined pins

// Define a threshold distance to detect obstacles (in centimeters)
#define OBSTACLE_THRESHOLD 5
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] = {53, 51, 48, 47}; // Connect to the row pinouts of the keypad
byte colPins[COLS] = {45, 43, 41, 39}; // Connect to the column pinouts of the keypad

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

int s1, s2, s3, s4, s5, s6, s7, s8;
const int ENA = 10; // PWM pin for Motor A speed control
const int IN1 = 22; // Motor A input 1
const int IN2 = 24; // Motor A input 2
const int ENB = 11; // PWM pin for Motor B speed control
const int IN3 = 26; // Motor B input 1
const int IN4 = 28; // Motor B input 2

int mode = 0; // Variable to store the selected mode

bool firstIntersectionPassed = false;
bool specialCaseActivated = false;
bool turned180 = false;

#define OLED_RESET 50
Adafruit_SSD1306 display(OLED_RESET);

void setup() {
  
static const uint8_t PIN_MP3_TX = 13; // Connects to module's RX 
static const uint8_t PIN_MP3_RX = 12; // Connects to module's TX 
SoftwareSerial hardwareSerial(PIN_MP3_RX, PIN_MP3_TX);

DFRobotDFPlayerMini player;

    pinMode(2, INPUT);
    pinMode(3, INPUT);
    pinMode(4, INPUT);
    pinMode(5, INPUT);
    pinMode(6, INPUT);
    pinMode(7, INPUT);
    pinMode(8, INPUT);
    pinMode(9, INPUT);

    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    Serial.begin(9600);
    btSerial.begin(9600); 
    hardwareSerial.begin(9600);

    if (player.begin(hardwareSerial)) {
   Serial.println("OK");

    // Set volume to maximum (0 to 30).
    player.volume(30);
    player.playMp3Folder(1);
    delay(6000);
    player.playMp3Folder(2);
    
 
  } else {
    Serial.println("Connecting to DFPlayer Mini failed!");
  }

    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;);
    }

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(10,0);
    display.println("FOOD SERVING ROBOT");
      display.setCursor(0,5);
    display.println("---------------------");
    display.display();
    delay(3000); // Delay for 3 seconds to display the greeting

    
    display.setCursor(15,15);
    display.println("CHOOSE A TABLE");
    
    display.display();
}

bool tableSelected = false; // Variable to indicate if a table number has been selected

int prevMode = 0; // Variable to store the previous mode

void loop() {
  
   if (btSerial.available()) {
        char key = btSerial.read(); // Read the character received from Bluetooth

        if (key == '1' || key == '2' || key == '3' || key == '4') {
            mode = key - '0'; // Convert char to int
            Serial.print("Selected Table: ");
            Serial.println(mode);
            specialCaseActivated = false; // Reset the special case flag
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("Selected Table: ");
            display.println(mode);
            display.display();
   
        }
        else if (key == '0') {
            turn180Degrees();
            specialCaseActivated = true; // Set the special case flag
            Serial.println("Return Button Pressed");
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.println("Return Button Pressed");
            display.display();
        }
    }
    char key = keypad.getKey();
  
    if (key != NO_KEY) {
        if (key == '1' || key == '2' || key == '3' || key == '4') {
            mode = key - '0'; // Convert char to int
            Serial.print("Selected Table: ");
            Serial.println(mode);
            specialCaseActivated = false; // Reset the special case flag
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("Selected Table: ");
            display.println(mode);
            display.display();
                     switch (mode) {
      case 1:
        player.playMp3Folder(3);// Replace with your actual file name
      
        break;
      case 2:
        player.playMp3Folder(4); // Replace with your actual file name
        break;
      case 3:
        player.playMp3Folder(5); // Replace with your actual file name
        break;
      case 4:
        player.playMp3Folder(6); // Replace with your actual file name
        break;
      default:
        break;
    }
        }
        else if (key == '0') {
            turn180Degrees();
            specialCaseActivated = true; // Set the special case flag
            Serial.println("Return Button Pressed");
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.println("Return Button Pressed");
            display.display();
        }
    }

    // If mode has been selected, start line following
    if (mode != 0) {
        // Read sensor values
        s1 = digitalRead(2);
        s2 = digitalRead(3);
        s3 = digitalRead(4);
        s4 = digitalRead(5);
        s5 = digitalRead(6);
        s6 = digitalRead(7);
        s7 = digitalRead(8);
        s8 = digitalRead(9);

        // Check for obstacles using ultrasonic sensor
        int distance = sonar.ping_cm();
        if (distance <= OBSTACLE_THRESHOLD && distance > 0) {
            // Stop the motors if an obstacle is detected
            motor_stop();
            // Print "OBSTACLE AHEAD"
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("OBSTACLE AHEAD");
            display.display();
            // Wait until the obstacle is cleared
            while (distance <= OBSTACLE_THRESHOLD && distance > 0) {
                distance = sonar.ping_cm();
                delay(50); // Adjust delay as needed
            }
            // Clear the display to revert back to normal
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("Selected Table: ");
            display.println(mode);
            display.display();
        }

        // Line following
        lineFollow();
    }
}




void lineFollow() {
  // Black = 1, White = 0

  // Forward
   if (
    ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 1) && (s5 == 1) && (s6 == 0) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 1) && (s5 == 0) && (s6 == 0) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 0) && (s5 == 1) && (s6 == 0) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 0) && (s3 == 1) && (s4 == 1) && (s5 == 1) && (s6 == 1) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 1) && (s3 == 1) && (s4 == 1) && (s5 == 1) && (s6 == 1) && (s7 == 1) && (s8 == 0))
  ) {
    forward();
  }
  // Right
  else if (
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||

    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0))
  ) {
    right();
  }
  // Left
  else if (
    ((s1==1)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0))
  ) {
    left();
  }
  // Stop
 else  if ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 0) && (s5 == 0) && (s6 == 0) && (s7 == 0) && (s8 == 0)) {
    if (!hasPlayed) { // Check if playback has not occurred yet
      motor_stop(); // Stop the motors
      Serial.println("Stopped");
      player.playMp3Folder(7); // Play file 7
      hasPlayed = true; // Set the flag to indicate playback has occurred
    }
  } else {
    // Reset the flag if sensors detect anything other than white
    hasPlayed = false;
  }


  // If all sensors are on the line and a mode has been selected, turn left or right
  if ((s1 == 1) && (s2 == 1) && (s3 == 1) && (s4 == 1) && (s5 == 1) && (s6 == 1) && (s7 == 1) && (s8 == 1)) {
    
    if (specialCaseActivated && turned180) {
      
      if (mode == 1) {
        right(); // Change behavior for table 1
        delay(1000);
        Serial.println("Returning From Table 1");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 1");
            display.println(mode);
            display.display();
      } else if (mode == 2) {
        left(); // Change behavior for table 2
        delay(1000);
        Serial.println("Returning From Table 2");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 2");
            display.println(mode);
            display.display();
      }
      else if (mode == 3) {
        forward(); // Change behavior for table 3
        delay(800);
        Serial.println("Returning From Table 3");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 3");
            display.println(mode);
            display.display();
      }
      else if (mode == 4) {
        forward(); // Change behavior for table 4
        delay(800);
       Serial.println("Returning From Table 4");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 4");
            display.println(mode);
            display.display();
      }
    } else {
      if (mode == 1) {
        left();
        delay(1000);
        Serial.println("Table 1");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Table 1");
            display.println(mode);
            display.display();
      } else if (mode == 2) {
        right();
        delay(1000);
        Serial.println("Table 2");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Table 2");
            display.println(mode);
            display.display();
      }
      else if (mode == 3){
        if (firstIntersectionPassed) {
        left(); // Turn left at the intersection
        delay(1000);
        Serial.println("Table 3: Turned left at intersection (subsequent)");
      } else {
        forward(); // Move forward without turning
        Serial.println("Table 3: Moved forward through intersection (first)");
        delay(1000); // Delay to ensure the robot fully crosses the intersection
        firstIntersectionPassed = true; // Update the flag to indicate the first intersection is passed
      }
      } 
      else if (mode == 4) {
        if (firstIntersectionPassed) {
        right(); // Turn right at the intersection
        delay(1000);
        Serial.println("Table 4: Turned right at intersection (subsequent)");
      } 
      else {
        forward(); // Move forward without turning
        Serial.println("Table 4: Moved forward through intersection (first)");
        delay(1000); // Delay to ensure the robot fully crosses the intersection
        firstIntersectionPassed = true; // Update the flag to indicate the first intersection is passed
      }
    }
    }
    
  }
}

void forward() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 130);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 130);
}

void right() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 0);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 170);
}

void left() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 170);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 0);
}

void motor_stop() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 0);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 0);
}

void turn180Degrees() {
  // Stop the robot
  motor_stop();
  delay(500); // Add a small delay for stability
  
  // Set the motors to rotate in opposite directions
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 150); // Adjust the speed as needed
  
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  analogWrite(ENB, 150); // Adjust the speed as needed
  
  // Delay for the time needed to complete the turn
  delay(1500); // Adjust the delay based on the robot's turning performance
  
  // Stop the motors
  motor_stop();
  turned180 = true; 
}

Nor will anyone else without seeing your code and a schematic of your project

3 Likes

Apologies, ive added the code.

Don't use SoftwareSerial when hardware serial ports are available. Mega has several hardware serial ports available. Use them instead of software serial for both Bluetooth and DF player.

#include <Keypad.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <NewPing.h> // Include the NewPing library for the ultrasonic sensor
//#include <SoftwareSerial.h>
#include "DFRobotDFPlayerMini.h"


bool hasPlayed = false;
bool isStopped = false; // Flag to track if playback is stopped

//#define BT_RX A8
//#define BT_TX A9

//SoftwareSerial btSerial(BT_RX, BT_TX); // RX, TX
#define btSerial Serial1 // TX=14, RX=15
#define hardwareSerial Serial2 // TX=16, RX=17

// Define the trigger and echo pins for the ultrasonic sensor
#define TRIGGER_PIN 14
#define ECHO_PIN 52

NewPing sonar(TRIGGER_PIN, ECHO_PIN); // Create a NewPing object with the defined pins

// Define a threshold distance to detect obstacles (in centimeters)
#define OBSTACLE_THRESHOLD 5
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] = {53, 51, 48, 47}; // Connect to the row pinouts of the keypad
byte colPins[COLS] = {45, 43, 41, 39}; // Connect to the column pinouts of the keypad

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

int s1, s2, s3, s4, s5, s6, s7, s8;
const int ENA = 10; // PWM pin for Motor A speed control
const int IN1 = 22; // Motor A input 1
const int IN2 = 24; // Motor A input 2
const int ENB = 11; // PWM pin for Motor B speed control
const int IN3 = 26; // Motor B input 1
const int IN4 = 28; // Motor B input 2

int mode = 0; // Variable to store the selected mode

bool firstIntersectionPassed = false;
bool specialCaseActivated = false;
bool turned180 = false;

#define OLED_RESET 50
Adafruit_SSD1306 display(OLED_RESET);
DFRobotDFPlayerMini player;

void setup() {
  
//static const uint8_t PIN_MP3_TX = 13; // Connects to module's RX 
//static const uint8_t PIN_MP3_RX = 12; // Connects to module's TX 
//SoftwareSerial hardwareSerial(PIN_MP3_RX, PIN_MP3_TX);

//DFRobotDFPlayerMini player;

    pinMode(2, INPUT);
    pinMode(3, INPUT);
    pinMode(4, INPUT);
    pinMode(5, INPUT);
    pinMode(6, INPUT);
    pinMode(7, INPUT);
    pinMode(8, INPUT);
    pinMode(9, INPUT);

    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    Serial.begin(9600);
    btSerial.begin(9600); 
    hardwareSerial.begin(9600);

    if (player.begin(hardwareSerial)) {
   Serial.println("OK");

    // Set volume to maximum (0 to 30).
    player.volume(30);
    player.playMp3Folder(1);
    delay(6000);
    player.playMp3Folder(2);
    
 
  } else {
    Serial.println("Connecting to DFPlayer Mini failed!");
  }

    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;);
    }

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(10,0);
    display.println("FOOD SERVING ROBOT");
      display.setCursor(0,5);
    display.println("---------------------");
    display.display();
    delay(3000); // Delay for 3 seconds to display the greeting

    
    display.setCursor(15,15);
    display.println("CHOOSE A TABLE");
    
    display.display();
}

bool tableSelected = false; // Variable to indicate if a table number has been selected

int prevMode = 0; // Variable to store the previous mode

void loop() {
  
   if (btSerial.available()) {
        char key = btSerial.read(); // Read the character received from Bluetooth

        if (key == '1' || key == '2' || key == '3' || key == '4') {
            mode = key - '0'; // Convert char to int
            Serial.print("Selected Table: ");
            Serial.println(mode);
            specialCaseActivated = false; // Reset the special case flag
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("Selected Table: ");
            display.println(mode);
            display.display();
   
        }
        else if (key == '0') {
            turn180Degrees();
            specialCaseActivated = true; // Set the special case flag
            Serial.println("Return Button Pressed");
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.println("Return Button Pressed");
            display.display();
        }
    }
    char key = keypad.getKey();
  
    if (key != NO_KEY) {
        if (key == '1' || key == '2' || key == '3' || key == '4') {
            mode = key - '0'; // Convert char to int
            Serial.print("Selected Table: ");
            Serial.println(mode);
            specialCaseActivated = false; // Reset the special case flag
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("Selected Table: ");
            display.println(mode);
            display.display();
                     switch (mode) {
      case 1:
        player.playMp3Folder(3);// Replace with your actual file name
      
        break;
      case 2:
        player.playMp3Folder(4); // Replace with your actual file name
        break;
      case 3:
        player.playMp3Folder(5); // Replace with your actual file name
        break;
      case 4:
        player.playMp3Folder(6); // Replace with your actual file name
        break;
      default:
        break;
    }
        }
        else if (key == '0') {
            turn180Degrees();
            specialCaseActivated = true; // Set the special case flag
            Serial.println("Return Button Pressed");
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.println("Return Button Pressed");
            display.display();
        }
    }

    // If mode has been selected, start line following
    if (mode != 0) {
        // Read sensor values
        s1 = digitalRead(2);
        s2 = digitalRead(3);
        s3 = digitalRead(4);
        s4 = digitalRead(5);
        s5 = digitalRead(6);
        s6 = digitalRead(7);
        s7 = digitalRead(8);
        s8 = digitalRead(9);

        // Check for obstacles using ultrasonic sensor
        int distance = sonar.ping_cm();
        if (distance <= OBSTACLE_THRESHOLD && distance > 0) {
            // Stop the motors if an obstacle is detected
            motor_stop();
            // Print "OBSTACLE AHEAD"
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("OBSTACLE AHEAD");
            display.display();
            // Wait until the obstacle is cleared
            while (distance <= OBSTACLE_THRESHOLD && distance > 0) {
                distance = sonar.ping_cm();
                delay(50); // Adjust delay as needed
            }
            // Clear the display to revert back to normal
            display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(15,15);
            display.print("Selected Table: ");
            display.println(mode);
            display.display();
        }

        // Line following
        lineFollow();
    }
}




void lineFollow() {
  // Black = 1, White = 0

  // Forward
   if (
    ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 1) && (s5 == 1) && (s6 == 0) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 1) && (s5 == 0) && (s6 == 0) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 0) && (s5 == 1) && (s6 == 0) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 0) && (s3 == 1) && (s4 == 1) && (s5 == 1) && (s6 == 1) && (s7 == 0) && (s8 == 0)) ||
    ((s1 == 0) && (s2 == 1) && (s3 == 1) && (s4 == 1) && (s5 == 1) && (s6 == 1) && (s7 == 1) && (s8 == 0))
  ) {
    forward();
  }
  // Right
  else if (
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||

    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==1)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==1)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==0)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0))
  ) {
    right();
  }
  // Left
  else if (
    ((s1==1)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==1)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==1)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==1)&&(s2==0)&&(s3==0)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==0)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==0)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==0)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==0)&&(s7==0)&&(s8==0)) ||
    ((s1==0)&&(s2==1)&&(s3==1)&&(s4==1)&&(s5==1)&&(s6==1)&&(s7==0)&&(s8==0))
  ) {
    left();
  }
  // Stop
 else  if ((s1 == 0) && (s2 == 0) && (s3 == 0) && (s4 == 0) && (s5 == 0) && (s6 == 0) && (s7 == 0) && (s8 == 0)) {
    if (!hasPlayed) { // Check if playback has not occurred yet
      motor_stop(); // Stop the motors
      Serial.println("Stopped");
      player.playMp3Folder(7); // Play file 7
      hasPlayed = true; // Set the flag to indicate playback has occurred
    }
  } else {
    // Reset the flag if sensors detect anything other than white
    hasPlayed = false;
  }


  // If all sensors are on the line and a mode has been selected, turn left or right
  if ((s1 == 1) && (s2 == 1) && (s3 == 1) && (s4 == 1) && (s5 == 1) && (s6 == 1) && (s7 == 1) && (s8 == 1)) {
    
    if (specialCaseActivated && turned180) {
      
      if (mode == 1) {
        right(); // Change behavior for table 1
        delay(1000);
        Serial.println("Returning From Table 1");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 1");
            display.println(mode);
            display.display();
      } else if (mode == 2) {
        left(); // Change behavior for table 2
        delay(1000);
        Serial.println("Returning From Table 2");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 2");
            display.println(mode);
            display.display();
      }
      else if (mode == 3) {
        forward(); // Change behavior for table 3
        delay(800);
        Serial.println("Returning From Table 3");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 3");
            display.println(mode);
            display.display();
      }
      else if (mode == 4) {
        forward(); // Change behavior for table 4
        delay(800);
       Serial.println("Returning From Table 4");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Returning From Table 4");
            display.println(mode);
            display.display();
      }
    } else {
      if (mode == 1) {
        left();
        delay(1000);
        Serial.println("Table 1");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Table 1");
            display.println(mode);
            display.display();
      } else if (mode == 2) {
        right();
        delay(1000);
        Serial.println("Table 2");
         display.clearDisplay();
            display.setTextSize(1);
            display.setTextColor(SSD1306_WHITE);
            display.setCursor(0,0);
            display.print("Table 2");
            display.println(mode);
            display.display();
      }
      else if (mode == 3){
        if (firstIntersectionPassed) {
        left(); // Turn left at the intersection
        delay(1000);
        Serial.println("Table 3: Turned left at intersection (subsequent)");
      } else {
        forward(); // Move forward without turning
        Serial.println("Table 3: Moved forward through intersection (first)");
        delay(1000); // Delay to ensure the robot fully crosses the intersection
        firstIntersectionPassed = true; // Update the flag to indicate the first intersection is passed
      }
      } 
      else if (mode == 4) {
        if (firstIntersectionPassed) {
        right(); // Turn right at the intersection
        delay(1000);
        Serial.println("Table 4: Turned right at intersection (subsequent)");
      } 
      else {
        forward(); // Move forward without turning
        Serial.println("Table 4: Moved forward through intersection (first)");
        delay(1000); // Delay to ensure the robot fully crosses the intersection
        firstIntersectionPassed = true; // Update the flag to indicate the first intersection is passed
      }
    }
    }
    
  }
}

void forward() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 130);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 130);
}

void right() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 0);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 170);
}

void left() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 170);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 0);
}

void motor_stop() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 0);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  analogWrite(ENB, 0);
}

void turn180Degrees() {
  // Stop the robot
  motor_stop();
  delay(500); // Add a small delay for stability
  
  // Set the motors to rotate in opposite directions
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 150); // Adjust the speed as needed
  
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  analogWrite(ENB, 150); // Adjust the speed as needed
  
  // Delay for the time needed to complete the turn
  delay(1500); // Adjust the delay based on the robot's turning performance
  
  // Stop the motors
  motor_stop();
  turned180 = true; 
}

Another mistake was to put the declaration of the software serial object and the DFRobotDFPlayerMini object inside setup() which makes them local to setup() and so they will get deleted as soon as setup() finishes.

i ran this code but its not taking bluetooth input, not reacting to phone commands.

Post your schematic.

Please post a schematic. If you don't know what that is, Google for examples. Fritzing has a schematic view, please use it. Alternatively, hand drawn will be fine so long as it is neat.

From the fuzzy wiring diagram you posted, I can't tell if you connected the Bluetooth module correctly or not, because the pin names are unreadable.

ill share the schematic shortly. I connected Tx if HC05 to 14 and Rx to 15

That's the wrong way. You connected TX to TX and RX to RX. With serial (UART) you should always connect TX to RX and RX to TX.

If you didn't know that, how did you get it working before? Or did it never work?

I already tried changing them still no response

Are you still using SoftwareSerial ?

How do you know the code was working? Were you viewing serial monitor?

I can't see how your circuit can work in any way from the wiring diagram. The L298 module will need 6.5-7V minimum input to make 5V output for the Mega. It can't do that from a 3.7V battery, it is not a DC-DC "boost" converter. So it's output might be 2~3V.

You have then connected the 5V output if the L298 module, which is maybe 2~3V in reality, to the Vin pin of the Mega, which requires also 6.5~7V minimum. The Mega's main chip might get 0.5~1.5V, which is not going to work.

it was working, im not using 3.7v batt. im using 2200mAh lipo batt.

no, its commented out

The capacity is irrelevant. The voltage is the problem.

Your diagram shows 3.7V.

what capacity batt should i use. robot was functioning fine with all modules except mp3 tf with speaker. also, im not using amplifier so is that a problem?

More is better.

No

Is there a restriction ? like will there be a problem to aduino if I use higher mAh battery?

No.

Ok, yes. A very high capacity battery will be so large and heavy that your robot will not be able to move.