Skip to main content

Layout sound on demand!

Here we go...all the sounds that you have collected over the years can now be heard from your railroad. In this article you will wire a sound playing module to a speaker and a Nano with 6 wires.

  Imagine a button to announce the next train ready to leave, a light sensor noticing a stock car at the loading chute making some cattle noises, wheels squealing around a curve, or on my layout, elephants and lions in the wild!

DFPlayer Mini pinout
  So, save some sounds, (or “songs” called from here on), in MP3 format, onto a micro (u) SD card using your personal computer. Reading the documentation makes it a bit confusing, from: the order matters in which you drag the files to the uSD card, to: having 100 folders with each 255 sounds and commands calling which file in a folder?!? What I did was save my sound files as 001.mp3, 002.mp3 and so forth in the root folder of the drive, and had no trouble getting them to play. Remember to properly “Eject” the card using your operating system software before removing it from the computer. Insert it into the uSD Card slot and when you power it all up, expect to hear some sounds!

  We are using the DFPlayer Mini, $8.90 from the original creators DFRobot, $9.06 at Amazon or as low as $1.52 at Ebay and $1.08 at AliExpress. With as little as power, ground and two more wires connected to the Nano, as well as the two wires to the speaker ( < 3 Watt ), you are ready to play. If you have an application where a user could press any one of 20 buttons to play 20 different “songs”, you won’t even need an Arduino, just read and build the AD KEY Mode example shown in paragraph 2 in this section online.  In this article, however, we will be using the I/O Mode, since we also want the Nano to trigger on an input, like a train passing by or a person pushing a button and then play the “songs”.  Any 8 Ohm speaker would work, just know that the amplifier on the Mini can only deliver 3 Watts and it is powered from the Nano’s regulator. Here are 10 speakers from Amazon for $9. Do know that the science of speakers making sound are still at work here and an enclosure like a baffle might still be needed to give you the best sound.  This article is not for audiophiles, you would have already installed the Kipnis Outer Limits Theatre equipment in your train room!

  First the wiring diagram: as shown in the next diagram, we will connect the speaker to the DFPlayer Mini with two wires.  Note that your speaker might have a + and/or - sign for its connections, so hook the + to the SPK_1 on the DFPlayer and the - to SPK_2. If no polarity, just connect the speaker wires to SPK_1 and SPK_2.

  Power (5Vdc) and ground from the Nano (5V and GND) to the DFPlayer (“VCC” @ pin 1 and “GND” @ pin 7 or 10 on the Mini). Searching Google will show you discussions on which GND to use on the Mini, on mine pin 7 and pin 10 are connected to each other with less than 0.01 ohms, so follow what you think is right.

Nano to DFPlayer Mini connections (thanks to fritzing)

To control the DFPlayer from the Nano, we need the orange wire from Nano pin D3 to RX and to get status from the player we want the yellow wire between the Nano pin D2 and the TX on the player.

  The bulk of the code is already done for us in a library that we can download, so install it using Sketch → Include Library → Manage Libraries. Do a search for DFPlayerMini and install the one by DFPlayer (currently version 1.0.5). Now all we need to use the code is the #include statement:
#include "DFRobotDFPlayerMini.h"

  And a player object to use:
DFRobotDFPlayerMini myDFPlayer;

  A software serial port is needed to talk to the DFPlayer Mini, and that library is included with:
#include "SoftwareSerial.h"

  The create the software serial port, since the default hardware one is already used by the communications towards the USB port, we add:
#define SWRXPIN                      2
#define SWTXPIN                      3
SoftwareSerial mySoftwareSerial( SWRXPIN, SWTXPIN );   // RX pin and TX pin to DFPlayer

  In setup() we set the baud rate to talk to the DFPlayer (9600 is the default), as well as the baud rate (I like 115,200) to give us some information into the Serial Port Monitor (Ctrl+Shift+M) with the well known Serial.println() commands.

  VERSION_STR needs to be defined as expected, so always use something you can search for with your favorite file search tool when you come back in 3 years to look for the code. Higher up in the file, add something like:
#define VERSION_STR "ML2020-01 Sound by DFPlayer Mini ver 0.001"

  From here you would like to know that the DFPlayer has a good working uSD Card inserted and maybe that there are some files on it that can be played.  There are quite a few error messages that the DFPlayer can tell when something goes wrong, but we will write code here for the “happy path” and assume all is well all the time. You should definitely invest a little more time to catch most of the possible errors before you install this under your layout. Six months later when something goes wrong, you would want to plug it into a computer’s USB port and quickly see what the problem might be. There are error messages like BUSY, SLEEPING, CHECKSUM MISMATCH, FILE INDEX OUT of BOUNDS and FILE NOT FOUND that might not show up in your first hundred hours playing with it, only when you least expect it!

  So in setup() we wait for the DFPlayer to tell us all is well, and only then do we continue to loop(), where we do some work to decide what to play. Again, the “happy path” does not take into account that you might remove the uSD Card while it is playing, so that code to check while inside loop(), would be your homework.  Maybe a function called checkIfAllIsWell() could be used by both setup() and loop() to accomplish the task.

  And now a real program. In this example, when you connect pin 4 to ground, using something like a push button switch or a BD20 track sensor, it will play all the mp3 files in the base or root folder of the uSD card, one after the other as the pin goes low every time. If there is only one file on the card, it would play it every time the pin goes low.

Upload and enjoy!

Thank you to Dr. Kamm of the Sue Line RailRoad in Shreveport for pointing us towards the DFPlayer Mini. 

  A few more notes:
  • When you turn the DFPlayer on without or with a bad uSD card, you’ll notice a very dim red LED on the player. When the card is good, the LED will be quite bright.
  • To avoid crackling noises when a song starts and/or stops, use software like Audacity to fade the sounds in at the beginning and fade out at the end.
  • It does not seem possible for the DFPlayer to tell you how much time is left in a file, so if timing is important in your application, use a stopwatch to time them and hardcode the values in the Arduino.  MP3 of WAV files can be used, sampled at as low as 8 kHz and as high as 48 kHz
  • The uSD card can be as small as 2 GB and as big as 32 GB. Formatted with FAT16 or FAT32 as needed.
  • When you try to upload the code to the Nano and it fails on first attempt, make sure that you have selected, under Tools, the correct Board, Processor and Port. If you bought an Arduino at a very low price, it is very likely that you need to select ATmega328P (Old Bootloader)” as the processor.

Popular posts from this blog

Not RRRduino, unless you have an MQTT connection via Ethernet or WiFi

JMRI code to connect to an MQTT broker, to publish and subscribe to the messages for signal masts. Of course, we agree to a standard for the MQTT topics, and since you were not here, we settled on "mast.xxxx" where xxxx is a number starting at zero. This MQTT topic is used as the User Name in a JMRI signal mast. Created as a Virtual Mast with the Aspect used as the payload in the message. And, yes, the device under the real mast needs to be programmed with the same name and code for each of the "aspect" payloads to be implemented. A yellow and red LED'd dwarf signal can not do a "Clear" aspect, so make sure "Clear" is maybe set to yellow for "Approach" as well.    Virtual Masts with agreed upon User Names. Comments are for the One Wire Signals on the NeoPixel string (see prior post)   Virtual Mast The Jython (or Python) code shown here below, is to attach a Listener to each Signal Mast, and to publish a message

Pi Pico, we smell competition in the land of the RRRduino! 

Pi Pico on an N-scale gondola Pi Pico, we smell competition in the land of the ‘duino!  Our very favorite low cost microcontroller system is seeing some fresh competition.  Everyone by now has heard about the Raspberry Pi, some fruity company in the United Kingdom, making single board computers!  They run Raspbian (or other flavors of Linux and are capable of some Windows versions) for as little money as $10 for the Pi Zero W.  The more popular Model 4, with 2 GB of RAM, retails for about $29.  Add a $5  micro SD card and you have a real computer with which you can surf the internet, write code and even program Arduinos.  It also runs our other favorite, JMRI.  Of course, plug it into a small or big screen television with an HDMI cable and you can even stream Netflix.  If you want a really cool computer built into a keyboard, also check out the brand new, Raspberry Pi 400 , you might just think you own a ZX Spectrum again. These are all “computers” with processors and now the Raspberry

Making things flash...yes LEDs!

So we have all seen the BLINK program, where we first configure the onboard LED to be an OUTPUT and then we turn the LED on, waste some time, turn the LED off and waste some time in the loop() function and then everything repeat again. So, that is really cool and 25 times faster using an Arduino, compared to 25 years ago where you had to erase the EPROM with a UV light first before you could upload the code that you tediously wrote in Assembler! And the 8051 did not have all the awesome built-in modules to simply do: Serial.begin( 300 ); // yes it was slow back then Serial.println( "Hello world" ); // and remember the extra work to do a String? // while \n and \r was needed too!!! Part I: So, back to the LED, the next question you ask is: "I have at least 17 more free pins , can they blink too?", and the answer is "Sure!". But in the current digitalWrite( 13, HIGH ); delay( 500 ); digitalWrite( 1