For a low power project, I need to power up the DFPlayer Mini module, let it say something, and power it down again using an Arduino Nano (w/o power regulator and LEDs). In the idle time, the Arduino will go to deep sleep. This is to be repeated regularly, e.g. on a daily basis. However, it seems I'm not able to power the module down in the right fashion. The module is connected to the Arduino via an n-channel logic-level MOSFET (IRLZ44N), such that the Player's VCC is permanently at ~5.3 V (4x1.3 V batteries), but no current can flow through the FET's drain to ground (source) if the MOSFET is not switched on via one of the Arduinos pins on its gate. I have a pull-down resistor on the gate to prevent a floating state and a 100uF capacitor from 5V to GND, otherwise turning on the MOSFET apparently causes a current spike which can reset the Arduino. The player's RX is protected by a 1k resistor as described in several tutorials. 5.3 V is not exactly within the specs of the player, but it doesn't seem to be the issue, as the following code works in the sense that the player does its job consistently fine in the first iteration of the loop but then fails every time afterwards.
#include <Arduino.h>
#include <LowPower.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
// MP3 module is powered through logic-level MOSFET
// 100uF capacitor is connected across 5V - GND to smoothen current spikes
static const int MP3Power = 2;
static const int MP3Tx = 3;
static const int MP3Rx = 4;
static const int MP3Baud = 9600; // Default hardware baud rate
uint32_t loop_count = 50000; // large loop_count: start into working loop after reset
//unsigned long loop_max;
uint32_t loop_max = 1; // 8 sec * 1 ~ 8 sec
DFRobotDFPlayerMini player;
SoftwareSerial MP3serial(MP3Rx, MP3Tx); // RX, TX
void speak(int filenumber, int volume=20);
void setup() {
// Set all pins connected to MOSFET gates as low outputs.
pinMode(MP3Power, OUTPUT); digitalWrite(MP3Power, LOW);
}
void loop() {
if (loop_count < loop_max) {
// increase loop counter, then go to deep sleep for 8 sec.
loop_count++;
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
} else {
// reset loop count, speak
loop_count = 0;
speak(1);
}
}
void speak(int filenumber, int volume) {
// turn on power for mp3 module
digitalWrite(MP3Power, HIGH);
// wait for the module to cope with being powered up
// it does light up its LED when powered up and doesn't seem to like
// to be talked to right away.
delay(1500);
// initialise mp3 serial communication
MP3serial.begin(MP3Baud);
// sometimes I added another delay here, but it didn't really change to much.
if (!player.begin(MP3serial)) {
// MP3 Player can't start -- shut down everything and return early (but gracefully?)
/*
* This is where I end up after the first time worked. I can confirm this e.g. by blinking an
* LED in here or reading the player's state, which returns a timeout error, whatever this means.
*/
MP3serial.flush();
MP3serial.end();
digitalWrite(MP3Power, LOW);
delay(100);
return ;
}
player.setTimeOut(1000);
player.EQ(DFPLAYER_EQ_POP);
player.outputDevice(DFPLAYER_DEVICE_SD);
player.volume(volume);
player.playMp3Folder(filenumber);
// enter this loop until playing is finished
while (true) {
delay(250); // give the player a little time before querying
int i = player.readState();
delay(250); // give the player a little more time, just in case
if (i != 1) {
// 1 means playing, break out when finished
break;
}
}
// close mp3 module
MP3serial.flush();
MP3serial.end();
// wait a bit?
delay(100);
// turn off power
digitalWrite(MP3Power, LOW);
// wait until everything is turned off for good
delay(100);
// I also tried this, but it didn't really change anything
//pinMode(MP3Tx,OUTPUT); digitalWrite(MP3Tx, HIGH);
//pinMode(MP3Rx,OUTPUT); digitalWrite(MP3Rx, HIGH);
}
I also managed to obtain some delay settings via trial and error such that sometimes it would play another track, but this was very unstable. As you can see, I have a lot of delays, which makes me unhappy. I suspect that the error lies somewhere within the part which powers down the DFPlayer mini module. Can someone give me a hint what I'm doing wrong?