10 Second Story/ Music Box - Original

by NeilBuilds in Circuits > Assistive Tech

291 Views, 4 Favorites, 0 Comments

10 Second Story/ Music Box - Original

As a story box.jpg

I regularly work with a local school for children with complex or additional needs. This project came out of a conversation with some of the school teachers about allowing students to interact with their environment through the use of a standard 3.5mm button. This enabled the higher functioning students to have an impact on their surroundings in a positive way and can be used to allow them to progress through a story at their own pace (as shown) or to play music at a pace that suits them but requires continued interaction. Through discussion with the teachers - 10 seconds was discussed as a reasonable length of time for audio to be played.

This is the original flavour of the music box and the use of a micro SD card allows for user read stories to be recorded in MP3 format and played back or for MP3 files to be transferred to the card. The DFPlayer Mini allows for multiple audio file formats but this worked well for me. The tactile toggle switch on this system provides a way of silencing the speaker if the student prefers headphones only.

A friend suggested making one of these and recording him reading stories to his as yet unborn grandchildren but I don't know what the memory life of the SD card would be. Perhaps something to consider.

I have created multiple 'remixes' of this project which I shall add over the coming weeks, to date these include:

Automatic speaker disconnection when headphones are added and a third version with on box volume control buttons.

Supplies

IMG_20230307_192454373.jpg
IMG_20230307_192445335.jpg
IMG_20230322_171320251_HDR.jpg
IMG_20230307_192244821.jpg
IMG_20230307_192131261.jpg
dfplayer-a-mini-mp3-player-dfrobot-dfr0299-36251812200643_800x.jpg
IMG_20230307_193403422.jpg
IMG_20230307_192005353.jpg
IMG_20230307_192723956.jpg
IMG_20230307_192613401.jpg

Plastic industrial box (121 x 87 x 192mm) - https://www.screwfix.com/p/schneider-electric-ip66-weatherproof-outdoor-enclosure-121-x-87-x-192mm/355hv - these are generic industrial electrical enclosures.

5V Power bank - Amazon link - chosen as these are on special offer, but any 5V USB powerbank will do.

Arduino controllers - Nano - https://uk.rs-online.com/web/p/arduino/1927590

Arduino controllers - Nano - AliExpress link - generic (cheaper and came with a shield to reduce soldering shown here, I also got the cable here too as the ones supplied are data capable)

Dfplayer mini MP3 codec, amp & SD card mount - Pi Hut link

4 Ohm 3W Speakers - Pi Hut link

3x 3.5mm mono ports - Bitsbox link

Micro SD card (or SD card of choice) - Amazon link - 4Gb selected but anything up to 32Gb should be acceptable.

Toggle switch (optional) - Bitsbox link - I added this between the speaker connections to effectively switch off the speaker when not required

Signal wire - as you see fit (I used multiple lengths about 10cm long here which seemed to fit in well) I've used white here but feel free to use whatever colour you prefer - here

Male to female jumper wires - Bitsbox link - these are always useful when building something so you can test as you go.

1x 1k Ohm resistor

1x 47 Ohm resistor


Tools to build this:

Good soldering iron starter kit - available here

or a more advanced soldering station with holder that I'm using here

Lead free solder (smaller packs are available) here

Drill - here

6mm drill bit - here

12mm drill bit - here for the speaker on/ off switch.

Wire strippers (I use these as they take the work out of wire sizing) - here

Wire cutters - here

Hot glue gun - Amazon link

Flat head screw driver - hardware shop of choice

Pencil/ permanent marker - makers choice


The Amazon links which I have set here I receive a commission on here which I use to continue developing and making assistive technology items. Alternative shops for all of these parts/ tools do exist.

Mark & Drill Holes in the Box

IMG_20230308_220757810.jpg
IMG_20230308_220750164.jpg
IMG_20230308_220806502.jpg
IMG_20230308_223407041.jpg
IMG_20230308_223341514.jpg
IMG_20230308_223355833.jpg

First of all I marked out the hole positions for the USB lead and headphone socket on the left side and for the two 3.5mm sockets on the right side. As this version includes the speaker switch - I marked the position there on the front along with 6 speaker holes to let the sound out.

Using a 6mm drill bit - I drilled these holes out with a piece of scrap wood behind the hole, this allowed me to put some pressure onto the box without risking damaging it. I then removed any cutting debris from the inside of the hole. To make fitting the 3.5mm sockets easier I did add a small countersink on the inside of the box. This gave me more room to fit the nut on the outside of the 3.5 socket.

For the speaker on/ off switch hole I drilled it first with the 6mm bit then opened it out to 12mm diameter.

For the USB hole on the left - I measured the smallest end of the connector and expanded the hole so I could fit the smallest end of the USB cable using a small file but you can use the wire cutters if more material needs to be removed.

Prepare the Electronic Connections

IMG_20230501_095820914_HDR.jpg
IMG_20230307_192310140.jpg
IMG_20230307_192401575.jpg
IMG_20230307_193427126.jpg
IMG_20230307_193449084.jpg
IMG_20230307_191952053.jpg
IMG_20230308_215619158.jpg
IMG_20230308_230212275.jpg
IMG_20230308_230237367_HDR.jpg
IMG_20230308_231500668_HDR.jpg

Everything in this box fits from the inside out so as long as you leave yourself enough wire (I found about 10 cm was plenty) you'll be fine. It also means you can connect everything on a bench first before fitting into the box.

The wiring diagram shown can be completed with wires soldered in place however I used male to female jumper wires between the Dfplayer mini mp3 card and the screw shield to limit the amount of soldering necessary.

Eager to get going I mounted the Arduino Nano into the screw shield. That satisfying feeling of getting something done so quickly.

I prepared the speakers by removing the connector from the end - we are only going to be using one speaker so stereo is not needed. Then I stripped 3mm off the positive and negative wires from one of the speakers and tinned the ends with solder.

For the 3.5mm switch jacks I checked with a continuity meter which connections would be closed when the button was pressed (normally open) and soldered around 15cm of signal wire onto the two tabs. I used a permanent marker to make one of the wires a 'negative'.

For the 3.5mm headphone jack I checked with a continuity meter which connections would be permanently on with or without a headphone plugged in and soldered around 15cm of signal wire onto the two tabs as above.

I then soldered a 1k Ohm resistor to the male end of a jumper cable and soldered a 47 Ohm resistor to a 10cm length of signal wire.

Now I added the jumper wires as shown to the Dfplayer mini card as shown on the diagram. You know you're doing it right when all of the jumper wires are on the same side - if not, take a look at the wiring diagram again.

At this point we can start connecting the wires to the correct points to test what we've done (final photo)

Box Build

FF0YSXFM1W61OGK.jpg
DF Player mini pin outs.png
IMG_20230312_111016498_HDR.jpg
IMG_20230312_112502598.jpg
IMG_20230312_105708921_HDR.jpg
IMG_20230312_112834428.jpg
IMG_20230322_171318024_HDR.jpg

A reminder of the wiring diagram.

The connections are:

Arduino Pin D3 - 1K Ohm resistor jumper to Rx on DFPlayer Mini

Arduino Pin D4 - jumper wire to Tx on DFPlayer Mini

Arduino Pin D6 - to one side of a 3.5mm switch jack - this will become the 'Next track' button.

Arduino Pin D8 - to one side of a 3.5mm switch jack - this will become the 'Play' button.

Arduino Pin D10 - 47 Ohm resistor wire to ground - this is needed to keep most battery banks active due to the low power draw.

The 5V connection on the Arduino to VCC on DFPlayer Mini

The grounds from the DFPlayer Mini and the two switch buttons need to be combined and fed into the Arduino ground. I combined them away from other connections and used some heatshrink to cover the connection to ensure it didn't contact anything else.

The speaker connections are wired from the DFPlayer through the headphone 3.5mm jack so this is always active, with the speaker negative passing through the toggle switch on the front.

At this point - I fitted the electrical parts into the box to get the positions correct (photo shows the speaker off to the top right). Once you're happy with this you can set this in place with some hot glue. I found that the DFPlayer Mini was best placed so you can push onto the SD card from the top with the speaker glued to the side opposite the speaker holes.

I then used pliers to ensure all external nut fittings were snug tight.

Lastly I glued the powerbank to the free side making sure the USB cable would reach between it and the Arduino before filling the last of the hole with hot glue to prevent debris from getting inside.

The Code

IMG_20230501_095646927.jpg

I have placed the code below and as a file. You'll need the latest DFPlayer library available here.

It's worth playing with the initial speaker volume to get that right. Once you've uploaded the code and some music or audio content to the SD card, you're ready to give it a go with switches through the 3.5mm jack.

For a low cost 3.5mm connected switch build - please see one of my other projects here.

As the USB A connection for the power bank is data capable - any changes you need to make to the volume, timing etc can be done wiithout having to open the box.


// MkIII music box version 8 code
// Credit to https://www.hackster.io/circuiTician/i-made-an-arduino-based-music-player-using-dfplayer-mini-c3c7c9
// For the code tips and the concepts. Transmission through Rx and Tx modified accordingly
// Additional code by Neil Williamson from discussions with Tim King for ideas and concepts and generally
// putting up with me during the idea generation process. To my daughter Eva - in all likelihood you'll
// never see this. Despite all I have achieved in this world, you are my greatest gift. My only hope is that you
// grow into the person you deserve to be and are happy with your efforts. Love dad.

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"
SoftwareSerial mySoftwareSerial(4, 3); // RX, TX
DFRobotDFPlayerMini myDFPlayer;
void printDetail(uint8_t type, int value);
#define pp 8
#define vu 9
#define vd 5
#define nxt 6
#define prv 7


//Set start volume for speaker from 10 to 30 - 10 is OK for room use, 20 is loud!
int v= 20, pv=0;

// Setting up a pulse to keep the battery bank powered up.

// this constant won't change. It's the pin number of the 47 Ohm resistor:
const int PulsePin = 10; // the number of the Pulse output
// PulseState used to set the pulse
int PulseState = LOW;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time Pulse was updated
// constants won't change:
const long interval = 1000; // interval at which to send pulse (milliseconds)

void setup()
{
mySoftwareSerial.begin(9600);
Serial.begin(115200);
pinMode(pp,INPUT_PULLUP);
pinMode(nxt,INPUT_PULLUP);
pinMode(prv,INPUT_PULLUP);
pinMode(vu,INPUT_PULLUP);
pinMode(vd,INPUT_PULLUP);

// set the digital pin as output:
pinMode(PulsePin, OUTPUT);
Serial.println();
Serial.println(F("DFRobot DFPlayer Mini Demo"));
Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));
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!"));
// Note: For some reason the program hangs when installed on generic Nano's so trying commenting out this code
// while(true){
// delay(0); // Code to compatible with ESP8266 watch dog.
// }
}
Serial.println(F("DFPlayer Mini online."));
myDFPlayer.volume(v); //Sets volume value. From 0 to 30
//myDFPlayer.play(1); //Play the first mp3
}
void loop()
{
Serial.println(pv);

// Pulse to sustain power bank output through PulsePin
// check to see if it's time to pulse; that is, if the difference
// between the current time and last time the pulse was made is bigger than
// the interval at which you want to send the pulse.
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {
// save the last time the pulse was sent
previousMillis = currentMillis;

// if the pulse is off turn it on and vice-versa:
if (PulseState == LOW) {
PulseState = HIGH;
} else {
PulseState = LOW;
}
// set the pulse with the PulseState of the variable:
digitalWrite(PulsePin, PulseState);
}
//This is the element that can be edited to add play for x time then pause
if(digitalRead(pp)==0){
if(pv == 0){
myDFPlayer.start();
delay(10000);
myDFPlayer.pause();
pv=1;
}
else if(pv == 1){
myDFPlayer.pause();
pv=0;
}
}
//If pause code not added, next track will play but not pause.
if(digitalRead(nxt)==0){
myDFPlayer.next();
delay(2000);
myDFPlayer.pause();
}
if(digitalRead(prv)==0){
myDFPlayer.previous();
}
if(digitalRead(vu)==0 && v<30){
v=v+1;
myDFPlayer.volume(v);
}
if(digitalRead(vd)==0 && v>0){
v=v-1;
myDFPlayer.volume(v);
}
delay(100);
if (myDFPlayer.available()) {
printDetail(myDFPlayer.readType(), myDFPlayer.read()); //Print the detail message from DFPlayer to handle different errors and states.
}
}
void printDetail(uint8_t type, int value){
switch (type) {
case TimeOut:
Serial.println(F("Time Out!"));
break;
case WrongStack:
Serial.println(F("Stack Wrong!"));
break;
case DFPlayerCardInserted:
Serial.println(F("Card Inserted!"));
break;
case DFPlayerCardRemoved:
Serial.println(F("Card Removed!"));
break;
case DFPlayerCardOnline:
Serial.println(F("Card Online!"));
break;
case DFPlayerUSBInserted:
Serial.println("USB Inserted!");
break;
case DFPlayerUSBRemoved:
Serial.println("USB Removed!");
break;
case DFPlayerPlayFinished:
Serial.print(F("Number:"));
Serial.print(value);
Serial.println(F(" Play Finished!"));
break;
case DFPlayerError:
Serial.print(F("DFPlayerError:"));
switch (value) {
case Busy:
Serial.println(F("Card not found"));
break;
case Sleeping:
Serial.println(F("Bored now - sleeping"));
break;
case SerialWrongStack:
Serial.println(F("Get Wrong Stack"));
break;
case CheckSumNotMatch:
Serial.println(F("Check Sum Not Match"));
break;
case FileIndexOut:
Serial.println(F("File Index Out of Bound"));
break;
case FileMismatch:
Serial.println(F("Cannot Find File"));
break;
case Advertise:
Serial.println(F("In Advertise"));
break;
default:
break;
}
break;
default:
break;
}
}

Various Labels

IMG_20230430_200647311.jpg
IMG_20230322_171303626.jpg
IMG_20230322_171325210_HDR.jpg
IMG_20230322_171308221.jpg
IMG_20230322_171312202.jpg

As this is a project for use in schools I added too many labels. These were printed on a generic label printer and once the box was in use - the need for them was reduced as shown on the main project photo.


Now get reading stories and adding them to music boxes.