Giter Site home page Giter Site logo

dyplayer's Introduction

Abstracted UART Control of DY-XXXX mp3 modules

This library abstracts all features described in the manual into a C++ class.

This library does not support the ONE_Line protocol, more info.

Although all features are implemented and should theoretically work, only those in the examples directory are tested. Please create an issue if you have problems.

This library was written in a hardware independent way. Which means it should work on any device with a serial port, e.g. any Arduino, Espressif, ARM based boards, probably even any computer.

There are Hardware Abstraction Layers (HAL) included for Arduino and ESP-IDF, for other boards you will have to provide one yourself (PR is welcome!).

Note on upgrading from version 3.x.x to version 4.x.x

TL;DR: Change all occurances of enum constants of DY::Device, DY::PlayState, DY::Eq, DY::PlayMode and DY::PreviousDir from upper case to CamelCase, e.g.: DY::Device::FLASH to DY::Device::Flash.

One of the problems with C++ I learned about, the hard way is how the namespace can still be polluted despite namespacing everything. As macro's are handled by the preprocessor, any mention of a macro in the source, even if obviously intended as code (well to a human) will be interpreted as a call to a macro.

Embedded devices' headers rely on macro's heavily and they aren't generally prefixed. So users reported collisions between constants such as USB (it's actually part of an enum class: DY::Device::USB which makes this even more frustrating) and a macro defined for a board that has a USB port, also named USB.

The only way around it is to drop the social convention (that was arguably already advised against) of naming constants in capitals, the compiler doesn't care about this convention, it's just usually done for readability.

Modules should work (not exhaustive)

Model name Capacity SD Card support Amplifier Voltage Tested
DY-SV17F 32Mbit No 3-5W(4Ω/8Ω) 5VDC Yes
DY-SV8F 64Mbit No 3-5W(4Ω/8Ω) 5VDC No
DY-HV20T NA Yes, Max. 32GB 3-5W(4Ω/8Ω) 5VDC No
DY-HV8F 8Mbit No 10W(8Ω)/20W(4Ω) 6-35VDC No
DY-HV20T NA Yes, Max. 32GB 10W(8Ω)/20W(4Ω) 6-35VDC No
DY-SV5W NA Yes, Max. 32GB 3-5W(4Ω/8Ω) 5VDC Yes

NOTE: I cannot guarantee that your board will work with the library. Nor that a specific feature will work. I only have the DY-SV17F in my possession to test at the time of writing. If something does not work, make an issue and/or send me a pull request.

Wiring the module

If you have a board with DIP switches, set CON3 to on, CON1 and CON2 should remain off. If your board doesn't have DIP switches (e.g. DY-SV17F board), you have to connect 3 resistors of 10KOhm, one from each CON# pin, to:

CON pin Connect to Via
CON1 GND 10KOhm
CON2 GND 10KOhm
CON3 3.3V 10KOhm

The 3.3V pin is exposed by the board so you don't need to provide it yourself.

Further make these connections:

Pin Connect to Via
V? V+ (voltage depends on module)
GND GND
IO0/TX MCU RX 1KOhm if using a 5V board
IO1/RX MCU TX 1KOhm if using a 5V board
SPK+ Speaker positive lead
SPK- Speaker negative lead

MCU should be your board or microprocessor, e.g. an Arduino board.

Note the logic levels should be 3.3V or at least limited by a 1KOhm resistor according to the module manual, or you could damage the module. Some modules appear to have resistors soldered onto the board. Make sure to check the datasheet of your board.

HAL

Arduino tl;dr; If you are using Arduino, skip this chapter and go to Arduino.

ESP32 tl;dr; If you are using ESP-IDF, skip this chapter and go to ESP-IDF.

Because the library is hardware independent you might need to add a Hardware Abstraction Layer (HAL) which sets up the serial port and that implements a minimum of 2 functions serialWrite() and serialRead(), there is a HAL for Arduino included, here's a simplified version of it:

// player.hpp
#include <Arduino.h>
#include "DYPlayer.h"
namespace DY {
  class Player: public DYPlayer {
    public:
      HardwareSerial *port;
      Player();
      Player(HardwareSerial* port);
      void begin();
      void serialWrite(uint8_t *buffer, uint8_t len);
      bool serialRead(uint8_t *buffer, uint8_t len);
  };
}


//player.cpp
#include "player.hpp"
#include "DYPlayerArduino.h"

namespace DY {
  Player::Player() {
    this->port = &Serial;
  }
  Player::Player(HardwareSerial* port) {
    this->port = port;
  }
  void Player::begin() {
    port->begin(9600);
  }
  void Player::serialWrite(uint8_t *buffer, uint8_t len) {
    port->write(buffer, len);
  }
  bool Player::serialRead(uint8_t *buffer, uint8_t len) {
    // Serial.setTimeout(1000); // Default timeout 1000ms.
    if(port->readBytes(buffer, len) > 0) {
      return true;
    }
    return false;
  }
}

Note: This Arduino HAL is simplied, the included HAL does SoftwareSerial as well which adds some complexity that I don't think should be in an example like this. You can find the real HAL here.

Steps:

  1. Define a class that extends the DY::DYPlayer class.
  2. Define constructors that set up the serial port. On some platforms you will need to setup your serial port after some other things are initialized, e.g. on Arduino, then define an additional DY::Player::begin() (or e.g. DY::Player::init()) to finish initialisation.
  3. Define functions for serialWrite() and serialRead() according to the board and the framework you use.

Memory use

This library uses a little memory as possible to play nice with micro controllers with small RAM, such as Atmega328 (used in many Arduino boards), which has 2K RAM.

To keep memory usage low, avoid using the functions that take char *path arguments. If you do not intend to play sounds by file name, you can skip the rest of this chapter. If you do, keep reading.

The char *path arguments will always use more RAM than the uint16_t arguments, obviously but this is compounded by an odd requirement of the player modules. I.e. the paths to files on flash/SD card have to be defined different than usual, e.g. /SONGS/IN/A/PATH/00001.MP3 should be specified as: /SONGS*/IN*/A*/PATH*/00001*MP3

Analysing this:

  • Paths normally end in / but an additional * is required;
  • except for the root level.
  • Period in before the extension should be replaced by * as well.
  • The new path is 4 bytes longer than the specified path.

The conversion is done by the library but this means that the path is allocated twice in memory, once by you, once by the library and the latter needs to have more capacity (in this case 4 bytes). The libray can keep the second string's memory in 2 ways: in heap or in stack memory.

Stack memory is not dynamic, i.e.: the required amount of bytes should be known at compile time, which means more than the expected amount of bytes should already be reserved, which is wasteful. Aside from being wastelful, the path could be really short (most likely, e.g. /00001.MP3 or something like /SFX/00001.MP3), or it could be really long..

Putting the path in dynamically assigned heap memory fixes all of that, the library can count the amount of / in the path and make a variable exactly long enough for the converted path. However we should always be wary of Heap fragmentation. In short to assign memory, a contgious block of it needs to be available. Assigning chunks of memory and then freeing them leaves holes in the memory that may be be too small to use again later. This will gradually lead to problems. You may need to reset your device after several minutes, hours or days because the program can't allocate heap memory any more.

So, by default the library will reserve stack memory. The amount is based on some assumptions:

  • The manual of the sound modules states that paths and file names may be up to 8 characters long.
  • The library assumes that you will not nest more than 2 directories.
  • Extentions can be .MP3 or .WAV, so always 4 bytes.

So we come to:

/ dir */ dir */ file * ext

1 + 8 + 2 + 8 + 2 + 8 + 1 + 4 = 34

Let's round that up to 40 and you could even have some more nesting as long as the directory names are small enough.

The library will therefore define DY_PATH_LEN as 40, you can override that if you need more, or if you want to save a few bytes of precious memory. Note that 40 is the maximum length of the path after conversion to the funcky format required by the module. The amount of bytes you may use with this default is set at 36.

Alternatively, if you have a more capable device and/or you can use virtual memory, you can define DY_PATHS_IN_HEAP to use heap memory instead of reserved stack memory.

NOTE: On Arduino, you can wrap your strings in F() to tell the compiler you want the string stored in flash, as opposed to RAM (default), which will save you even more RAM.

Arduino

Because this is included, on Arduino you can just include the DYPlayerArduino.h header file and use the module.

You may use any Serial port on the board, you will have to pass it to the begin() function. Like this:

DY::Player player(&Serial2);

To find out how to use the Arduino HAL see PlaySoundByNumber.ino.

ESP-IDF

Because this is included, on Arduino you can just include the DYPlayerESP32.h header file and use the module.

You may use any Serial port on the board, and any 2 pins for TX and RX. E.g.: user UART_NUM_2 on pins TX: 18, RX: 19:

DY::Player player(UART_NUM_2, 18, 19);

You can find an example here: PlaySounds.cpp.

API

The library abstracts sending binary commands to the module. There is manual for the module floating around the web, which I am not sure is copy righted or not, so I won't upload it here or link to it. Just google DY-SV17F manual & Datasheet and you will probably find it.

The manual doesn't clearly name any of the commands so I came up with class method names myself. The manual does contain a command description so I included that in the list below. Notably the "check" commands, are named as "get" commands to incidate they retrieve information from the module. Setting you can change are applied by "set" commands.

Set methods

Setting or playing any sound is not confirmed by the module so if you need confirmation that the module is doing what is expected, you need to use one of the get functions to verify that it's doing what you told it to. E.g. when you play a sound, you can consequently call DY::DYPlayer::getPlayingSound() to check that it worked.

Get methods

Get methods will send a command to the module and wait for an answer. If an answer is not received a timeout will expire and subsequently an they will return 0 for sound counts,

Command/method list

Command (from the manual) byte Method name
Check the play state 0x01 DY::PlayState::play_state_t DY::DYPlayer::checkPlayState
Play 0x02 void DY::DYPlayer::play
Pause 0x03 void DY::DYPlayer::pause
Stop 0x04 void DY::DYPlayer::stop
Previous Music 0x05 void DY::DYPlayer::previous
Next music 0x06 void DY::DYPlayer::next
Play specified music 0x07 void DY::DYPlayer::playSpecified
Specified device and path play 0x08 void DY::DYPlayer::playSpecifiedDevicePath
Check Current Playing Device 0x0a DY::Device::device_t DY::DYPlayer::getPlayingDevice
Switch to selected device 0x0b void DY::DYPlayer::setPlayingDevice
Check Number Of all Music 0x0c uint16_t DY::DYPlayer::getSoundCount
Check Current Music 0x0d uint16_t DY::DYPlayer::getPlayingSound
Previous folder directory (first) 0x0e void DY::DYPlayer::previousDir
Previous folder directory (last) 0x0f void DY::DYPlayer::previousDir
End playing 0x10 void DY::DYPlayer::stopInterlude
Check the first music in folder 0x11 uint16_t DY::DYPlayer::getFirstInDir
Check Number of music in folder 0x12 uint16_t DY::DYPlayer::getSoundCountDir
Volume setting 0x13 void DY::DYPlayer::setVolume
Volume+ 0x14 void DY::DYPlayer::volumeIncrease
Volume- 0x15 void DY::DYPlayer::volumeDecrease
Select specified file to interlude 0x16 void DY::DYPlayer::interludeSpecified
Select specified path to interlude 0x17 void DY::DYPlayer::interludeSpecifiedDevicePath
Cycle mode setting 0x18 void DY::DYPlayer::setCycleMode
Cycle times setting 0x19 void DY::DYPlayer::setCycleTimes
Set EQ 0x1a void DY::DYPlayer::setEq
Combination play setting 0x1b void DY::DYPlayer::combinationPlay
End Combination play 0x1c void DY::DYPlayer::endCombinationPlay
Select file but do not play 0x1f void DY::DYPlayer::select

UART commands are formed by:

aa [cmd] [len] [byte_1..n] [crc]

Where:

  • aa Start a command
  • [cmd] A command from the list, e.g. 01 to check the play state.
  • [len] The length of the amount of bytes sent as an argument.
  • [byte_1..n] All bytes uses as arguments, some argument are 1 byte, such as for selecting the storage device, some are 2 bytes long such as specifying a song by number (uint16_t value, between 0 and 65535), sometimes it's a combination, or a path.
  • [crc] The sum of all bytes in the entire command as a uint8_t.

API documentation

DY::play_state_t DY::DYPlayer::checkPlayState(..)

Check the current play state can, be called at any time.

Type Name Description
return DY::play_state_t Play status: A DY::PlayState e.g DY::PlayState::Stopped, DY::PlayState::Playing, etc

void DY::DYPlayer::play(..)

Play the currently selected file from the start.

void DY::DYPlayer::pause(..)

Set the play state to paused.

void DY::DYPlayer::stop(..)

Set the play state to stopped.

void DY::DYPlayer::previous(..)

Play the previous file.

void DY::DYPlayer::next(..)

Play the next file.

void DY::DYPlayer::playSpecified(..)

Play a sound file by number, number sent as 2 bytes.

Type Name Description
param uint16_t number number of the file, e.g. 1 for 00001.mp3

void DY::DYPlayer::playSpecifiedDevicePath(..)

Play a sound file by device and path. Path may consist of up to 2 nested directories of 8 bytes long and a file name of 8 bytes long excluding the extension of 4 bytes long. If your directory names are shorter you can use more nesting. Use no more than 36 bytes for your paths. If you require more, check the readme, chapter: Memory use.

Type Name Description
param DY::device_t device device A DY::Device member e.g DY::Device::Flash or DY::Device::Sd
param char path path pointer to the path of the file (asbsolute)

DY::device_t DY::DYPlayer::getPlayingDevice(..)

Get the storage device that is currently used for playing sound files.

Type Name Description
return DY::device_t a DY::Device member e.g DY::Device::Flash or DY::Device::Sd

void DY::DYPlayer::setPlayingDevice(..)

Set the device number the module should use. Tries to set the device but no guarantee is given, use getDevice() to check the actual current storage device.

Type Name Description
param DY::device_t device device A DY::Device member e.g DY::Device::Flash or DY::Device::Sd

uint16_t DY::DYPlayer::getSoundCount(..)

Get the amount of sound files on the current storage device.

Type Name Description
return uint16_t number of sound files

uint16_t DY::DYPlayer::getPlayingSound(..)

Get the currently playing file by number.

Type Name Description
return uint16_t number of the file currently playing

void DY::DYPlayer::previousDir(..)

Select previous directory and start playing the first or last song.

Type Name Description
param playDirSound_t song song Play DY::PreviousDir::FirstSound o DY::PreviousDir::LastSoun

uint16_t DY::DYPlayer::getFirstInDir(..)

Get number of the first song in the currently selected directory.

Type Name Description
return uint16_t number of the first song in the currently selected directory

uint16_t DY::DYPlayer::getSoundCountDir(..)

Get the amount of sound files in the currently selected directory. NOTE: Excluding files in sub directories.

Type Name Description
return uint16_t number of sound files in currently selected directory

void DY::DYPlayer::setVolume(..)

Set the playback volume between 0 and 30. Default volume if not set: 20.

Type Name Description
param uint8_t volume volume to set (0-30

void DY::DYPlayer::volumeIncrease(..)

Increase the volume.

void DY::DYPlayer::volumeDecrease(..)

Decrease the volume.

void DY::DYPlayer::interludeSpecified(..)

Play an interlude file by device and number, number sent as 2 bytes. Note from the manual: "Music interlude" only has level 1. Continuous interlude will cover the previous interlude (the interlude will be played immediately). When the interlude is finished, it will return to the first interlude breakpoint and continue to play.

Type Name Description
param DY::device_t device device A DY::Device member e.g DY::Device::Flash or DY::Device::Sd
param uint16_t number number of the file, e.g. 1 for 00001.mp3

void DY::DYPlayer::interludeSpecifiedDevicePath(..)

Play an interlude by device and path. Note from the manual: "Music interlude" only has level 1. Continuous interlude will cover the previous interlude (the interlude will be played immediately). When the interlude is finished, it will return to the first interlude breakpoint and continue to play.

Path may consist of up to 2 nested directories of 8 bytes long and a file name of 8 bytes long excluding the extension of 4 bytes long. If your directory names are shorter you can use more nesting. Use no more than 36 bytes for your paths. If you require more, check the readme, chapter: Memory use.

Type Name Description
param DY::device_t device device A DY::Device member e.g DY::Device::Flash or DY::Device::Sd
param char path path pointer to the path of the file (asbsolute)

void DY::DYPlayer::stopInterlude(..)

Stop the interlude and continue playing. Will also stop the current sound from playing if interlude is not active.

void DY::DYPlayer::setCycleMode(..)

Sets the cycle mode. See DY::play_mode_t for modes and meaning.

Type Name Description
param play_mode_t mode mode The cycle mode to set

void DY::DYPlayer::setCycleTimes(..)

Set how many cycles to play when in cycle modes 0, 1 or 4 (repeat modes).

Type Name Description
param uint16_t cycles cycles The cycle count for repeat modes

void DY::DYPlayer::setEq(..)

Set the equalizer setting. See DY::eq_t for settings.

Type Name Description
param DY::eq_t eq eq The equalizer setting

void DY::DYPlayer::select(..)

Select a sound file without playing it.

Type Name Description
param uint16_t number number of the file, e.g. 1 for 00001.mp3

void DY::DYPlayer::combinationPlay(..)

Combination play allows you to make a playlist of multiple sound files.

You could use this to combine numbers e.g.: "fourthy-two" where you have samples for "fourthy" and "two".

This feature has a particularly curious parameters, you have to specify the sound files by name, they have to be named by 2 numbers and an extension, e.g.: 01.mp3 and specified by 01. You should pass them as an array pointer. You need to put the files into a directory that can be called DY, ZH or XY`, you will have to check the manual that came with your module, or try all of them. There may well be more combinations! Also see Loading sound files.

E.g.

const char * sounds[2][3] = { "01", "02" };
DY::DYPlayer::combinationPlay(sounds, 2);
Type Name Description
param char sounds sounds An array of char[2] containing the names of sounds t play in order
param uint8_t len len The length of the passed array

void DY::DYPlayer::endCombinationPlay(..)

End combination play.

typedef enum class DY::device_t

Storage devices reported by module and to choose from when selecting a storage device.

const value description
DY::Device::Usb 0x00 USB Storage device.
DY::Device::Sd 0x01 SD Card.
DY::Device::Flash 0x02 Onboard flash chip (usually winbond 32, 64Mbit flash).
DY::Device::Fail 0xfe UART failure, can't be -1 (so this can be uint8_t).
DY::Device::NoDevice 0xff No storage device is online.

This enum class is based off uint8_t.

typedef enum class DY::play_state_t

The current module play state.

const value description
DY::PlayState::Fail -1 UART Failure, can be a connection or a CRC problem.
DY::PlayState::Stopped 0
DY::PlayState::Playing 1
DY::PlayState::Paused 2

This enum class is based off int8_t.

typedef enum class DY::eq_t

Equalize settings.

const value
DY::Eq::Normal 0x00
DY::Eq::Pop 0x01
DY::Eq::Rock 0x02
DY::Eq::Jazz 0x03
DY::Eq::Classic 0x04

This enum class is based off uint8_t.

typedef enum class DY::play_mode_t

Play modes are basically whatever you commonly find on a media player, i.e.: Repeat 1, Repeat all, Repeat list (dir), playlist (by dir), random play.

The default is perhaps somewhat unexpected: DY::PlayMode::OneOff. Often these modules will be used in toys or information displays where you can press a button and hear a corresponding sound. To get default media player behaviour, you should probably set DY::PlayMode::Sequence to just continue playing the next song until all are played or skipped, then stop.

const value description
DY::PlayMode::Repeat 0x00 Play all music in sequence, and repeat.
DY::PlayMode::RepeatOne 0x01 Repeat current sound.
DY::PlayMode::OneOff 0x02 Play sound file and stop.
DY::PlayMode::Random 0x03 Play random sound file.
DY::PlayMode::RepeatDir 0x04 Repeat current directory.
DY::PlayMode::RandomDir 0x05 Play random sound file in current folder.
DY::PlayMode::SequenceDir 0x06 Play all sound files in current folder in sequence, and stop.
DY::PlayMode::Sequence 0x07 Play all sound files on device in sequence, and stop.

Loading sound files

Normal Playback

For normal playback of sound files, I recommend you name your files sequentially and put them in the root directory of the drive unless you need something more fancy. The numbering should be as follows:

00001.mp3
00002.mp3
00003.mp3
...
65535.mp3

Important: files do not play in order of named sequence

The DY::DYPlayer::playSpecified function will not necessarily play the sound file named 00001.MP3 when asked to play sound file 1. The module will look for the first sound file found in the filesystem. It's not using the file name, neither does it order by file name. To be sure the sound files play in the expected order:

  1. Empty the storage device.
  2. Make sure there aren't any trash files on the storage device.
  3. Copy the files in the order they should be played (it helps to have them named sequentially, sort by name and copy the files, usually they will be copied in sequence order.

Please don't file bugs stating there is a bug in the DY::DYPlayer::playSpecified function because 00001.MP3 doesn't play when 1 is sent to the module. It's not a bug in this library, it's how the module works. If you find that the above information is not correct, or if you have suggestions for improvements, please do create an issue..

By file path

You can also use paths and filenames but neither directory nor filename should exceed 8 bytes. You can put the files in directories, but don't make a lot of nested directories. Files in the root are played by specifying the path as /00001.MP3 (note the /).

Use normal paths

In the module's manual you can find that paths are required to be separated by */ and * in place of ., upper case characters, etc., etc. Forget about all of that, just supply paths as you are used to, case insensitive, no funny character substitutions. The library will handle the required conversions.

Combination play

For combination play, you will have to add files with names of 2 characters plus the extension, e.g.: 01.mp3 into a directory that can be called XY, ZH, DY, you will have to check the manual that came with your module, or try all of them. There may well be more options! Most manuals claim it should be DYbut most people reported thatXYactually works, so try:/DY/##.MP3` first.

If you find out what the letter combination on your board is, please add an issue with the directory name and the module model name, so I can add it here to help others.

ONE_LINE support?

This library only supports UART at this time. It should be relatively straight forward to add the ONE_Line protocol as found in the manual. Note however that the entire communication protocol is different from the UART protocol. So there is no particular benefit to adding it to this library. That said, if you plan to implement it, we could discuss merging it with this library for convenience.

Runnning this library on PIC

It's not supported, however there you can find a port here by @DoubleTop12, proving it's possible with some effort.

Troubleshooting

No communication with the board

  • Check power is supplied to the module.
  • Check that TX on your Arduino board connects to RX on the module and vice versa, check that you connected the serial lines through resistors if your Arduino runs on 5V. See Wiring the module.
  • Check the configuration of the board, either by connecting the correct value of resistors to the correct CON# pins or, if your board has them, the DIP switches are set to the correct value. See Wiring the module.
  • If you share the serial port between the computer for flashing and connecting to the module, disconnect the cable (FTDI or USB cable) from the board before booting it. Anything on the module TX line besides your Arduino board will prevent data from being received.
  • Check there are compatible sound files on the modules storage device, maybe it's connecting, but doesn't have a sound to play, use DY::DYPlayer::playSpecified to play sound file 00001.MP3 because it's more fault tolerant than by path functions.

No sound

  • Check the speaker connection.
  • Check the volume control, some boards have a potentiometer you can turn.
  • Test the speaker on another device and see if it is operational.
  • Use the DY::DYPlayer::getPlayingDevice function to see if the device is responsive.
  • See the loading sound files chapter and apply the simplest file structure to see the wiring etc is correct before filing issues.
  • Check there are compatible sound files on the modules storage device maybe it doesn't have a sound to play, use DY::DYPlayer::playSpecified to play sound file 00001.MP3 because it's more fault tolerant than by path functions.

Unexpected behaviour

dyplayer's People

Contributors

chatelao avatar fritsjan avatar irregularshed avatar snijderc avatar woutput avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dyplayer's Issues

Arduino Nano 33 IOT issue

Hi, I'm trying to use the library with a Arduino Nano 33 IOT and get the following error when compiling:
D:\Arduino\libraries\DYPlayerArduino/DYPlayer.h:392:1: error: expected declaration before '}' token
}
^
exit status 1
Error compiling for board Arduino NANO 33 IoT.

Compiling for Uno works properly, do you have an idea on what could be causing the problem?

More examples?

This library looks promising for the ardunio project I've just started working on (I'm new to arduino), as I have an MP3 board with an chipset that should be compatible with this.

Do you have any other examples of how to use the various commands, such as checkPlayState, how is this actually called and used in an arduino ini - eg: syntax?

Another example would be how to set up the RX/TX on different pins.
eg: if I set up the RX to pin 10 and TX to pin 11, I can issue commands out on pin 11, and do a checkPlayState on pin 10?

cheers

Missing library

It's maybe more about Arduino itself, not your library particularly, but when I've tried to import your library and compile just to check if it works (Arduino 1.8.13)

#include <Arduino.h>
#include "DYPlayerArduino.h"

Error log:

exit status 1
DYPlayerArduino.h: No such file or directory

I've tried to search for the lib in Arduino "Manage Libraries" section (with the DYPlayer keyword), but could not found anything related to your module: DYPlayer.

Please advice

Convert paths to uppercase

Methods that takes path arguments should convert those to upper case as it is expected by the module and more intuitive to the developer to be able to call by case insensitive paths.

Play specific files according to their actual filename.

Hi.
I don't know if it is the place to post this, but as the player plays the files in the order they are written in partition (i.e. file 1 for the first file in the partition and not for the actual 00001.mp3), it is actually possible to match each file number with it's actual filename, using a freeware called Drivesort, which sorts files in the partition without the need of formatting and copying them in the right order.

I use this software to sort USB flash drive for my car built-in mp3 player.

I hope this helps

Entering the equalizer settings command

Hello. I want to thank you for your work. I tried your code and everything works fine for me. I connect DY-17SF via uart. The only thing I can't figure out is how to change the equalizer settings. I don't understand the Arduino code very well, I'm still learning it. I have a question: is it possible to set equalizer settings in a sketch using a command similar to the volume command? If yes, please give an example. Thank you.

Version for use with PIC

I've been asked by Chris to document the variant I am using with a PIC. It is in 'C' with the XC8 complier under the MPLAB IDE.
I'm not an expert by any means but the changes are fairly minor and they work. This may even be the wrong place to post this.

Steps are:

Rename DYPlayer.cpp DyPlayer.c

Remove all class statements e.g “DYPlayer::” from all functions

Remove all “inline” statements from functions

Include relevant headers

  • #include "mcc_generated_files/uart2.h"
  • #include <xc.h>
  • #include <stdlib.h>
  • #include <stdbool.h>

Add serial read and write functions, including a separate function for the single byte crc serialwrite_crc. Using a buffer length of [1] didn’t work so this was the quick fix. Serial read write functions are as generated by MPLAB Code Configurator (MPP).

  • uint8_t UARTx_Read(void)
  • void UARTx_Write(uint8_t txData)

Amend DYPlayer.h to match DYPlayer.c

Modify typedef and enum statements to be XC8 compliant.

Files attached

DYPlayer for PIC.zip

Pete

How are the mp3 files loaded into the flash memory of the DY-SV17F?

Hi Chris,
first off, let me tell you that you really did an excellent job. I also ordered a DY-SV17F board, but it is still in the mail and has not yet arrived. But I am already thinking about the handling and I have one question: I am not sure how I can load my mp3 files into the flash memory on the DY-SV17F. I understood your explanations to mean that I simply connect the board to my PC using a USB cable and a new CD-ROM drive then appears in the PC's file explorer. Is that so and can I then simply copy my mp3 files and paste them into this CD-ROM directory? Will the IC DY1703A on the DY-SV17F board take over the entire flash programming process or do I need any special software?
And what is the reason for the file "UART tuning tool.exe", that I found elsewhere on the Internet? I have opened the exe file, a window appears with a lot of Chinese characters that mean little to me.
With best regards
maxSnyder

Only odd files are playing

Hello
I'm completely lost here. Prepared SD card according to instructions. Formatted to FAT, copied ten files one by one named 00001.mp3 etc. to the root folder. Using this function "player.playSpecified(8);"

The result is puzzling - only odd files are playing. This strange pattern is making me curious.
00001.mp3 = ok
00002.mp3 = not
00003.mp3 = ok
00004.mp3 = not
00005.mp3 = ok
00006.mp3 = not
00007mp3 = ok
00008.mp3 = not
00009.mp3 = ok
00010.mp3 = not

Changed the CD card. No change. Files are ok, playing on mac.
Formatted card and copied the back in different order.
Pattern stays the same.

Appreciate any ideas!

Janis

DYPlayer::getDevice should have parameter

I guess I interpreted the manual incorrectly, this was already not doing exactly what I expected but in hindsight that makes sense.

It should be refactored to check if a storage device is "online", probably return a boolean, in the spirit of DYPlayer::checkDeviceOnline(). The latter should probably be the name of the former.

Delay between player.begin() and player.setVolume required

Hi,

I have these

#include <SoftwareSerial.h>

SoftwareSerial SoftSerial(D1, D2); // RXpin, TXpin
DY::Player player(&SoftSerial);

and my void setup() ends with:

    player.begin();
    delay(100);
    player.setVolume(15);
    player.setCycleMode(DY::PlayMode::OneOff);
    player.stop();
    Serial.println("Setup done");

but if I remove the delay(100) after player.begin() then the setVolume command has no effect.
I'm not sure if this is an issue of this library since I've seen similar behavior after Serial.begin() but I think that it should still be solved. Maybe it can be solved by adding the delay(100) inside the player.begin() function?
In addition: maybe other calls to player.xxx directly after player.begin() also don't work; I didn't test that. I also didn't try values lower than 100 ms.

I'm using ESP8266 on Wemos D1 mini clone and DY-SV17F

Small delay between track?

Hi !
I'm working on a cosplay project using the DY-SV8F and using this librairy. It's working pretty well, thanks a lot for this great work.

My only issue is that there is a small delay between sounds. I just wonder if it's a board issue or if there is a way to call sounds wi no playing delay? Or maybe it's a controller issue? I'm using nano board with softaerial

Regards!

ESP32 Wrover module issue

I am attempting to use the "DYPlayerESP32.h" module on an ESP32 Wrover but get a compile issue below.

It seems to choke on this line:
DY::Player player(UART_NUM_2, 16, 17);

Any help would be off assistance!

sketch/BT_RC_Trim.ino.cpp.o:(.literal.startup._GLOBAL__sub_I_player+0x4): undefined reference to `DY::Player::Player(uart_port_t, unsigned char, unsigned char)'
sketch/BT_RC_Trim.ino.cpp.o: In function `_GLOBAL__sub_I_player':
Multiple libraries were found for "WiFi.h"
 Used: /Users/xxx/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/WiFi
 Not used: /Applications/Arduino.app/Contents/Java/libraries/WiFi
/Users/xxx/Documents/Arduino/Fartrarri_V1/BT_RC_Trim/BT_RC_Trim.ino:13: undefined reference to `DY::Player::Player(uart_port_t, unsigned char, unsigned char)'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board ESP32 Wrover Module.

PlayRandom always starts from the first song in the folder

Hi,

I am using Arduino Uno R3 with DY-SV5W Voice Playback Module and it seems that PlayRandom option doesn't work as I think it should with this setup.
I've tried to use my own sketch and also just PlayRandom.ino alone to check if this is my mistake or some bug, but no difference.
I've checked the connection between Tx/Rx ports on the boards, but it looks ok and other functions like playSpecified work perfect but not the Random option. The files are named 00001.mp3 to 00010.mp3 and placed on the root SD card. The module is powered by Arduino.

Whenever I power on the Arduino the DY-SV5W module plays the first song then a random track is picked after.
But when I reset Arduino after the DY-SV5W module moves over to the next song (for example 2), then the module starts from this (2) song. Then again the module picks randomly the next song.

I will probably overcome it with the generation of a random number from the 1-10 range and use playSpecified(random_number) but I am curious if this is the right way for PlayRandom function as I didn't find any info in the resources files to explain it.

Any ideas?

Regards
Adam

Impossible to create Player with SoftwareSerial

When trying to execute the SoftwareSerial.h example, I get the following error:

SoftSerial:7:30: error: no matching function for call to 'DY::Player::Player(SoftwareSerial*)'
DY::Player player(&SoftSerial);
^
/home/alex/Documents/RizomeAudio/SoftwareSerial/SoftSerial/SoftSerial.ino:7:30: note: candidates are:
In file included from /home/alex/Documents/RizomeAudio/SoftwareSerial/SoftSerial/SoftSerial.ino:3:0:
/home/alex/snap/arduino/current/Arduino/libraries/dyplayer-main/src/DYPlayerArduino.h:29:5: note: DY::Player::Player()
Player();
^
/home/alex/snap/arduino/current/Arduino/libraries/dyplayer-main/src/DYPlayerArduino.h:29:5: note: candidate expects 0 arguments, 1 provided
/home/alex/snap/arduino/current/Arduino/libraries/dyplayer-main/src/DYPlayerArduino.h:24:9: note: constexpr DY::Player::Player(const DY::Player&)
class Player : public DYPlayer
^
/home/alex/snap/arduino/current/Arduino/libraries/dyplayer-main/src/DYPlayerArduino.h:24:9: note: no known conversion for argument 1 from 'SoftwareSerial*' to 'const DY::Player&'
/home/alex/snap/arduino/current/Arduino/libraries/dyplayer-main/src/DYPlayerArduino.h:24:9: note: constexpr DY::Player::Player(DY::Player&&)
/home/alex/snap/arduino/current/Arduino/libraries/dyplayer-main/src/DYPlayerArduino.h:24:9: note: no known conversion for argument 1 from 'SoftwareSerial*' to 'DY::Player&&'
exit status 1
no matching function for call to 'DY::Player::Player(SoftwareSerial*)'
_

I am out of ideas on how to fix this. Could you please help me?

Thank you in advance.

Alex.

PlaySpecified, getPlayingSound numbers do not match file numbers

Using DY-SV17F soundboard with Arduino Uno.
On the soundboard I've placed files 00001.mp3, 00002.mp3, 00003.mp3 ... up to 00009.mp3

When playing all the sounds using the SoftwareSerial example (included in this library), it displays the sound numbers being played as 1, 3, 5, 7, 11, 13, 15, 17

Similarly for PlaySpecified, I have to use those odd-number representations instead of the actual number.

My workaround for PlaySpecified is to convert the requested sound number:
int convertedSoundNumber = (soundNumber-1) * 2 + 1;
player.playSpecified(convertedSoundNumber);

Checking of the library with the DY-SV5W and DY-SV8F

DYPlayer Issues.pdf
In the attachment I marked with yellow the problematic places.

The library is very interesting, but it needs some corections.

  1. In the library I didn't find the follow commands from the manual:

Query Command
Command: Query current play drive
Command code: AA 0A 00 B4

Setting Commands
Command: Specified song to be interplay
Command code: AA 16 03 Drive S.N.H S.N.L SM

Command: Combination play setting
Command code: AA 1B length SM

Command: End Combination play
Command code: AA 1C 00 C6

  1. In the README.MD, in the table with the modules, the first "DY-HV20T" has to become "DY-SV5W"

  2. I checked the examples of the library with the modules DY-SV5W and DY-SV8F. None of the examples didnt work with my modules.
    My settings were:
    Arduino UNO v.3
    Mode: UART (0-0-1)
    Power supply: 5V
    RX and TX connections through 1K resistors with Arduino's TX and RX.

Am I doing something wrong?

ONE Line protocol support.

Hello! Great library, I am delighted but also frustrated at the same time. Since there is no support for the ONE Line protocol. Can you add it? I really wanted to deal with him and control the player using only one wire.

Issue with assigning MP3's to buttons

I wonder if anyone can help

I have a Dy-sv8f

I've wired pins

IO0 to button 1
IO1 to button 2
IO2 to button 3

I would like 6 in total but if I name one mp3 file 0001.mp3 it plays from pin IO0, if I name a file 0002.mp3 it plays from pin IO1, if I name a file 0004.mp3 it plays from pin IO2, meaning if I rename 0004 to 0003 it won't play, and if I add more mp3 files and name them accordingly in numerical order they won't play, only the first 3 buttons will work but files names are 1, 2 and 4

I'm quite new to this so any help would be greatly appreciated as I'd like pin 0 to play mp3 1, and pin 1 to plays mp3 2 and so on

I just want 6 push buttons to play 6 MP3's 🤷‍♂️

playSpecifiedDevicePath()

Thanks for your awesome work.
I'm using a SV5W connected to an "arduino" pro micro.
I can make most commands work except for playing by path. I've got three files in /root 108.mp3, 109.mp3 and 110.mp3 and 3 directories with numbered files - /101 - /102 - /103. I've tried for a week to get the play by path to work but with no success. Can't even select the root files let alone the ones in folders. Is any one else able to make this work.
Just want to confirm the command is working for someone before spending any more time on it.
Any feedback or tips would be much appreciated. I'm out of ideas.

Arduino IDE 2.X requires different order of includes

In SoftwareSerial.ino, the order of includes needs to be updated.

Current version:
#include <Arduino.h>
#include "DYPlayerArduino.h"
#include <SoftwareSerial.h>

This will get an error on compilation in Arduino IDE:

Compilation error: 'SoftwareSerial' does not name a type; did you mean 'HardwareSerial'?

The sketch needs to be edited so the includes are in this order:
#include <Arduino.h>
#include <SoftwareSerial.h>
#include "DYPlayerArduino.h"

compilation error on AI Thinker ESP32-CAM: undefined reference to `DY::Player::Player(int, unsigned char, unsigned char)'

Hi there,

thank you very much for this great work of implementing the communication protocol.

I just tried to use your library with the AI Thinker ESP32-CAM board and the Espressif Arduino core for the ESP32 in the Arduino IDE 2.1.0 on macOS 12.3.1.

However, a minimal example (simplified from your esp32 example), using only the creation of a player variable with your DY::Player class (see below) already fails with this error message:

/Users/lion/Library/Arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /private/var/folders/q1/jhtqw8ys3kdb_dn83_55fstr0000gn/T/arduino/sketches/0E70F041FA60B7BAC5DE78818341E610/sketch/DY_minimal_example.ino.cpp.o:(.literal.startup._GLOBAL__sub_I_player+0x0): undefined reference to `DY::Player::Player(int, unsigned char, unsigned char)'
/Users/lion/Library/Arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /private/var/folders/q1/jhtqw8ys3kdb_dn83_55fstr0000gn/T/arduino/sketches/0E70F041FA60B7BAC5DE78818341E610/sketch/DY_minimal_example.ino.cpp.o: in function `_GLOBAL__sub_I_player':
/Users/lion/Documents/Arduino/DY_minimal_example/DY_minimal_example.ino:7: undefined reference to `DY::Player::Player(int, unsigned char, unsigned char)'
collect2: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

DY_minimal_example.ino

#include <DYPlayerESP32.h>

DY::Player player(UART_NUM_2, 12, 13);

void setup() {
  player.setVolume(15); // 50% Volume
}

void loop() {
  /* Nothing to do.. */
  delay(5000);
}

I would be super happy if you could give me any hints on what the problem might be.

Cheers!
Lion

WAV file number vs name

I got the player to work on an Uno via a software serial port, so I can use the main serial port for debugging.

I am using playSpecified(int) to play file number X, on the basis of this being simpler than editing strings and my files are all numbered in the root directory anyway.

The problem is it is not associating file #1 with "\00001.WAV". Instead it plays the highest file (00015.WAV). Then #2 plays file "\00001.WAV" and #3 plays 00002.WAV, etc.

Why are they playing out of order like this and is there anything I can do to fix it?

5V to 3.3V Tx/Rx lines

I'm trying to confirm the need for the 1K resistors in the Tx/Rx lines with the DY-SVxxx cards or whether those devices have them installed. I'm using dyplayer, on a PIC with, the code converted to C and compilied with XC8 in Microchips MPLABX IDE. It all compiles well and test code sends the correct byte sequences to the PIC Uart. All good

The PIC (and I assume Arduino) use 5v signal levels. The data sheets for the similar XY-V17B advise the use of the 1k resistors in the lines, those cards don't have any components in the signal lines but the DY-SVxxx modules appear to have conditioning resistors already installed. When I did put a 1k resistor in the PIC Tx to DY_SV5W Rx line the signal at the DY-SV5W end was severly distorted.

In addition if a 1K resistor is put in the PIC/Arduino Rx line wouldn't that reduce the signal level when the PIC/Arduino is expecting to see a 5V Rx signal?

Any clues anybody? I can't get this to work and may have lost one of my DY-SV5W cards in trying to find out?

SoftwareSerial only for AVR?

Hi,
I wanted to use this library with an ESP32 S2 module with the Arduino IDE and I noticed that SoftwareSerial is only available on AVR? Any specific reason for this, given that SoftwareSerial also exists on many other platforms? (Here's the ESP32 one https://www.arduino.cc/reference/en/libraries/espsoftwareserial/ and it works identically to the AVR version)

Removing all the #ifdef AVR will solve this. I'm also a bit sceptical to the use of #ifdef HAVE_HWSERIAL0. On my ESP32 S2 dev board from Unexpected Maker, this is not defined despite the board having hardware Serial1 and Serial2 (ref https://www.youtube.com/watch?v=3sXtVuMhuoc). Removing all the ifdef's actually made this library work much better.

The compiler will complain if a feature is not present, so I would suggest to remove the "cleverness" since it does not work as intended. Thanks for an otherwise great lib!

Add command: Combination play setting

AA 1B length High Byte Low Byte ..... High Byte Low Byte SM

First High Byte Low Byte is the first sound, second High Byte Low Byte is the nth sound.

The manual is not clear on how many sounds may play at the same time but it does mention that the sound files should only be 2 characters long!

It doesn't make much sense to do "End Combination play" separately, so let's I'm adding that to this issue as well.

compilation for Due

When I try to compile this for the Arduino Due, I get these errors:

0_Declarations:203:27: error: no matching function for call to 'DY::Player::Player(USARTClass*)' DY::Player player(&Serial2);

My code is:

In Declarations: DY::Player player(&Serial2); In Setup(): Serial2.begin(9600); player.begin(); player.setVolume(25); player.playSpecified(2);

In the loop() there are more playSpecifieds(x).

SoftwareSerial doesn't work on the Due, but there are 3 hardware serial ports, I used Serial2 successfully when I used the DFPlayer mini, but the DFPlayer mini is not reliable after weeks of investigation and I'd like to try a DY-5V8F module with dyplayer instead; and I need to use the Due as it is buried and integrated within a large robot project I am involved with.

ESP8266 with DY-5V5W mini MP3 player - won't compile

Thank you very much for this fantastic library.

I have downloaded and installed it and am trying to get started with an ESP8266 Wemos D1 (Uno format) board.

I am trying your demo files, with the dyplayeresp32.h library but I get compile errors:
"'DY' does not name a type" and "'player' was not declared in this scope".

The only modification to the files is to point to the dyplayeresp32.h library.

I added the line #define ESP_PLATFORM 1 above the #include for your library. Now it says it cannot locate "driver/uart.h"

Please may you advise where I am going wrong. Probably something basic fundamental.

Fix play_mode_t in readme.md

DYPlayer.h says in line 62:

  typedef enum PlayMode: uint8_t {
    Repeat,       // Play all music in sequence, and repeat.
    RepeatOne,   // Repeat current sound.
    OneOff,      // Play sound file and stop.
    Random,       // Play random sound file.
    RepeatDir,   // Repeat current directory.
    RandomDir,   // Play random sound file in current folder.
    SequenceDir, // Play all sound files in current folder in sequence, and stop.
    Sequence      // Play all sound files on device in sequence, and stop.
  } play_mode_t;

and DYPlayer.h on line 284:

void setCycleMode(play_mode_t mode);

while readme.md says:

void DY::DYPlayer::setCycleMode(..)

Sets the cycle mode. See DY::play_state_t for modes and meaning.

  Type Name Description
param play_mode_t mode mode The cycle mode to set

So I think that DY::play_state_t should be replaced by DY::play_mode_t in readme.md. In addition, play_mode_t should be added to readme.md.
It would make the text "Set how many cycles to play when in cycle modes 0, 1 or 4 (repeat modes)." at setCycleTimes understandable.

P.S. Thanks for sharing this library 😄

WAV files have to be read as MP3

I am using playSecifiedDevicePath().
My files are all WAV format in the root directory of the Sd card.
If I set address as "/00005.WAV" then nothing happens.
If I set address as "/00005.MP3" then the player plays file 00005.WAV.
Ditto other files. if the number is correct then it will play, but the extension has to be MP3.
Is this a feature or a bug?

Add tested boards to the list in README

You all recently made issues on this project, and I've tried to help you out with them. Could you do me a favour and let me know which boards you used and if they worked okay? There is a list in the readme that I would like to update with your experiences so others can find out if their boards should work with this library.

If you could also tell me what boards you were using, i.e. Arduino boards or other (and which type) that would be super helpful!

Thanks a lot for your feedback!

@ntapsis @daPoppa @jvet88 @ghoeffner

Compiling via PlatformIO fails

Trying the example sketch at https://github.com/SnijderC/dyplayer/blob/master/examples/PlayAllSounds/PlayAllSounds.ino compilation on platformio for nodemcuv2 (esp8266) fails in a weird way. Am I doing something the wrong way?
"DYPlayer @ 3.0.0 has been successfully installed!" -> seems like it should be installed...
Would appreciate any help :)

Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/nodemcuv2.html
PLATFORM: Espressif 8266 2.3.3 > NodeMCU 1.0 (ESP-12E Module)
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES:
 - framework-arduinoespressif8266 3.20603.200130 (2.6.3)
 - tool-esptool 1.413.0 (4.13)
 - tool-esptoolpy 1.20800.0 (2.8.0)
 - toolchain-xtensa 2.40802.191122 (4.8.2)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ deep+, Compatibility ~ soft
Looking for DYPlayer library in registry
Found: https://platformio.org/lib/show/6949/DYPlayer
LibraryManager: Installing id=6949 @ ~3
Using cache: C:\Users\German\.platformio\.cache\64\0f25ce840531ee206a1ffe745b719c64
DYPlayer @ 3.0.0 has been successfully installed!
Found 30 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <DYPlayer> 3.0.0
Building in release mode
Compiling .pio\build\nodemcuv2\src\main.cpp.o
Generating LD script .pio\build\nodemcuv2\ld\local.eagle.app.v6.common.ld
Compiling .pio\build\nodemcuv2\lib788\DYPlayer_ID6949\dyplayer\DYPlayer.cpp.o
Compiling .pio\build\nodemcuv2\lib788\DYPlayer_ID6949\dyplayer\DYPlayerArduino.cpp.o
Compiling .pio\build\nodemcuv2\lib788\DYPlayer_ID6949\dyplayer\DYPlayerESP32.cpp.o
Archiving .pio\build\nodemcuv2\libFrameworkArduinoVariant.a
Compiling .pio\build\nodemcuv2\FrameworkArduino\Esp-frag.cpp.o
src\main.cpp:2:29: fatal error: DYPlayerArduino.h: No such file or directory

*************************************************************************
* Looking for DYPlayerArduino.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:DYPlayerArduino.h"
* Web  > https://platformio.org/lib/search?query=header:DYPlayerArduino.h
*
*************************************************************************

 #include "DYPlayerArduino.h"
                             ^
compilation terminated.
Compiling .pio\build\nodemcuv2\FrameworkArduino\Esp-version.cpp.o
Compiling .pio\build\nodemcuv2\FrameworkArduino\Esp.cpp.o
Compiling .pio\build\nodemcuv2\FrameworkArduino\FS.cpp.o
Compiling .pio\build\nodemcuv2\FrameworkArduino\FSnoop.cpp.o
Compiling .pio\build\nodemcuv2\FrameworkArduino\FunctionalInterrupt.cpp.o
*** [.pio\build\nodemcuv2\src\main.cpp.o] Error 1
===================================================================================== [FAILED] Took 3.31 seconds =====================================================================================
The terminal process terminated with exit code: 1

DY::checkPlayState

Hello.
Can I have an example on how to use the player state function in Arduino on the DY-SV5W please?

DY::Player player;

void loop() {
if (player.checkPlayState.Playing()
player.stop();
}

Thanks

Getting back file names from USB disk

Hi SnijderC, thanks for the great work done! I'm a rookie in that and I got lost somewhere and couldn't understand which board can give back list of files present in the U Disk and not only the count of files.
Reading at what you wrote I understood that this is possible but, then, I couldn't find any more mention of this capability.
Thank again for your time!

Commands working fine however can't get valid response

I'm using ESP8266 connected to DY-SV17F. I'm able to send commands to the module but attempting to use the functions checkPlayState / getPlayingSound I'm unable to get a valid response. Seems like I get garbled data. Not sure how to further debug this as I don't have any ideas as to why sending data is working fine but getting back data not.

One_Line-Mode solved

Dear all
Because of missing UART-channels, I wrote and tested the one line operation. Not yet all functions, but thats easy to add with my tested functions.
Because I am a beginner in programming and only in C, I don't know how to commit etc.
So perhaps a better programmer than me can/will do it?

To know about one line:

  • send lowest bit of a byte first
  • timing values written in the table of one-line seams to be not correct. We have to send bits slower. I took 1/3 ms instead of 0,4/1,2 ms. Otherwise it worked not safe.
const byte oneLinePin = 8;

void send(bool bit) {
  if(bit == 0){
    digitalWrite(oneLinePin, HIGH);
    delay(1);
    digitalWrite(oneLinePin, LOW);
    delay(3);
  }

  if(bit == 1){
    digitalWrite(oneLinePin, HIGH);
    delay(3);
    digitalWrite(oneLinePin, LOW);
    delay(1);
  }
}


void setVolume(uint8_t vol){
  if(vol <= 9){
    const byte data = vol;       // volume 0-9
    digitalWrite(oneLinePin, LOW);   // start
    delay(5);
    for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
    digitalWrite(oneLinePin, HIGH);   // stop
    delay(10);
  }

  if(vol > 9 && vol <= 30){                    // volume 0-30
    const byte data = vol/10;       // zehner
    digitalWrite(oneLinePin, LOW);   // start
    delay(5);
    for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
    digitalWrite(oneLinePin, HIGH);   // stop
    delay(10);

    const byte data2 = vol%10;       // einer
    digitalWrite(oneLinePin, LOW);   // start
    delay(5);
    for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data2 & bit);}
    digitalWrite(oneLinePin, HIGH);   // stop
    delay(10);
  }

  if(vol > 30){
    Serial.println("Volume max. 30");
    
    const byte data = 3;              // zehner
    digitalWrite(oneLinePin, LOW);   // start
    delay(5);
    for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
    digitalWrite(oneLinePin, HIGH);   // stop
    delay(10);

    const byte data2 = 1;             // einer
    digitalWrite(oneLinePin, LOW);   // start
    delay(5);
    for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data2 & bit);}
    digitalWrite(oneLinePin, HIGH);   // stop
    delay(10);
  }
  
  const byte data3 = 0x0C;          // set Volume
  digitalWrite(oneLinePin, LOW);    // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data3 & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);
}

void eqSettingDYHV20T(uint8_t eq){       // set Equalizer Mode 0-4: 0 = normal / 1 = Pop / 2 = Rock / 3 = Jazz / 4 = classic
  const byte data = eq;            // equalizer mode
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);

  const byte data2 = 0x0D;         // set EQ
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data2 & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);
}

void loopModeDYHV20T(uint8_t loopMode){       // set Loop Mode 0-7: 0 = play all songs / 1 = repeat the same song / 2 = play one song and stop / 3 = random / 4 = ...
  const byte data = loopMode;      // equalizer mode
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);

  const byte data2 = 0x0E;         // set loop mode
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data2 & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);
}

void playSongDYHV20T(uint8_t song){       // select song and play
  const byte data = song;       // song nbr
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);

  const byte data2 = 0x0B;       // confirm song number
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data2 & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);

  const byte data3 = 0x11;       // play
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data3 & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);
}

void setDeviceSDcard(){
  const byte data = 0x18;       // sd card selection 0x18 = 00011000 ist nötig!
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);
}

void setSystemSleep(){
  const byte data = 0x1B;       // sd card selection 0x18 = 00011000 ist nötig!
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);
}


void stopDYHV20T(){
  const byte data = 0x13;          // stop playing
  digitalWrite(oneLinePin, LOW);   // start
  delay(5);
  for (byte bit = 0x01; bit != 0 ; bit = bit << 1){send(data & bit);}
  digitalWrite(oneLinePin, HIGH);   // stop
  delay(10);
}


void initDYHV20T(){
  pinMode (oneLinePin, OUTPUT);
  digitalWrite(oneLinePin, HIGH);
  delay(100);
  setDeviceSDcard();
  setVolume(20);
}

I hope my code is helpful for someone else.

Greetings
Silvan

ESP32 WROOM 32d: software serial 2 no matching function for call to 'DY::Player::Player(SoftwareSerial*)'

I cant compile the code due error:

no matching function for call to 'DY::Player::Player(SoftwareSerial*)'

this is the preview sketch I used for testing.

`

#include <Arduino.h>
#include "DYPlayerArduino.h"
#include <SoftwareSerial.h>

SoftwareSerial SoftSerial(16, 17); //RX and TX from Arduino
DY::Player player(&SoftSerial); //should connect them to io0 and io1

void setup() {
Serial.begin(9600);
Serial.println("Starting the Player...");

player.begin();
player.setPlayingDevice(DY::Device::Sd); //SD card, USB storage volume is
player.setVolume(30); // 30 is 100% of Volume; with 15 you get 50% Volume
// player.setCycleMode(DY::PlayMode::Repeat); // Play all and repeat.
player.play();
// player.next();

}

void loop() {
// Print the number of the sound that is playing.
Serial.print("Playing Device: ");
Serial.println((int16_t)player.checkPlayState()); //if you receive -1, it's fail
// Print the number of the sound that is playing.
Serial.print("Playing sound: ");
Serial.println((int16_t)player.getPlayingSound());
delay(500);
}
`

@SnijderC

DY-SV8F fonctional with serial com

Hi !

If it can be of any help, I'm working on a project using the DY-SV8F with an arduino Nano and so far the module is responding good to the library. I'm not an expert so I can't say that it's completely tested, but it's functional.

The only thing I've encountered that is bugging me is that I've try to use the Nano Tx/Rx pins but it didn't work. I'm using two other pins instead (D9/D10) and it works great. As I have said, maybe it's just something I'm doing wrong since I'm an hard working amateur...

Also, I'm using the audio jack to send the signal to a small amp the to two speakers. Works great and you can adjust the sound volume by software with the library.

Thanks for the great work !
DY-SV8F

'HardwareSerial*' to 'DY::Player&&' Conversion error (platform.io and arduino ide)

setup:
platform io
esp32

...
DY::Player player(&Serial2);
...

i am using pin 16 and 17 on the board. So i can't use the regular DY::Player player.
when sending a basic play command by UART the module does respond. so it has to do with the configuration of the serial interface in the constructor i think

when compiling the "PlaySoundByNumber.ino" to an esp32, the following error is thrown:

lib\dyplayer-master\src/DYPlayerArduino.h:15:7: note: candidate: DY::Player::Player()
       Player();
       ^
lib\dyplayer-master\src/DYPlayerArduino.h:15:7: note:   candidate expects 0 arguments, 1 provided
lib\dyplayer-master\src/DYPlayerArduino.h:11:9: note: candidate: constexpr DY::Player::Player(const DY::Player&)
   class Player: public DYPlayer {
         ^
lib\dyplayer-master\src/DYPlayerArduino.h:11:9: note:   no known conversion for argument 1 from 'HardwareSerial*' to 'const DY::Player&'
lib\dyplayer-master\src/DYPlayerArduino.h:11:9: note: candidate: constexpr DY::Player::Player(DY::Player&&)
lib\dyplayer-master\src/DYPlayerArduino.h:11:9: note:   no known conversion for argument 1 from 'HardwareSerial*' to 'DY::Player&&'

@IrregularShed @SnijderC @chatelao

ibrary dyplayer-master version 4.0.0 ld returned 1 exit status

I have made an Arduino IDE program for ESP32 by copy of your PlaySounds.cpp program in Exemples/ESP32
But a get an ld error : undefined reference to `DY::Player::Player(uart_port_t, unsigned char, unsigned char)'

I am lost and don't know how to fix it
Thanks for your help


include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_log.h>
#include <driver/uart.h>
#include "DYPlayerESP32.h"

#define TAG "dyplayer"

DY::Player player(UART_NUM_2,(uint8_t) 18, (uint8_t)19);

void setup() {
// put your setup code here, to run once:
// Initialise the player on uart2, pins TX: 18, RX: 19.
// player(UART_NUM_2, (uint8_t)18,(uint8_t) 19);

}

void loop() {
// put your main code here, to run repeatedly:

vTaskDelay(1000 / portTICK_PERIOD_MS);
player.setVolume(15); // 50% Volume

ESP_LOGI(TAG, "Sound count: %u", (uint8_t) player.getSoundCount());
ESP_LOGI(TAG, "Player device %u", (uint8_t) player.getDeviceOnline());
while (true) {
// Change to next sound after 5 seconds (non-blocking call so will cut off
// currently playing sound if any).
for (uint8_t i = 1; i < player.getSoundCount(); i++) {
player.playSpecified(i);
ESP_LOGI(TAG, "Playing song %d", player.getPlayingSound());
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
}


Linking everything together...

**C:\Users\Dan\AppData\Local\Temp\arduino_build_877896\sketch\sketch_oct02a.ino.cpp.o:(.literal.startup._GLOBAL__sub_I_player+0x4): undefined reference to `DY::Player::Player(uart_port_t, unsigned char, unsigned char)'

C:\Users\Dan\AppData\Local\Temp\arduino_build_877896\sketch\sketch_oct02a.ino.cpp.o: In function `_GLOBAL__sub_I_player':

C:\Users\Dan\Documents\Arduino\sketch_oct02a/sketch_oct02a.ino:9: undefined reference to `DY::Player::Player(uart_port_t, unsigned char, unsigned char)'

collect2.exe: error: ld returned 1 exit status**

Use of library dyplayer-master version 4.0.0 dans le dossier: C:\Users\Dan\Documents\Arduino\libraries\dyplayer-master

exit status 1

Player::checkDevice returns invalid numbers

aa 09 checks which storage device is online but weird that's weird because it only returns 1 number and:

  • it's not one of the listed options in the manual.
  • there could be more than one online.

My DY-SV17F returns 04, but that is not on the list of valid return values: USB:00, SD:01, FLASH:02, I expected 2.
It's probably not a bitmask value because my board only has 1 storage device.

Update readme on odd path requirements and hidden files

Paths for combination play seem to have to be required to be named ZH/, as opposed to DY/ as in the manual of the modules.

Files played by number are not corresponding to the number in the file name that, while it is suggested in the manual to number the files. It seems to be that the first file found on the drive is what is played when you ask it to play 00001, even if that is a file in a .Trash directory.

SoftwareSerial does not name a type

Hi there,

Thanks for your effort and sharing of the library.

Although i managed to connect and play sound, I am trying to use the software serial, but i can not get passed the compilation. The error message states :

SoftwareSerial:6:1: error: 'SoftwareSerial' does not name a type; did you mean 'HardwareSerial'?
SoftwareSerial SoftSerial(10, 11);
^~~~~~~~~~~~~~
HardwareSerial
SoftwareSerial:7:20: error: 'SoftSerial' was not declared in this scope
DY::Player player(&SoftSerial);
^~~~~~~~~~
C:\temp\SoftwareSerial.ino:7:20: note: suggested alternative: 'Serial'
DY::Player player(&SoftSerial);
^~~~~~~~~~
Serial
exit status 1
'SoftwareSerial' does not name a type; did you mean 'HardwareSerial'?

Any ideas how to fix it ? Kindly check the softserial example.

Thank you very much

Regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.