//This is the code for the studdy buddy, note that the bread board mini is supposed to be the DF Player Mini
//DF PLayer Fuctions
/*
//----Set volume----
myDFPlayer.volume(10); //Set volume value (0~30).
myDFPlayer.volumeUp(); //Volume Up
myDFPlayer.volumeDown(); //Volume Down
//----Set different EQ----
myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);
// myDFPlayer.EQ(DFPLAYER_EQ_POP);
// myDFPlayer.EQ(DFPLAYER_EQ_ROCK);
// myDFPlayer.EQ(DFPLAYER_EQ_JAZZ);
// myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC);
// myDFPlayer.EQ(DFPLAYER_EQ_BASS);
//----Set device we use SD as default----
// myDFPlayer.outputDevice(DFPLAYER_DEVICE_U_DISK);
myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
// myDFPlayer.outputDevice(DFPLAYER_DEVICE_AUX);
// myDFPlayer.outputDevice(DFPLAYER_DEVICE_SLEEP);
// myDFPlayer.outputDevice(DFPLAYER_DEVICE_FLASH);
//----Mp3 control----
// myDFPlayer.sleep(); //sleep
// myDFPlayer.reset(); //Reset the module
// myDFPlayer.enableDAC(); //Enable On-chip DAC
// myDFPlayer.disableDAC(); //Disable On-chip DAC
// myDFPlayer.outputSetting(true, 15); //output setting, enable the output and set the gain to 15
//----Mp3 play----
myDFPlayer.next(); //Play next mp3
delay(1000);
myDFPlayer.previous(); //Play previous mp3
delay(1000);
myDFPlayer.play(1); //Play the first mp3
delay(1000);
myDFPlayer.loop(1); //Loop the first mp3
delay(1000);
myDFPlayer.pause(); //pause the mp3
delay(1000);
myDFPlayer.start(); //start the mp3 from the pause
delay(1000);
myDFPlayer.playFolder(15, 4); //play specific mp3 in SD:/15/004.mp3; Folder Name(1~99); File Name(1~255)
delay(1000);
myDFPlayer.enableLoopAll(); //loop all mp3 files.
delay(1000);
myDFPlayer.disableLoopAll(); //stop loop all mp3 files.
delay(1000);
myDFPlayer.playMp3Folder(4); //play specific mp3 in SD:/MP3/0004.mp3; File Name(0~65535)
delay(1000);
myDFPlayer.advertise(3); //advertise specific mp3 in SD:/ADVERT/0003.mp3; File Name(0~65535)
delay(1000);
myDFPlayer.stopAdvertise(); //stop advertise
delay(1000);
myDFPlayer.playLargeFolder(2, 999); //play specific mp3 in SD:/02/004.mp3; Folder Name(1~10); File Name(1~1000)
delay(1000);
myDFPlayer.loopFolder(5); //loop all mp3 files in folder SD:/05.
delay(1000);
myDFPlayer.randomAll(); //Random play all the mp3.
delay(1000);
myDFPlayer.enableLoop(); //enable loop.
delay(1000);
myDFPlayer.disableLoop(); //disable loop.
delay(1000);
//----Read imformation----
Serial.println(myDFPlayer.readState()); //read mp3 state
Serial.println(myDFPlayer.readVolume()); //read current volume
Serial.println(myDFPlayer.readEQ()); //read EQ setting
Serial.println(myDFPlayer.readFileCounts()); //read all file counts in SD card
Serial.println(myDFPlayer.readCurrentFileNumber()); //read current play file number
Serial.println(myDFPlayer.readFileCountsInFolder(3)); //read file counts in folder SD:/03
*/
//Libaries
#include "DFRobotDFPlayerMini.h"
#include <LiquidCrystal.h>
//DF player items
DFRobotDFPlayerMini player; // Create the Player object
//the df player uses the Rx and the Tx pins (rx2 and tx2)
//Button items (pins are diffrent than diagram)
int button_back = 5;
int button_forward = 18;
int button_select = 19;
int buttonState_back;
int buttonState_forward;
int buttonState_select;
//There is no need for Switch items since it is just to actully disconnect the power
//LCD items
const int rs = 13, en = 12, d4 = 14, d5 = 27, d6 = 26, d7 = 25;// note that the pins are diffrent from the diagram
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
//Ultra Sonic items (pins are diffrent than diagram)
const int trigPin = 15;
const int echoPin = 2;
//define sound speed in cm/uS
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701
//create variables
long duration;
float distanceCm;
float distanceIn;
//System Variables
int trackSelected = 1;
int trackRandomized = 1;
int randomOrNot = 0;
int randomOrNotLoop = 0;
int trackSelectedLoop = 0;
float recordedPositionIn = 0;
float recordedPositionIn_WithPositiveTolorence = 0;
float recordedPositionIn_WithNegitiveTolorence = 0;
int PushToRecordLoop = 0;
int setTolorenceLoop = 0;
int tolorenceIn = 1;
int ActiveLoop = 0;
int TotalTracks = 1;
int TotalTracksLoop = 0;
int SelectingTrackCount = 0;
void setup() {
// put your setup code here, to run once:
//Serial Moniter
Serial.begin(115200);// Init USB serial port for debugging
Serial2.begin(9600); // Init serial port for DFPlayer Mini
Serial.println("Turning on"); //To identify that the esp32 turned on
// Start communication with DFPlayer Mini
Serial.println("Connecting to DFplayer");
while (!player.begin(Serial2))
{
Serial.print(".");
delay(1000);
}
Serial.println(" DFplayer connected!");
//Setting the initial Volume
player.volume(30); // Set volume to maximum (0 to 30).
//Setting up Buttons
pinMode(button_back, INPUT_PULLUP); //The pull up means that I do not need an external resistor, note that LOW is now when the button is pushed and HIGH is when it is not pushed
pinMode(button_forward, INPUT_PULLUP);
pinMode(button_select, INPUT_PULLUP);
buttonState_back = digitalRead(button_back);
buttonState_forward = digitalRead(button_forward);
buttonState_select = digitalRead(button_select);
//Setting up Switches is not needed since it is just to physically disconnect the power
//Setting up LCD
lcd.begin(16, 2);
//Setting up Ultra Sonic
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}
//Fuctions
void testDF()//play the first three mp3 tracks one after another for 3 seconds
{
player.play(1);
delay(3000);
player.play(2);
delay(3000);
player.play(3);
delay(3000);
}
void readButtons()//read the three buttons and set the buttons states to be correct
{
buttonState_back = digitalRead(button_back);
buttonState_forward = digitalRead(button_forward);
buttonState_select = digitalRead(button_select);
}
//LCD Fuctions
void HelloLCD()//Introduce the study buddy
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Hello I Am");
lcd.setCursor(0,1);
lcd.print ("Study Buddy");
Serial.print("Hello Screen");
}
void RandomOrNotLCD()//To decide if the track played is specific or random
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Press + for random");
lcd.setCursor(0,1);
lcd.print ("Press - to select");
Serial.print("Random or not screen");
}
void SelectSoundLCD()//Ask for the sound that will be used to be selected
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Select Sound Track");
lcd.setCursor(0,1);
lcd.print ("Number");
Serial.print("Selecting Track Number LCD");
}
void SoundSelectedLCD()//Tell that the track was selected
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Sound Selected");
Serial.print("Sound Selected");
}
void PushToRecordLCD()//Tell that you need to push select
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Push Select");
lcd.setCursor(0,1);
lcd.print ("Then Move");
Serial.print("Select then Move");
}
void moveNowLCD()//Tell that you need to move
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Move Into");
lcd.setCursor(0,1);
lcd.print ("Position");
Serial.print("Get into Position on LCD");
}
void SecondsPassedLCD()//Note that it is halfway till time it will record
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("30 Seconds");
lcd.setCursor(0,1);
lcd.print ("Left");
Serial.print("30 Seconds Left to get into position");
}
void PositionRecordedLCD()//note that the postion your in has been recored and that you need to physically use the off switch when done
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Position Recorded");
Serial.print("Position Recorded");
}
void RandomTrackLCD()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Random Track");
lcd.setCursor(0,1);
lcd.print ("Selected");
Serial.println("Random Track Selected LCD");
}
void DecisionLCD()//this displays the correct LCD screen depending on if the random or selection track was made
{
Serial.println("Decision LCD");
if(randomOrNot == 1){//if they want to select the track themselves
SelectSoundLCD();//Ask for the sound that will be used to be selected
}else if(randomOrNot == 2){//if they want a random track each time
RandomTrackLCD();
}
}
void SelectingTheTrackLCD()//this explains how to select the track, that they should press forword to change the track and press select to confirm the track
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Use + to change track");
lcd.setCursor(0,1);
lcd.print ("Use - to go back");
Serial.print("giving instructions for how to select track");
}
void TrackBeingSelectedLCD()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Current Track");
lcd.setCursor(0,1);
lcd.print (trackSelected);
Serial.print("current track displayed");
}
void SettingDistanceLCD()//This lets the user know that we will now be going threw the steps of setting the distance
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Now to");
lcd.setCursor(0,1);
lcd.print ("Record Position");
Serial.print("letting user know position will be recorded soon");
}
void SettingGiveLCD()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Set Tolorence");
lcd.setCursor(0,1);
lcd.print ("Of Position");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Of Position");
lcd.setCursor(0,1);
lcd.print ("In Inches");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Use +");
lcd.setCursor(0,1);
lcd.print ("Then Select");
Serial.print("letting user know to set the tolorence");
}
void ActiveLCD()
{
Serial.print("Showing user activate screen");
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Activating");
lcd.setCursor(0,1);
lcd.print ("Studdy Buddy");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Push Select");
lcd.setCursor(0,1);
lcd.print ("Or Turn Off");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("When Done");
lcd.setCursor(0,1);
lcd.print ("Now Activating");
}
void howManyTracksLCD()//This has the user tell how many tracks there are incase they choose to have it be random
{
Serial.print("Having the user tell how many tracks there are");
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("How Many");
lcd.setCursor(0,1);
lcd.print ("Total Tracks");
delay(4000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Push +");
lcd.setCursor(0,1);
lcd.print ("Then Select");
}
void howManyTracksLoopLCD()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print ("Current Number");
lcd.setCursor(0,1);
lcd.print (TotalTracks);
Serial.print("Current Total Tracks:");
Serial.print(TotalTracks);
}
//Ulra Sonic
void find_distance()//uses the ultra sonic to find the distance and then print it on the serial monitor
{
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance
distanceCm = duration * SOUND_SPEED/2;
// Convert to inches
distanceIn = distanceCm * CM_TO_INCH;
// Prints the distance in the Serial Monitor
Serial.print("Distance (cm): ");
Serial.println(distanceCm);
Serial.print("Distance (inch): ");
Serial.println(distanceIn);
delay(1000);
}
//Other Fuctions
void howManyTracks()// not done, This has the user tell how many tracks there are incase they choose to have it be random
{
while(TotalTracksLoop == 0)
{
howManyTracksLoopLCD();
if(buttonState_forward == LOW){ //if forward is pushed increase the total tracks
TotalTracks = TotalTracks + 1;
Serial.print("Current Total Tracks increased to:");
Serial.print(TotalTracks);
}
if(buttonState_back == LOW && TotalTracks > 1){ //if forward is pushed and the total tracks is more than one decrease the total tracks
TotalTracks = TotalTracks - 1;
Serial.print("Current Total Tracks decreased to:");
Serial.print(TotalTracks);
}
if(buttonState_select == LOW){//push select to end the loop
TotalTracksLoop = 1;
break;
}
}
}
void RandomOrNotSelect()//The if statment tells if the person wants the track played to be random or not
{
while(randomOrNotLoop == 0)//While the desision for the track to be random or not has not been made run the loop
{
Serial.print("Making Decision");
if(buttonState_back == LOW){//if the back button is pressed then they want to select the track them selves
randomOrNot = 1;
Serial.print("Selecting Track");
randomOrNotLoop = 1;
}else if (buttonState_forward == LOW){//if the forword button is pressed then they want to randomize
randomOrNot = 2;
Serial.print("Random Track");
randomOrNotLoop = 1;
}
}
}
void SelectingTheTrack()//the process of selecting the track that is being played //if the user needs to select the track then they will
{
if(randomOrNot == 2){//if this fuction is not needed
Serial.print("User will not select track, since randomized chosen");
}
while(randomOrNot == 1)//since user wants to select the track, go threw that process
{
if(SelectingTrackCount == 0){
SelectingTheTrackLCD();//tells instruction
delay(2000);// wait so they can read
SelectingTrackCount = 1;
}
Serial.print("User will now select track, current track is");
Serial.print(trackSelected);
TrackBeingSelectedLCD();//This shows which track is currently selected
if (buttonState_forward == LOW && trackSelected < TotalTracks){//if the forword button is pressed and the current track is less than the total number of tracks then they want the next track instead
trackSelected = trackSelected + 1;
Serial.print("Added one to the current track number");
}
if (buttonState_back == LOW && trackSelected > 1){//if the back button is pressed and the track selected is not the first track then they want the past track instead
trackSelected = trackSelected - 1;
Serial.print("Subtracted one from the current track number");
}
if(buttonState_select == LOW){//if the select button is pressed then they want the current track
randomOrNot = 3; //this will end the loop
break; //this will also end the loop
}
}
}
void SettingDistance()//This has the user go threw the process of recording the distance the Ultra sonic sensor will calabrate to
{
while(PushToRecordLoop == 0)
{
PushToRecordLCD();//Tells that you need to push select
if(buttonState_select == LOW){
PushToRecordLoop = 1;
break;
}
}
moveNowLCD();
Serial.print("One minute to get into positon");
delay(30000);//waits for 30 seconds
SecondsPassedLCD();
delay(30000);//waits for 30 seconds
Serial.print("One minute has passed");
find_distance();
recordedPositionIn = distanceIn;//set user position to be where they currently are
PositionRecordedLCD();
}
void SettingGive()
{
while(setTolorenceLoop == 0)
{
if(buttonState_forward == LOW){// if forward is pushed increase tolorence
Serial.print("Increasing");
tolorenceIn = tolorenceIn + 1;
Serial.print("Tolorence is (in inches)");
Serial.print(tolorenceIn);
}
if(buttonState_back == LOW && tolorenceIn > 1){//if back is pushed and the tolorence is not one or below decrease
Serial.print("Decreasing");
tolorenceIn = tolorenceIn - 1;
Serial.print("Tolorence is (in inches)");
Serial.print(tolorenceIn);
}
if(buttonState_select == LOW){//Select ends the loop
setTolorenceLoop = 1;
break;
}
}
recordedPositionIn_WithPositiveTolorence = recordedPositionIn + tolorenceIn;//creating the positive tolorence line
recordedPositionIn_WithNegitiveTolorence = recordedPositionIn - tolorenceIn;//creating the negative tolorence line
}
void ActiveRun()//not done
{
while(ActiveLoop == 0)
{
find_distance();//checks the users current position
if(randomOrNot == 1){//if a specific track was selected
if(recordedPositionIn_WithPositiveTolorence >= distanceIn || recordedPositionIn_WithNegitiveTolorence <= distanceIn){// if the users current position is further away or on the positive tolorence line OR if the user is colser or on the negitive tolorence line
Serial.println("User outside tolorence bounds, playing selected track");
player.play(trackSelected);
delay(1000);
Serial.println("Finished the track, now looking for position");
}
}else if(randomOrNot == 2){//else if user stated they wanted a random track
if(recordedPositionIn_WithPositiveTolorence >= distanceIn || recordedPositionIn_WithNegitiveTolorence <= distanceIn){// if the users current position is further away or on the positive tolorence line OR if the user is colser or on the negitive tolorence line
Serial.println("User outside tolorence bounds, playing randomized track");
trackRandomized = random(1,TotalTracks);//make the random number between 1 and the total number of tracks
player.play(trackRandomized);//play the random track
delay(1000);
Serial.println("Finished the track, now looking for position");
}
}
if(buttonState_select == LOW){// if select is pushed then end the loop
Serial.println("Reseting Studdy Buddy");
ActiveLoop = 1;
break;
}
}
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("Begining Studdy Buddy Void Loop");
readButtons();//read the buttons at the begining of every loop
HelloLCD();//Introduce the study buddy
howManyTracksLCD();//how many tracks are there LCD
howManyTracks();//have the user input how many tacks there are
RandomOrNotLCD();//To decide if the track played is specific or random
RandomOrNotSelect();//This is the process of selecting
DecisionLCD();//this displays the correct LCD screen depending on if the random or selection track was made
SelectingTheTrack();//if the user needs to select the track then they will
SettingDistanceLCD();//This lets the user know that we will now be going threw the steps of setting the distance
delay(3000);
SettingDistance();//This has the user go threw the process of recording the distance the Ultra sonic sensor will calabrate to
SettingGiveLCD();//This tells the user to set the tolorence of where they will be
SettingGive();//This has the user set the tolorence of where they will be
Serial.print("Activating Studdy Buddy");
ActiveLCD();//This lets the user know that the studdy buddy is active, it also tells that you need to turn off in order to reset it
delay(3000);
lcd.clear();//this is so the lcd doesnt get burned in
ActiveRun;//this either plays the selected track or it runs a randomized track
Serial.print("Ending Studdy Buddy Void Loop");
//Speeding up simulation
delay(10); // this speeds up the simulation
}