Close

Phew-Phew (2)

A project log for AT-AT or 'All Terrain Armored Transport'

Creating a model of this iconic 'vehicle'. With some animation. ( no, it won't walk)

cees-meijerCees Meijer 08/27/2023 at 20:230 Comments

After my unsuccesful attempt to get some nice sound effects using just the Arduino, I decided to buy some DFPlayer MP3 modules. A little to my surprise these are both very cheap ( around 1 USD at AliExpress) and they support direct output to a speaker so I won't need an additional amplifier ( though that's equally cheap, it just saves some wiring). A disadvantage is that you also need a MicroSD card, which is much more expensive than the module. Of course the smallest available card will do, so you could just use a leftover 1 or 2 GB, if you can find one.

There is a nice description on how to connect and use the module on the DFRobot site.

Wiring just could not be easier...

And so is the coding. After initializing the serial port and the DFPlayer as shown in the example, these few lines trigger the playing:

void loop() {
  
      myDFPlayer.play(1);  //Play the first mp3
      Serial.println(F("Phew Phew"));

// Read and Print the detail message from DFPlayer to handle different errors and states.
      if (myDFPlayer.available()) {
       printDetail(myDFPlayer.readType(), myDFPlayer.read()); }
      randomDelay = random(2000,8000);
      delay(randomDelay);
}

 At first I left out the line for reading the return message from the player module. But then the loop just ran once, and stopped. So to find out what was going wrong I did include the line, only to find that this actually solves the problem.

While testing and running this program for a while, I soon found out that the repetitive 'Phew Phew' sound gets annoying, even with a random interval. So there has to be a simple way to enable or disable it. Therefore I added a capacitve touch-switch ( A TP223 ) that would trigger the sound and light.


By mounting the switch on the inside of the body I should be able to trigger it by simply touching it in the right spot.

The complet schematic:


Note that no series resistors were added for the LEDs. This will cause them to flash at their maximum. And since the duty cycle is very low ( they are only on for 100 mS) they do not get a chance to burn out.


The speaker is on the left. It's one that came from an old laptop, which was equipped with a 'Harman Kardon Sound system'. This AT-AT will be HiFi !

The sound file contains two 'blasts', with approximately 200 mS interval. So in the software I start the MP3, flash the first LED, wait 200 mS and flash the second LED. This works really nice and produces a realistic dual-cannon blast.

Here is the final Code:

/* AT AT

*/

#include "DFRobotDFPlayerMini.h"
#include <SoftwareSerial.h>
#define rxPin 4
#define txPin 5
#define triggerPin 6

#define FPSerial softSerial

DFRobotDFPlayerMini myDFPlayer;
long randomDelay;
void printDetail(uint8_t type, int value);

void setup() {
SoftwareSerial softSerial(rxPin, txPin);

    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);
    pinMode(triggerPin, INPUT);

    FPSerial.begin(9600);
  Serial.begin(9600);

  Serial.println();
  Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));

  if (!myDFPlayer.begin(FPSerial, /*isACK = */true, /*doReset = */true)) {  //Use serial 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!"));
    while(true){
      delay(0); // Code to compatible with ESP8266 watch dog.
    }
  }
  Serial.println(F("DFPlayer Mini online."));

  myDFPlayer.volume(10);  //Set volume value. From 0 to 30
}

void loop() {
  if( digitalRead(triggerPin)==HIGH)
  {
      myDFPlayer.play(2);  //Play the first mp3
      Serial.println(F("Phew Phew"));
      if (myDFPlayer.available()) {
       printDetail(myDFPlayer.readType(), myDFPlayer.read()); }//Print the detail message from DFPlayer to handle different errors and states.
      digitalWrite(2,HIGH);
      delay(100);
      digitalWrite(2,LOW);
       delay(200);
      digitalWrite(3,HIGH);
      delay(100);
      digitalWrite(3,LOW);
      randomDelay = random(2000,8000);
      delay(randomDelay);
       
  }

}
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("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;
  }
}

Discussions