1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-27 01:56:14 +01:00

DFPlayer: allow volume to be set in play command.

This commit is contained in:
Neil McKechnie 2021-09-17 12:31:28 +01:00
parent ad7cd5f401
commit fa650673eb
2 changed files with 114 additions and 51 deletions

View File

@ -27,17 +27,19 @@
* The driver is configured as follows: * The driver is configured as follows:
* *
* DFPlayer::create(firstVpin, nPins, Serialn); * DFPlayer::create(firstVpin, nPins, Serialn);
*
* Where firstVpin is the first vpin reserved for reading the device, * Where firstVpin is the first vpin reserved for reading the device,
* nPins is the number of pins to be allocated (max 5) * nPins is the number of pins to be allocated (max 5)
* and Serialn is the name of the Serial port connected to the DFPlayer (e.g. Serial2). * and Serialn is the name of the Serial port connected to the DFPlayer (e.g. Serial1).
*
* *
* Example: * Example:
* In mySetup function within mySetup.cpp: * In mySetup function within mySetup.cpp:
* DFPlayer::create(3500, 5, Serial2); * DFPlayer::create(3500, 5, Serial1);
* Writing a value 0-2999 to the first pin will select a numbered file from the SD card; *
* Writing a value 0-30 to the second pin will set the volume of the output; * Writing an analogue value 0-2999 to the first pin will select a numbered file from the SD card;
* Writing an analogue value 0-30 to the second pin will set the volume of the output;
* Writing a digital value to the first pin will play or stop the file; * Writing a digital value to the first pin will play or stop the file;
* Reading a digital value from any pin will return true(1) if the player is playing, false(0) otherwise.
* *
* From EX-RAIL, the following commands may be used: * From EX-RAIL, the following commands may be used:
* SET(3500) -- starts playing the first file on the SD card * SET(3500) -- starts playing the first file on the SD card
@ -45,6 +47,9 @@
* etc. * etc.
* RESET(3500) -- stops all playing on the player * RESET(3500) -- stops all playing on the player
* WAITFOR(3500) -- wait for the file currently being played by the player to complete * WAITFOR(3500) -- wait for the file currently being played by the player to complete
* SERVO(3500,23,0) -- plays file 23 at current volume
* SERVO(3500,23,30) -- plays file 23 at volume 30 (maximum)
* SERVO(3501,20,0) -- Sets the volume to 20
* *
* NB The DFPlayer's serial lines are not 5V safe, so connecting the Arduino TX directly * NB The DFPlayer's serial lines are not 5V safe, so connecting the Arduino TX directly
* to the DFPlayer's RX terminal will cause lots of noise over the speaker, or worse. * to the DFPlayer's RX terminal will cause lots of noise over the speaker, or worse.
@ -123,29 +128,37 @@ protected:
} }
// WriteAnalogue on first pin uses the nominated value as a file number to start playing, if file number > 0. // WriteAnalogue on first pin uses the nominated value as a file number to start playing, if file number > 0.
// If value is zero, it stops playing. // Volume may be specified as second parameter to writeAnalogue.
// If value is zero, the player stops playing.
// WriteAnalogue on second pin sets the output volume. // WriteAnalogue on second pin sets the output volume.
void _writeAnalogue(VPIN vpin, int value, uint8_t, uint16_t) override { void _writeAnalogue(VPIN vpin, int value, uint8_t volume=0, uint16_t=0) override {
uint8_t pin = vpin - _firstVpin; uint8_t pin = vpin - _firstVpin;
switch (pin) {
case 0: // Validate parameter.
volume = min(30,volume);
if (pin == 0) {
// Play track
if (value > 0) { if (value > 0) {
// Play global track
if (value > 2999) return;
#ifdef DIAG_IO #ifdef DIAG_IO
DIAG(F("DFPlayer: Play %d"), value); DIAG(F("DFPlayer: Play %d"), value);
#endif #endif
sendPacket(0x03, value); sendPacket(0x03, value); // Play track
_playing = true; _playing = true;
} else if (value == 0){ if (volume > 0) {
#ifdef DIAG_IO
DIAG(F("DFPlayer: Volume %d"), volume);
#endif
sendPacket(0x06, volume); // Set volume
}
} else {
#ifdef DIAG_IO #ifdef DIAG_IO
DIAG(F("DFPlayer: Stop")); DIAG(F("DFPlayer: Stop"));
#endif #endif
sendPacket(0x16); sendPacket(0x16); // Stop play
_playing = false; _playing = false;
} }
break; } else if (pin == 1) {
case 1:
// Set volume (0-30) // Set volume (0-30)
if (value > 30) value = 30; if (value > 30) value = 30;
else if (value < 0) value = 0; else if (value < 0) value = 0;
@ -153,9 +166,6 @@ protected:
DIAG(F("DFPlayer: Volume %d"), value); DIAG(F("DFPlayer: Volume %d"), value);
#endif #endif
sendPacket(0x06, value); sendPacket(0x06, value);
break;
default:
break;
} }
} }

View File

@ -24,8 +24,9 @@
// Examples of statically defined HAL directives (alternative to the create() call). // Examples of statically defined HAL directives (alternative to the create() call).
// These have to be outside of the mySetup() function. // These have to be outside of the mySetup() function.
//=======================================================================
// The following directive defines a PCA9685 PWM Servo driver module. // The following directive defines a PCA9685 PWM Servo driver module.
//=======================================================================
// The parameters are: // The parameters are:
// First Vpin=100 // First Vpin=100
// Number of VPINs=16 (numbered 100-115) // Number of VPINs=16 (numbered 100-115)
@ -34,13 +35,15 @@
//PCA9685 pwmModule1(100, 16, 0x40); //PCA9685 pwmModule1(100, 16, 0x40);
//=======================================================================
// The following directive defines an MCP23017 16-port I2C GPIO Extender module. // The following directive defines an MCP23017 16-port I2C GPIO Extender module.
//=======================================================================
// The parameters are: // The parameters are:
// First Vpin=164 // First Vpin=196
// Number of VPINs=16 (numbered 164-179) // Number of VPINs=16 (numbered 196-211)
// I2C address of module=0x20 // I2C address of module=0x22
//MCP23017 gpioModule2(164, 16, 0x20); //MCP23017 gpioModule2(196, 16, 0x22);
// Alternative form, which allows the INT pin of the module to request a scan // Alternative form, which allows the INT pin of the module to request a scan
@ -48,19 +51,23 @@
// all the time, only when a change takes place. Multiple modules' INT pins // all the time, only when a change takes place. Multiple modules' INT pins
// may be connected to the same Arduino pin. // may be connected to the same Arduino pin.
//MCP23017 gpioModule2(164, 16, 0x20, 40); //MCP23017 gpioModule2(196, 16, 0x22, 40);
//=======================================================================
// The following directive defines an MCP23008 8-port I2C GPIO Extender module. // The following directive defines an MCP23008 8-port I2C GPIO Extender module.
//=======================================================================
// The parameters are: // The parameters are:
// First Vpin=300 // First Vpin=300
// Number of VPINs=8 (numbered 300-307) // Number of VPINs=8 (numbered 300-307)
// I2C address of module=0x22 // I2C address of module=0x22
//MCP23017 gpioModule3(300, 8, 0x22); //MCP23008 gpioModule3(300, 8, 0x22);
//=======================================================================
// The following directive defines a PCF8574 8-port I2C GPIO Extender module. // The following directive defines a PCF8574 8-port I2C GPIO Extender module.
//=======================================================================
// The parameters are: // The parameters are:
// First Vpin=200 // First Vpin=200
// Number of VPINs=8 (numbered 200-207) // Number of VPINs=8 (numbered 200-207)
@ -74,7 +81,9 @@
//PCF8574 gpioModule4(200, 8, 0x23, 40); //PCF8574 gpioModule4(200, 8, 0x23, 40);
// The following directive defines an HCSR04 ultrasonic module. //=======================================================================
// The following directive defines an HCSR04 ultrasonic ranging module.
//=======================================================================
// The parameters are: // The parameters are:
// Vpin=2000 (only one VPIN per directive) // Vpin=2000 (only one VPIN per directive)
// Number of VPINs=1 // Number of VPINs=1
@ -90,7 +99,10 @@
//HCSR04 sonarModule1(2000, 30, 31, 20, 25); //HCSR04 sonarModule1(2000, 30, 31, 20, 25);
//HCSR04 sonarModule2(2001, 30, 32, 20, 25); //HCSR04 sonarModule2(2001, 30, 32, 20, 25);
// The following directive defines a single VL53L0X Time-of-Flight sensor.
//=======================================================================
// The following directive defines a single VL53L0X Time-of-Flight range sensor.
//=======================================================================
// The parameters are: // The parameters are:
// VPIN=5000 // VPIN=5000
// Number of VPINs=1 // Number of VPINs=1
@ -103,29 +115,33 @@
// For multiple VL53L0X modules, add another parameter which is a VPIN connected to the // For multiple VL53L0X modules, add another parameter which is a VPIN connected to the
// module's XSHUT pin. This allows the modules to be configured, at start, // module's XSHUT pin. This allows the modules to be configured, at start,
// with distinct I2C addresses. In this case, the address 0x29 is only used during // with distinct I2C addresses. In this case, the address 0x29 is only used during
// initialisation to configure each device with the desired unique I2C address. // initialisation to configure each device in turn with the desired unique I2C address.
// The examples below have one module's XSHUT pin connected to Arduino pin 34, // The examples below have the modules' XSHUT pins connected to the first two pins of
// and the other's connected to the second pin on the first MCP23017 module (VPIN 165). // the first MCP23017 module (164 and 165), but Arduino pins may be used instead.
// The first module is given I2C address 0x30 and the second is 0x31. // The first module here is given I2C address 0x30 and the second is 0x31.
//VL53L0X tofModule1(5000, 1, 0x30, 200, 250, 34); //VL53L0X tofModule1(5000, 1, 0x30, 200, 250, 164);
//VL53L0X tofModule2(5001, 1, 0x31, 200, 250, 165); //VL53L0X tofModule2(5001, 1, 0x31, 200, 250, 165);
//=======================================================================
// The function mySetup() is invoked from CS if it exists within the build. // The function mySetup() is invoked from CS if it exists within the build.
// It is called just before mysetup.h is executed, so things set up within here can be // It is called just before mysetup.h is executed, so things set up within here can be
// referenced by commands in mySetup.h. // referenced by commands in mySetup.h.
//=======================================================================
void mySetup() { void mySetup() {
// Alternative way of creating MCP23017, which has to be within the mySetup() function // Alternative way of creating a module driver, which has to be within the mySetup() function
// The other devices can also be created in this way. The parameter lists for the // The other devices can also be created in this way. The parameter lists for the
// create() function are identical to the parameter lists for the declarations. // create() function are identical to the parameter lists for the declarations.
//MCP23017::create(180, 16, 0x21); //MCP23017::create(196, 16, 0x22);
//=======================================================================
// Creating a Turnout // Creating a Turnout
//=======================================================================
// Parameters: same as <T> command for Servo turnouts // Parameters: same as <T> command for Servo turnouts
// ID and VPIN are 100, sonar moves between positions 102 and 490 with slow profile. // ID and VPIN are 100, sonar moves between positions 102 and 490 with slow profile.
// Profile may be Instant, Fast, Medium, Slow or Bounce. // Profile may be Instant, Fast, Medium, Slow or Bounce.
@ -133,7 +149,9 @@ void mySetup() {
//ServoTurnout::create(100, 100, 490, 102, PCA9685::Slow); //ServoTurnout::create(100, 100, 490, 102, PCA9685::Slow);
//=======================================================================
// DCC Accessory turnout // DCC Accessory turnout
//=======================================================================
// Parameters: same as <T> command for DCC Accessory turnouts // Parameters: same as <T> command for DCC Accessory turnouts
// ID=3000 // ID=3000
// Decoder address=23 // Decoder address=23
@ -142,7 +160,9 @@ void mySetup() {
//DCCTurnout::create(3000, 23, 1); //DCCTurnout::create(3000, 23, 1);
//=======================================================================
// Creating a Sensor // Creating a Sensor
//=======================================================================
// Parameters: As for the <S> command, // Parameters: As for the <S> command,
// id = 164, // id = 164,
// Vpin = 164 (configured above as pin 0 of an MCP23017) // Vpin = 164 (configured above as pin 0 of an MCP23017)
@ -151,11 +171,44 @@ void mySetup() {
//Sensor::create(164, 164, 1); //Sensor::create(164, 164, 1);
//=======================================================================
// Way of creating lots of identical sensors in a range // Way of creating lots of identical sensors in a range
//=======================================================================
//for (int i=165; i<180; i++) //for (int i=165; i<180; i++)
// Sensor::create(i, i, 1); // Sensor::create(i, i, 1);
//=======================================================================
// Play mp3 files from a Micro-SD card, using a DFPlayer MP3 Module.
//=======================================================================
// Parameters:
// 10000 = first VPIN allocated.
// 10 = number of VPINs allocated.
// Serial1 = name of serial port (usually Serial1 or Serial2).
// With these parameters, up to 10 files may be played on pins 10000-10009.
// Play is started from EX-RAIL with SET(10000) for first mp3 file, SET(10001)
// for second file, etc. Play may also be initiated by writing an analogue
// value to the first pin, e.g. SERVO(10000,23,0) will play the 23rd mp3 file.
// SERVO(10000,23,30) will do the same thing, as well as setting the volume to
// 30 (maximum value).
// Play is stopped by RESET(10000) (or any other allocated VPIN).
// Volume may also be set by writing an analogue value to the second pin for the player,
// e.g. SERVO(10001,30,0) sets volume to maximum (30).
// The EX-RAIL script may check for completion of play by calling WAITFOR(pin), which will only proceed to the
// following line when the player is no longer busy.
// E.g.
// SEQUENCE(1)
// AT(164) // Wait for sensor attached to pin 164 to activate
// SET(10003) // Play fourth MP3 file
// LCD(4, "Playing") // Display message on LCD/OLED
// WAITFOR(10003) // Wait for playing to finish
// LCD(4, " ") // Clear LCD/OLED line
// FOLLOW(1) // Go back to start
// DFPlayer::create(10000, 10, Serial1);
} }
#endif #endif