MicroController Recommendation for Podcast Player

One thing I am not sure of is how to make multiple serial writes to the player. e.g. In this code for button7.pressed() it only responds to the first write “AT+PLAY=LAST\r\n”. I’m assuming this has something to do with the way a serial connection works. Do I need to do something before the second line “DFPlayer.write(“AT+TIME=+100”);”. Thanks for everyones help so far.

1 Like

I think that you may need to either put in a sleep for a second or so between commands OR do a read back from the device looking for it to say “OK\r\n” thats 4 characters O, K, Return, Newline
Some of the commands generate an OK response, before it will accept another command

This is some python test code I did in my Borg project - note the sleep commands

from machine import Pin, UART
from PiicoDev_Unified import sleep_ms
import random

uart - UART(0, baudrate=115200, tx=Pin(12), rx=Pin(13))

durations = [0, 17, 10, 2, 2, 6, 2, 3 ]    # runtime + 1 second, no track 0

uart.write("AT\r\n")        # wakeup
sleep_ms(100)
uart.write("AT+AMP=ON\r\n")
sleep_ms(100)
uart.write("AT+PLAYMODE=3\r\n")    # single track mode

# play 10 random noises
for i in range(10):
    play = random.randint(1,7)          # pick a track 1 - 7 
    print("playing track ", play)       # show me
    c_num = "% s" % play                #   / itoa()
    s = "AT+PLAYNUM=" + c_num + "\r\n"  #  / build DFRobot command
    uart.write(s)                       # / and send it
    sleep_ms(durations[play]*1000)      # zzzzz - this one is to allow track to complete

Murray

3 Likes

Thanks Murray, I thought I’d tried a short delay. Anyway I have changed the baud rate to 9600 as I have seen somewhere people saying the default is problematic and also added a 100ms delay between writes. It seems to be behaving now. Hooray!!

I’ll get back into it later today, need to go for a walk now!

2 Likes

Okay… Solved with work around.

So the AT commands had the same problem when I tried them. The problem being that the commands to fast forward (fastForward) or position the playhead (setPlayHead) don’t work if the seconds used are bigger than 255! Even though they are supposed to be uint16_t.

So I went back to using the DFRobot_DF1201S library as I had already coded most of what I wanted.
My solution was to use the fast forward function in 200 second jumps until the playhead reached the required time. It now works properly.
Here is the function:

void setTimeUsingFF(int startAt) {
  //Doing this because of a bug in software that doesn't allow numbers bigger than 255
  //Past End of file?
  Serial.print("File size: ");
  Serial.println(DFPlayer.getTotalTime());
  if (startAt > DFPlayer.getTotalTime()) {
    Serial.println("Past end of file.");
    currentFileNumber++;
    DFPlayer.next();
    currentTimeIndex = 0;
    return;
  }
  //Potentially before start of file?
  if (startAt < 200) return;
  //Move play head to correct place - Using shifts of 200 as it is less than 255
  while (DFPlayer.getCurTime() < startAt - 200) {
    DFPlayer.fastForward(200);
  }
}

I also changed the second button from reseting file and time indices to 0 to fast forward to the next 10 minute mark in the file.

I am happy with it now! Thanks everyone for your suggestions and help.

2 Likes

Full code here if anyone is interested:
https://github.com/ExpensiveNotes/Podcast-Player-With-Auto-Timer/tree/main

3 Likes

Hi John,
Congrats on completing your project and a big thanks for sharing.
Hopefully you can sleep a little easier now that it is done.

4 Likes

Congratz! :radio: :balloon:

2 Likes

Thanks Jack and Pixmusix. All the best.

2 Likes

You are very welcome.
Happy making!

2 Likes

In action without having to wait 10 minutes… :wink:
https://youtube.com/shorts/6UoI7460ZME

1 Like

Amazing work John

2 Likes

Having had a looksee at the chips on the module ( a 32-bit RISC CPU, an Audio amp, and a flash memory) I reckon that the issue with the 255 value limit is probably in their ‘embedded code’ in the flash memory that turns the processor into something that understands AT commands and play music files.
I am guessing that the manufacturer has ‘reserved’ a block of the flash for their operating codebase, while the rest is for user music files.

At some point in the code there is a (for want of a better phrase) ASCII-to-integer function that for some reason truncates the integer value and only returns the low byte (8 bits that give the range 0-255).

It is a good solution that you have to step forward in 200 second jumps, but it would be ‘nicer’ if you could do the jump as per the implied range in the doco.

Murray

3 Likes

This type of problem is very typical for this type of device. The code base they have all used was originally developed for use with a small number of small files - safety messages in a factory, passenger alerts in transport, promotional announcements for a broadcaster, or random sounds from a toy. It was never intended for a large number of files or for long songs (there wasn’t the memory capacity anyway). Enhancements to make it usable as a generic MP3 player were added over the years but it seems the original code was never re-done from scratch. This is evident in the lack of a proper confirmation mechanism, requiring arbitrary pauses between commands, difficulty in handling higher baud rates, despite now running on a fast MCU, and the lack of any support for a file system other than sequential file numbers. All these problems can be overcome and the device can be a competent player for longer MP3 files, but it takes some effort to work around the quirks.

4 Likes

Makes sense, thanks for your thoughts. It was very frustrating for a while but I am happy to hack a solution.

2 Likes

One of the things I that I was interested in was making it as low power as possible, mainly to not waste energy.
I know you can put the nano into sleep mode to save power but I guess the 3W the amp uses in the DFPlayer would be the main power use.
If it used 3W all the time then that would be 3x24x365/1000 kWh ~ 26 KWh for a year. While this isn’t a massive amount as an upper limit (~$10) it would be nice to reduce it as much as possible, if the effort is worth it.

I already unplug it in the morning so that reduces this figure by ⅓.

Any thoughts?

2 Likes

Hi John,

According to the schematic, it’s a PAM8403, a class D chip, so it’s not like it’s an A or AB with high quiescent current. The datasheet reckons it’s in the mA:

2 Likes

Thanks James. Guess I won’t bother then.

2 Likes

Hi John
Good you got some sort of work around. But

This is not quite what I meant. I was questioning the fact that the term “uint16_t” did not appear in colour as if it were somehow incorrect. I suggested that something could have (and quite often does) happened during a copy and paste operation and deleting and manually retyping the affected lines of code might possibly fix it.

I note that when I had a look at your sketch in the link you provided there are a couple of times this term comes up which seem to be unrelated to the problem you were having. These occur in lines 136 and 185 and the term “uint16_t” DOES appear in colour.

Your fix appears to do the job at the moment but is it a real solution?
Cheers Bob

Thanks Robert but every uint16_t is in the correct colour in my Ardunio IDE.

1 Like

Hi John
In your sketch you posted 4 days ago this term was black, all the other terms were blue. I think this was a test sketch you used to check the timing with the print functions. This is the sketch I was referring to that could have developed a funny if you copied and pasted which has happened several times in the past.
Cheers Bob