This kind of system already exists even with DIY solutions :

So I decided to build mine with the following features :

And to get a good sound level and quality :

Audio Exciters are loudspeaker components that lack the frame and cone of traditional speakers and function by vibrating a rigid surface to create sound. Instead of mounting them with screws, they're adhered to whatever surface is intended to function as the speaker. In our use case it will be glued on the plane frame inside the cockpit.

All this should cost as cheap as possible (around 30/40 €)

Here is a small video of the system during tests on my desktop :


And a second one with the system fully hidden into the plane.

A software modification was made in order to synchronize the start and stop sounds with the propeller motion.

Result is more realistic. More details into this log


Electronics

Most of the electronics should be based on already available modules:


DFPlayer mini

This small module was originally designed by DFRobot

This player supports an microSD card on which can be stored mp3 or Wav files

This chip has a 3.3V ttl logic but its VCC can be between 3.3V and 6V max. A good value is 4.8V. We cannot power this module via the 3.3V of the ESP32 as its voltage regulator would be too weak... So an external power supply is mandatory

DFPlayer can be directly connected to an ESP32 using serial port. And its 3W built in amplifier (Speaker pins) can directly feed a small loudspeaker (less than 3W).

Unfortunately this amplifier is only a 3W model.. So we can add an external amplifier an connect it to the DACs output of the Player.

For my application I will only use a mono amplifier so only connect the amplifier to one of the DACs (DAC_left see schematics below).


Schematics

Here is how to connect the modules.

From left to right :


PCB

This schematics was easily routed on a dual sided PCB board.

The PCB was kindly sponsored by PCBWay and is as usual of excellent quality.

You can order it here : PCBWay shared project. It's cheap, delivered very fast and so professional looking!

and if you are new to PCBWay please use this affiliated link : https://pcbway.com/g/o35z4O

This board allows a "mezzanine mount" of all the components, so that the final product enters into a 5x5x2 cm box.

Soldering is fairly easy but you should follow this procedure:

As you can see the DFPlayer goes exactly between the ESP32 pin headers

Now you can turn the board and solder the amplifier.

position and solder male pin headers:

Now insert the amplifier and solder it in place.

you can also add the 5V power cable for the ESP32 (bottom of the picture).

But do NOT yet insert the white plug into the ESP32 connector (unlike I did on the picture)

And we need now to power the board...


Power considerations

5V can be delivered either by the DC/DC converter (prefered solution) or directly by the ESC of your plane


power with DC/DC converter


Power with the ESC :

If your ESC is equiped with a strong enough BEC you can power the DFPlayer and the ESP32 directly with the throttle connector :

I recommend the first option (DCDC step down converter) as the ESP32 can eat up to 700MAh (max) and the DFPlayer 200 mAh with integrated 3W amplifier or 50mA with the DAC... Don't forget that classicaly the ESC is also supposed to power the servos of your plane... It's better to avoid to stress more the ESC...

When these components are installed you can solder the audio amplifier on the bottom side of the PCB. Alternatively if 3W power is enough for you the Speakers outputs of the DF Player could be used


Powering the audio amplifier

The XH-M313 TPA3118 60W is an audio amplifier that can be powered up to 24V. As we will fly an electrical RC plane we will for sure power it with a lipo battery from 2s to 6s 

A 6s battery will output (when fully charged) 6 x 4.23V = 25.38V which is above the max voltage of our amplifier.

So we will power the amplifier with a maximum 5s battery (5 x 4.23 = 21.15V). If we use a 6s battery for our plane we can pick up the 5s value into the balancer connector of the battery. This will slightly un balance our lipo (5s 1A current (drained for the amplifier) while 6s 40A current will be drained to power the plane motor). This is negligible and will be corrected by the balance charge for next flight !

However depending on the loudspeaker that you will choose, an even smaller voltage could be recommended to avoid burning the speaker coil... 12 to 16V seems to be loud enough !


Software

Software of our system should be very simple as we want to implement this simplified state machine :

Basically we need the following features:

Reading the receiver channels

I found an excellent library to decode PWM Rx channels with embedded RMT hardware of the ESP32. 

Using this library is fantastically simple :

Declare the channels (pins) you want to decode

//Rx servo reader library : https :  //github.com/rewegit/esp32-rmt-pwm-reader
#include <esp32-rmt-pwm-reader.h>
// #include "esp32-rmt-pwm-reader.h" // if the lib is located directly in the project directory

// init channels and pins
uint8_t pins[] = { 32, 33, 25 };  // desired input pins
int numberOfChannels = sizeof(pins) / sizeof(uint8_t);

Then read a channel at a time

// Reading the actual pulse width of Throttle channel
  speedIndex = constrain((pwm_get_rawPwm(0) - 1000), 0, 1000);  //clip throttle value between 0 and 5
  speedIndex = map(speedIndex, 0, 1000, 0, 5);

Here the throttle channel. As you can see the output of the library is a standard pulse duration between 1ms to 2ms with a center position at 1.5ms

I remap this value between 0 and 5 so that I can play 5 sounds depending on the throttle stick position. Simple!

Having read these Rx channels, it's now simple to code the state machine:

// Do something with the pulse width... throttle and gun

  switch (status) {  //handle motor and gun
    case statusIdle:
      startTime = millis();
      if (speedIndex > 0) {
        status = statusStarting;
        volume(volIndex);
        currentSpeedIndex = -1;  //will force exit from startmotor playing
        PlaySound(0x00, 0);      //PlaySound(motor_start)/Play the 1.mp3 (motor start)
        Serial.println("starting");
      }
      break;
    case statusStarting:
      if (((millis() - startTime) > startDuration) || (startPlayed == true)) { // wait for the startPayed event of the startmotor track (or failsafe time out)
        status = statusRunning;
        PlaySound(0x00, 1);  //PlaySound(1_mot.wav) now go to the 001 rpm sound
        PlaySoundLoop();
        Serial.println("running");
      }
      break;
    case statusRunning:
      stopTime = millis();
      if ((speedIndex != currentSpeedIndex) || (shoot != previousShoot)) {
        currentSpeedIndex = speedIndex;
        previousShoot = shoot;
        if (speedIndex == 0) {  // change status to stop motor
          status = statusStopping;
        } else {
          PlaySound(shoot, speedIndex);  //Play the speedIndex.wav (motor run (+ gun if shoot)) and loop
          PlaySoundLoop();
        }
      }
      break;
    case statusStopping:
      if (speedIndex == 0) {
        if ((millis() - stopTime) > 100) {
          PlaySound(0x00, 6);  //Play the 06_motorStop.wav (motor stop) and do not loop
          Serial.println("stopping");
          status = statusIdle;
        }
      } else status = statusRunning;
      break;
    default:
      // statements
      break;
  }

Well it should have been simple if the DFPlayer was working as expected !


Interfacing the DFPlayer with ESP32

My first idea was to use the DFRobotDFPlayerMini Arduino library. But I quite soon discovered that my DFPlayer was not a genuine one and with this library... I got the bad error mesage at startup :

Unable to begin:
1.Please recheck the connection!
2.Please insert the SD card!

I finally got the DFPlayer working and I wrote my own code as the protocol was quite simple and as I didn't need all the commands...

Sound files naming rules

DFPlayer has quite strict naming rules for sound files and folders.

You can add files into folders with names "XX" where XX are numbers 0 to 9.

I created two folders "00" and "01" containing respectively the "normal" and the "machine gun" files

And files into the folders must start with a 3 digits code. But files names can be appended with text to ease understanding the sd card content

With these naming conventions the DFplayer alllows commands such as :

PlaySound(folderNum, fileNum)

I also coded two useful functions 

Finally I coded a way to detect end of song (return code 0x3D)

 switch (receive_frame.CMD) {
        case 0x3A:
          Serial.println("card inserted");
          break;
        case 0x3B:
          Serial.println("card ejected");
          break;
        case 0x3D:
          {
            Serial.println("card playing finished");
            if (status == statusStarting) startPlayed = true;
            else startPlayed = false;
          }
          break;

And that's it. The DFPlayer was working and my project almost finished!

The full code is available into my Github pages


Preparing the sound files

Sound files should be into Wav format. This format is uncompressed so eats much more room on your SD card... but is fast to decode (no decoding) so easier to read for the DF Player. Thus there is almost no sound gap when changing track neither any audible nasty click

I use 16bits PCM monophonic Wav format which is compact enough and still with a good quality.

You will find planes sounds files on this site : https://simviation.com/1/browse-Flight+Simulator+Sounds-112-0

Or you can unzip the sounds Pack that I have created.

If you want to change the sounds pack the procedure to create your own sounds is quite easy.

You will have to install Audacity software

Then open any track you want (here is an example with a stereo machine gun sound)

First step will be to transform this stereo file into a mono one:

now you can trim the start and end to only keep the gun sound (select and cut)

you can now copy and paste the full track to repeat the sound effect :

And finally export the full track:

You can also mix the motor sound with the gun effect:

open both tracks, trim them so that they start and stop at the right same moment.

Then mix them (mix and render menu)

And export the result as a mono Wav file.

Now that you know how to mix sounds you can easily create your own mix including Stuka siren sound. Have a look at this log to understand what I mean


choosing the right Exciter and integration into the plane

An RC plane has a very important design constraint : WEIGHT

So adding this sound machine must take this constraint into consideration.  We would like to add the most powerful loudspeaker... But we shouldn't if it is heavy. 

So we have searched for a good balance point between weight and power.

We found this tiny yet powerful Dayton Audio Exciter : DAEX25CT

It weights 75g, it's small enough to fit into the fuselage and still has 10W RMS power.

Our amplifier is said to go to 60W... Too much for this exciter ? Well no if we power the amplifier with 12 to 16V instead of 23V (max).

So a 3s lipo battery would be perfect. We could even jump to 4s depending on our motor specifications !

And with 3s or 4s we can directly pick the juice on all the cells of the battery without any risk of unbalancing the cells. (see power considerations above).