DY-player library: How to get the play state read into a variable

Hi friends,
I have a quick arduino programming question about the <DYPlayerArduino.h> library:
As I do not have big experience in C-programming and cannot find a complete guide for the DY-player module I need to ask here if somebody can give me just the right syntax for how to get the play State of the player read into a variable in my sketch.
Thank you.

If you think "teach me to write programs for a specific module" is a quick question, then a quick answer is, "Yes. I taught myself, it was well worth the struggle."

The library you installed has an examples folder. IDE >> FILES >> EXAMPLES >> DY-xyz >> something.ino. Try all the examples, and you may find the answer on your own. A few "DY player" libraries exist, so knowing exactly the one you have will be up to you posting that information...

What sketch?

All the code that goes into anything you build is on your machine.

Often it is also on github.

I searched for the library header name and then looked at the code.

Here's the quick answer.


    /**
     * Check the current play state can, be called at any time.
     * @return Play status: A [`DY::PlayState`](#typedef-enum-class-dyplay_state_t),
     *         e.g DY::PlayMode::Stopped, DY::PlayMode::Playing, etc.
     */
    play_state_t checkPlayState();

   

which seems to say you can call the checkPlayState() method to, um, check the play state.

Read further to see what values it returns and what they mean.

a7

which specific player are you using? give a link?

if you are using a player with a BUSY output you can read the state of the pin, e.g.

 // check if player Busy status has changed
pinMode(BUSY, INPUT_PULLUP);  // GPIO 4 is Busy signal  
......
if (digitalRead(BUSY) != busy) {   // if BUSY has changed
    if ((busy = digitalRead(BUSY)))
      Serial.println("busy " + String(busy) + " NOT playing");
    else
      Serial.println("busy " + String(busy) + " playing");
    ;

Thanks for your answer,
all examples which I found are showing just how to make the DY-player do something like Music.playSpecified(number); and this works great. What I need is how to write the code statement which returns the play status if it is playing or stopped.
my example sketch is this one:


#include <HardwareSerial.h>
#include <DYPlayerArduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <Adafruit_SSD1306.h>

HardwareSerial SerialPort1(1);  // use UART1
//HardwareSerial SerialPort2(2);  // use UART2

DY::Player Music(&SerialPort1);

//Adafruit_SSD1306 oled = Adafruit_SSD1306(128, 64, &Wire, -1); 
Adafruit_SH1106G oled = Adafruit_SH1106G(128, 64, &Wire, -1); // select Oled 128x64

#define Btn 0
#define Sel 1

int track;
int state;

void setup() 
{
  pinMode(Btn,INPUT_PULLUP);
  pinMode(Sel,INPUT_PULLUP);
  
   //oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // for SSD1306 only
   oled.begin(0x3C);
   oled.setTextSize(1);
   oled.setTextColor(SH110X_WHITE);
   oled.clearDisplay();
   oled.display();  

  SerialPort1.begin(9600, SERIAL_8N1, 21, 20);  // Serielle Schnittstelle 1 für Audio an
  Music.begin();
  //Music.setCycleMode(DY::PlayMode::OneOff);
  Music.setCycleMode(DY::PlayMode::RepeatOne);
  Music.setCycleTimes(3);
  //Music.setCycleMode(false);
  Music.setVolume(30);
}

void loop() 
{
  //oled.clearDisplay();
  oled.setCursor(0,10);
  oled.println("select track > ");
  oled.display();
  
  while(digitalRead(Btn)&& digitalRead(Sel)) {;}
  if(!digitalRead(Sel)) 
  {
    track++; 
    if(track>8) {track=1;}
  oled.clearDisplay();  
  oled.setCursor(0,10);
  oled.println("select track > ");
  oled.println();
  oled.print("then press Button");    
  oled.setCursor(100,10);
  oled.print(track);
  oled.display();
  delay(300);  
  }

  if(!digitalRead(Btn))
  {
  oled.clearDisplay();
  oled.setCursor(0,10);
  oled.print("now playing...");
  oled.println();
  state = Music.play_state_t (DY::PlayMode::Playing);
  oled.print(Music.getPlayState());
  oled.display();  
  Music.playSpecified(track);  // Musik abspielen
  delay(1000);
  oled.clearDisplay();
  } 
}

You don't seem to know enough to interpret my answer.

This

state = Music.play_state_t (DY::PlayMode::Playing);

looks like nonsense to me. I will assume it is where you want to determine the play state.

This is what I was aiming you towards

  state = Music.checkPlayState();

The return value is of type play_state_t. Interpretation of that value can inform your decisions about what action to take.

a7

That line might be unnecessary and even problematic. Which Arduino board are you using? Nearly all boards with multiple hardware UARTs have them pre-assigned to Serial1, Serial2, etc. So you don't want to instantiate a new HardwareSerial object on an already-assigned UART.

yes you are right, this is nonsense and you are right, I don´t understand enough about classes, members, methods, objects in order to build the right statement. I just want to get the right code statement without studying informatics :wink: is this possible?

Ppl accomplish things with an astonishing lack of knowledge all the time.

Here, however, you are talking about some fairly basic things.

Even for a simple project you'll need to be able to muddle your way through reading other ppl's code, and maybe even code for a library.

Sadly, many libraries do not come with very good documentation and the examples often do not go into every corner of what the author has provided.

If you promise to spend a little time learning just a little bit, no need to get a degree in informatics, whatever that means, I will say that the method I located for you will return a coded value.

This is what the returned value is and means, clipped form source code that is on your computer. I don't want to seem rude, but this is as much fish as I will give you, time to learn how to fish:

  /**
   * The current module play state.
   */
  typedef enum class PlayState : int8_t
  {
    Fail = -1, // UART Failure, can be a connection or a CRC problem.
    Stopped = 0,
    Playing = 1,
    Paused = 2
  } play_state_t;

Think about almost anything else you didn't know until you knew. By analogy, you've placed yourself behind the wheel of an automobile going 42 kilometers per hour without knowing what all those pedals on the floor can do.

This is no different. Spend seven minutes looking at seven websites you can find by googling

arduino programmer for beginners

One of them might be something you could spend more time with, it's a matter of learning style and taste. All of them will let you learn something. Less than an hour from when you started you will def have learned something.

Ppl like the iced coffee guy. I prefer the breezy young lady who seems to be able to make learning anything lotsa fun. You will find your match; stick with any organized exposition of this material and every minute you spend will return its value many times.

a7

Thank you very much for your advices. I just want to make everything clear about me
I am 62 years old, my programming experience comes from process automation systems like Siemens S5 and S7 and some UNIX based systems containing basic Oracle and today it is kind of vintage. I never switched to deeper C, C++ programming. I started playing around with Arduino and built some nice clocks and other simple projects. All what I made working I did by finding examples which contain the code pieces I needed and modified them for my purposes.
Actually I don´t want to study 7 hours on 7 webpages which cost me 7 days to find exactly what I need to make something working on my small projects. For this reason I am here to ask the C, C++ experts to built a statement for me which I can use with my Arduino hardware and project. Until now I found a lot of help for the issues I was facing and I am deeply geatful.
Thanks a lot.

I said seven minutes on seven google hits and did the maths that let me say that would be less than an hour.

And considering your youth and your claim of experience grappling with stuff like this, I will let you find your own level of comfort as far programming the Arduino is concerned. As I said, ppl accomplish things w/o knowing much at all.

Here's something that might help: Although C++ is the official language of the Arduino, many of us would never claim to be experts in C++, and TBH you can get along perfectly well with C, even late 20th century level C, and a modicum of common sense. I wouldn't even claim to be an expert in C, but I can read and think and for the most part have succeeded to the degree I have based on pattern matching to an alarming extent.

C is a tiny language and a satisfactory ability to read it can be acquired fairly rapidly.

Good luck.

a7

Sorry but ´til now I cannot find anything that might help me. I didn´t want to get into a philosophic discussion about learning programming. If you like to help me with my inquiry then just put me all nessesary letters and signs into the right order so that the compiler does not argue and I can get the playstatus of my DYplayer. Maybe I can apply this also for receiving other status information from the DY module.
I really feel ashamed and sorry about my ignorance regarding C++ structure and I would highly appreciate if you could help me in the way I like.
Thanks, thanks, thanks :flushed:

Get over it. There is no need for shame or apology. We were all stating from nowhere on this.

You posted code including these lines

  state = Music.play_state_t (DY::PlayMode::Playing);
  oled.print(Music.getPlayState());

I don't see any method getPlayState() in the library. In the preceding line you do place a meaningless value into the variable state, and then do nothing with it.

Did it compile?


All I can do is guess. I hope this is enough letters in the correct order

// call the checkPlayState method on the Music object
  state = Music.checkPlayState();

// see if it sez we are paused, and then do something about that
  if (state == Paused) {

// code here for the circumstance in which playing is paused.
  }

An earlier reply of mine lists the valid constants that state might be compared to in order to inform a test for the current state of the player and do something because.

a7

Thank you a lot for your support,
ok, now I included the typedef which you suggested and declared the state variable as int8_t
here the sketch again:


#include <HardwareSerial.h>
#include <DYPlayerArduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <Adafruit_SSD1306.h>

DY::Player Music(&Serial);

//Adafruit_SSD1306 oled = Adafruit_SSD1306(128, 64, &Wire, -1); 
Adafruit_SH1106G oled = Adafruit_SH1106G(128, 64, &Wire, -1); // select Oled 128x64

#define Btn 0
#define Sel 1

int track;

typedef enum class PlayState : int8_t
  {
    Fail = -1, // UART Failure, can be a connection or a CRC problem.
    Stopped = 0,
    Playing = 1,
    Paused = 2
  } play_state_t;

  int8_t state;

void setup() 
{
  pinMode(Btn,INPUT_PULLUP);
  pinMode(Sel,INPUT_PULLUP);
  
   //oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // for SSD1306 only
   oled.begin(0x3C);
   oled.setTextSize(1);
   oled.setTextColor(SH110X_WHITE);
   oled.clearDisplay();
   oled.display();  

  Serial.begin(9600, SERIAL_8N1, 21, 20);  // Serielle Schnittstelle 1 für Audio an

  Music.begin();
  //Music.setCycleMode(DY::PlayMode::OneOff);
  Music.setCycleMode(DY::PlayMode::RepeatOne);
  Music.setCycleTimes(3);
  //Music.setCycleMode(false);
  Music.setVolume(30);
}

void loop() 
{
  //oled.clearDisplay();
  oled.setCursor(0,10);
  oled.println("select track > ");
  oled.display();
  
  while(digitalRead(Btn)&& digitalRead(Sel)) {;}
  if(!digitalRead(Sel)) 
  {
    track++; 
    if(track>8) {track=1;}
  oled.clearDisplay();  
  oled.setCursor(0,10);
  oled.println("select track > ");
  oled.println();
  oled.print("then press Button");    
  oled.setCursor(100,10);
  oled.print(track);
  oled.display();
  delay(300);  
  }

  if(!digitalRead(Btn))
  {
  oled.clearDisplay();
  oled.setCursor(0,10);
  oled.print("now playing...");
  oled.println();
  state = Music.checkPlayState();
  //oled.print(Music.checkPlayState());
  oled.display();  
  Music.playSpecified(track);  // Musik abspielen
  delay(1000);
  oled.clearDisplay();
  } 
}

what the compiler claims now is :
DYPlayer-Test:108:32: error: cannot convert 'DY::play_state_t' {aka 'DY::PlayState'} to 'int8_t' {aka 'signed char'} in assignment

state = Music.checkPlayState();

Get rid of this:

When you want to know if playing:

  auto state = Music.checkPlayState();
  if (state == DY::PlayState::Playing) {
    // Do stuff here for playing state
  } else {
    // Do stuff here for NOT playing state
  }

EDIT:
If you want state to be a global variable like in your previous code, then replace this:

typedef enum class PlayState : int8_t
  {
    Fail = -1, // UART Failure, can be a connection or a CRC problem.
    Stopped = 0,
    Playing = 1,
    Paused = 2
  } play_state_t;

  int8_t state;

With:
DY::PlayState state;

Then:

  state = Music.checkPlayState();
  if (state == DY::PlayState::Playing) {
    // Do stuff here for playing state
  } else {
    // Do stuff here for NOT playing state
  }
1 Like

Very creative, perhaps too much so!

I was quoting code that would have automatically been part of your effort. In any case @gfvalvo has set you much straighter and faster than could I, let us hope it is more downhill from here.

TBH I thought the compiler would be more forgiving about the casual use of what are ultimately just small numbers. I blame that on the freewheeling habits I developed in my own youth.

a7

ok, I got the compiler happy but on the program the PlayState never changes neither playing nor on silence.
What is the "Music.checkPlayState()" statement supposed to return and to write into the state variable ? Can I get this visible on my oled display ? If I include a command like "oled.print(state);" the compiler vomits again.

You can use if() statements (just expand the code I already posted) to test the various return values and print something appropriate on the OLED for each case:

Or, you can use a switch() statement.

Here are the references:
https://docs.arduino.cc/language-reference/en/structure/control-structure/if/
https://www.arduino.cc/reference/cs/language/structure/control-structure/switchcase/

ok, with the if... and switch... statements I am familiar.
what I mean, with the following arrangement I cannot get a satisfying result what means the return value is never the playing option.

  
  while(digitalRead(Btn)&& digitalRead(Sel)) 
   { 
     state =  Music.checkPlayState();
     oled.clearDisplay();
     oled.setCursor(0,20);
     if( state == DY::PlayState::Playing) { oled.print("playing");oled.display();} else {oled.print("stopped");oled.display();}
   }

Rule # it doesn't have a number, but in order to see what you did, and see why it does not give joy, you must post the new sketch in its entirety.

Either a sketch that does not compile, in which case the error messages would need to also be posted or...

... the sketch that does compile but when executed does something you don't want it to do or doesn't do something you do want it to, along with a reminder of what it is you are aiming for. or at least a note about where on the thread we might find one.

Charming. Just say it throws an error, and as I said, posting the red ink here in code tags (use the <CODE/> button and paste where is tells you to) would be helpful.

I can guess, again. So try

  state = Music.checkPlayState();
  if (state == DY::PlayState::Playing) {
    oled.setCursor(0,10);
    oled.println("playing");
  } else {
    oled.setCursor(0,10);
    oled.println("not playing");
  }

And I hope it is obvious that you can make that show up wherever you want by changing the setCursor() arguments.

And it looks like you'll need to run across

  oled.display();

and

  delay(1000); 

to see it on you display.

a7