I'm working on a Halloween skull prop for out haunted barn we are use each year for dollars for scholars. At the moment I have a basic working setup using "jawdrino" shared by buttonbanger,com. The jaw moves every smooth however a laptop was used to demo this capability. Thank you! if you listening, It works great using my PC.
Im trying to adapt this setup to include use of a DF Player Mini which would play ~10 different scary talk tracks automatically selecting the next .mp3 file or a random one. Unfortunately I only believe I know the following about whats needed in the sketch:
1.Most likely I will need range of .mp3 selections (say 10)using a stepping or random number generator and the ability to take this number apply it so the next song is selected and played.
Additionally I expect that there should be a monitor to ensure the selection playing has completed before starting the next.
Yes I'm still a newbe and I have seen some parts of this online but not yet able to put anything worth sharing here. Apologies if this has already been done and I missed it.
Im working with an UNOv3 and DF Player Mini. So far I have managed to get the DF Player Mini to work with the basic jawdrino sketch but have to push a button to play the next selection.
I can probably figure this out but need some help with the framework to get it started correctly.
Below is the link to see the jawdrino setup:
Anas Kuzechie has done intricate (AND understandable) work with DFPlayerMini and MP3 player on his YouTube channel (he has two channels, one technical, one personal).
Thank both of you for your replies.
I did watch this well done video and in the end all I really need right now is a way to enable "play next" (pin9 on the player) from the Adrino without depressing a switch.
Today I looked over the details for the DF Mini (DFPlayer Mini Mp3 Player - DFRobot Wiki) and discovered there is an example file at the end that may get this working. Ill play around with this a bit more and update this later. Attached is a copy of the basic hardware setup currently in test
Hello @dnfriedl67 - Some suggest using DFPlayerMiniFast for solving a "play the next track" problem using isPlaying() to wait for the present track to finish before starting the next. The link shows the API functions available.
Thanks again for everyone's help.
This project is now basically working as intended. At the moment all 10 of my test .mp3 files play correctly and the servo responds as expected. Apologies i read over the 'is playing" information and not sure what instructions I need to include. The newbe in me is not picking this up.
Below is a copy of the Sketch I created using different sources hopefully giving credit to those that originally created the initial structures and adding my comments.
/***********************************************************
08-14-2016 Mike North This is a little proof of concept
to make a servo move in sync with audio.
http://buttonbanger.com/?page_id=137
04-23-2023 DFriedl Incorporate DFRobot DFPlayer - A Mini MP3 Player For Arduino
https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299#Connection_Diagram
Overall intent is a prop to play .mp3 files while moving a skull jaw
*******************/
#include "SoftRcPulseOut.h"
#include "SoftwareSerial.h"//from MP3mini
#include "DFRobotDFPlayerMini.h" //from MP3mini
#define TEST_PIN 5 //pin 5 set to ground will kick off the servo sweep test
int audio_value = 0;
long lastMsg = 0;
long sleepWindow = 300000; //if 5 minutes go by with no signal, then put the servos to bed
SoftRcPulseOut servo;
volatile boolean servosEnabled = false;
volatile boolean ledsOn = true;
volatile unsigned long currentTime = 0;
volatile unsigned long lastLEDtime = 0;
unsigned long resetWait = 120000; //servos sleep if not changed within this time frame (120 secs)
int SPin3=A2;
int SVal3;
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX //from MP3mini
DFRobotDFPlayerMini myDFPlayer; //from MP3mini
void setup()
{
mySoftwareSerial.begin(9600);
if (!myDFPlayer.begin(mySoftwareSerial)) {while(true); //Use softwareSerial to communicate with mp3
}
set_minmax();
pinMode(TEST_PIN,INPUT); //pin 5 will be
digitalWrite(TEST_PIN,HIGH); //assign pull-up resistor
myDFPlayer.volume(20); //Set volume value. From 0 to 30 //from MP3mini
myDFPlayer.play(1); //Play the first mp3 //from MP3mini
Serial.begin (9600);
}
void loop()
{
///////////////////////////////////////////////////////////////////
//replace this timed play to one that waits for track to complete and advances to next
//also add 5sec delay before playing next track
//how to do this?
static unsigned long timer = millis(); //from MP3mini
if (millis() - timer > 10000) //from MP3mini
{
timer = millis(); //from MP3mini
myDFPlayer.next(); //Play next mp3 every 10 seconds. //from MP3mini
}
//////////////////////////////////////////////////////////////////////
SVal3=analogRead (SPin3);
Serial.println(SVal3);
servo_test();
audio_updates(); //read sample from audio input and apply average to buffer
if(servosEnabled)
{
action(); //servos are handled in the action loop
SoftRcPulseOut::refresh();
if((millis() - lastMsg) > sleepWindow)
detach_servos();
}
}
void attach_servos()
{ // attach the pin to the servo object
servo.attach(2);
servosEnabled = true;
}
void detach_servos()
{ // detach the servo objects
servo.detach();
servosEnabled = false;
}
void servo_test()
{
if(digitalRead(TEST_PIN) == HIGH) return;
attach_servos();
SoftRcPulseOut::refresh();
for(int i = 0; i < 360;i++)
{
if(i < 180)
audio_value = i;
else
audio_value = 359 - i;
action();
for(int i = 0; i < 10; i++)
{
delay(1);
SoftRcPulseOut::refresh();
}
}
detach_servos();
}
void audio_updates()
{
audio_value = 0;
if(analogRead(A0) < 341) audio_value += 60;
if(analogRead(A1) < 341) audio_value += 60;
if(analogRead(A2) < 341) audio_value += 60;
if(audio_value > 0)
{
lastMsg = millis(); //save the time stamp from when we last had some action
if(!servosEnabled)attach_servos();
}
}
void action() {
if (!servosEnabled) attach_servos();
servo.write(audio_value);
SoftRcPulseOut::refresh();
}
void set_minmax()
{
//set the first parameter in the following functions to a number between 0 and 180.
//I used 92 and 72 in my tests to give about 20 degrees of motion.
//You may swap the large and small numbers to reverse direction.
//Just play with them, upload the code, then ground pin 11 to run the sweep test.
// Be sure to only play with these numbers while the jaw linkage is disconnected,
// otherwise, you risk hitting mechanical limits and damaging your linkage or servo!
servo.setMinimumPulse(map(92,0,180,512,2400));
servo.setMaximumPulse(map(72,0,180,512,2400));
}