diff --git a/IO_DFPlayer.h b/IO_DFPlayer.h index f7a1a9b..4c133b5 100644 --- a/IO_DFPlayer.h +++ b/IO_DFPlayer.h @@ -27,17 +27,19 @@ * The driver is configured as follows: * * DFPlayer::create(firstVpin, nPins, Serialn); + * * Where firstVpin is the first vpin reserved for reading the device, * 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: * In mySetup function within mySetup.cpp: - * DFPlayer::create(3500, 5, Serial2); - * 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 a digital value to the first pin will play or stop the file; + * DFPlayer::create(3500, 5, Serial1); + * + * 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; + * 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: * SET(3500) -- starts playing the first file on the SD card @@ -45,6 +47,9 @@ * etc. * RESET(3500) -- stops all playing on the player * 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 * to the DFPlayer's RX terminal will cause lots of noise over the speaker, or worse. @@ -123,39 +128,44 @@ protected: } // 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. - 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; - switch (pin) { - case 0: - if (value > 0) { - // Play global track - if (value > 2999) return; - #ifdef DIAG_IO - DIAG(F("DFPlayer: Play %d"), value); - #endif - sendPacket(0x03, value); - _playing = true; - } else if (value == 0){ - #ifdef DIAG_IO - DIAG(F("DFPlayer: Stop")); - #endif - sendPacket(0x16); - _playing = false; - } - break; - case 1: - // Set volume (0-30) - if (value > 30) value = 30; - else if (value < 0) value = 0; + + // Validate parameter. + volume = min(30,volume); + + if (pin == 0) { + // Play track + if (value > 0) { #ifdef DIAG_IO - DIAG(F("DFPlayer: Volume %d"), value); + DIAG(F("DFPlayer: Play %d"), value); #endif - sendPacket(0x06, value); - break; - default: - break; + sendPacket(0x03, value); // Play track + _playing = true; + if (volume > 0) { + #ifdef DIAG_IO + DIAG(F("DFPlayer: Volume %d"), volume); + #endif + sendPacket(0x06, volume); // Set volume + } + } else { + #ifdef DIAG_IO + DIAG(F("DFPlayer: Stop")); + #endif + sendPacket(0x16); // Stop play + _playing = false; + } + } else if (pin == 1) { + // Set volume (0-30) + if (value > 30) value = 30; + else if (value < 0) value = 0; + #ifdef DIAG_IO + DIAG(F("DFPlayer: Volume %d"), value); + #endif + sendPacket(0x06, value); } } diff --git a/mySetup.cpp_example.txt b/mySetup.cpp_example.txt index 0e2be50..0efc771 100644 --- a/mySetup.cpp_example.txt +++ b/mySetup.cpp_example.txt @@ -24,8 +24,9 @@ // Examples of statically defined HAL directives (alternative to the create() call). // These have to be outside of the mySetup() function. - +//======================================================================= // The following directive defines a PCA9685 PWM Servo driver module. +//======================================================================= // The parameters are: // First Vpin=100 // Number of VPINs=16 (numbered 100-115) @@ -34,13 +35,15 @@ //PCA9685 pwmModule1(100, 16, 0x40); +//======================================================================= // The following directive defines an MCP23017 16-port I2C GPIO Extender module. +//======================================================================= // The parameters are: -// First Vpin=164 -// Number of VPINs=16 (numbered 164-179) -// I2C address of module=0x20 +// First Vpin=196 +// Number of VPINs=16 (numbered 196-211) +// 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 @@ -48,19 +51,23 @@ // all the time, only when a change takes place. Multiple modules' INT pins // 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 parameters are: // First Vpin=300 // Number of VPINs=8 (numbered 300-307) // 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 parameters are: // First Vpin=200 // Number of VPINs=8 (numbered 200-207) @@ -74,7 +81,9 @@ //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: // Vpin=2000 (only one VPIN per directive) // Number of VPINs=1 @@ -90,7 +99,10 @@ //HCSR04 sonarModule1(2000, 30, 31, 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: // VPIN=5000 // Number of VPINs=1 @@ -103,29 +115,33 @@ // 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, // 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. -// The examples below have one module's XSHUT pin connected to Arduino pin 34, -// and the other's connected to the second pin on the first MCP23017 module (VPIN 165). -// The first module is given I2C address 0x30 and the second is 0x31. +// initialisation to configure each device in turn with the desired unique I2C address. +// The examples below have the modules' XSHUT pins connected to the first two pins of +// the first MCP23017 module (164 and 165), but Arduino pins may be used instead. +// 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); +//======================================================================= // 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 // referenced by commands in mySetup.h. +//======================================================================= 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 // create() function are identical to the parameter lists for the declarations. - //MCP23017::create(180, 16, 0x21); + //MCP23017::create(196, 16, 0x22); + //======================================================================= // Creating a Turnout + //======================================================================= // Parameters: same as command for Servo turnouts // ID and VPIN are 100, sonar moves between positions 102 and 490 with slow profile. // Profile may be Instant, Fast, Medium, Slow or Bounce. @@ -133,7 +149,9 @@ void mySetup() { //ServoTurnout::create(100, 100, 490, 102, PCA9685::Slow); + //======================================================================= // DCC Accessory turnout + //======================================================================= // Parameters: same as command for DCC Accessory turnouts // ID=3000 // Decoder address=23 @@ -142,7 +160,9 @@ void mySetup() { //DCCTurnout::create(3000, 23, 1); + //======================================================================= // Creating a Sensor + //======================================================================= // Parameters: As for the command, // id = 164, // Vpin = 164 (configured above as pin 0 of an MCP23017) @@ -151,11 +171,44 @@ void mySetup() { //Sensor::create(164, 164, 1); + //======================================================================= // Way of creating lots of identical sensors in a range + //======================================================================= //for (int i=165; i<180; i++) // 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