Vmusic2 cockrill

Rampz

Well-known member
Or of course you could create a simple PICaxe lookup table to relate a volume control level to each track.
Thank you Alan, I have read several examples of tables but can't get my head around how to implement it in my code? I would say increasing the volume by an amount of steps above the volume set is the best way for what I'm doing. My master volume if you like is written to eeprom I wouldn't want each table change to get written to eeprom too, just changes as they do at the moment.
Code:
#picaxe 14m2
#no_data
#terminal 4800

Symbol TX = B.4
Symbol RX = C.3
Symbol BUSY_PIN = pinC.2
Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol cmd = b0
Symbol arg = w1 ; b3:b2
Symbol arg.lsb = b2
Symbol arg.msb = b3
Symbol varA = w2
symbol varB = w3
Symbol BTN = PinB.5 'volume up
Symbol BTN1 = PinB.3 'volume down
Symbol BTN2 = PinB.2 'next song
Symbol AXE134pin = C.1 'connected to screen input
Symbol Pressed = 1

init:


High TX ; set TX pin high for idle high serial
SerTxd("Get ready to Rock", CR, LF )
Pause 3000



'varB = 8 'initial volume setting
'cmd = 0x06 : arg = varB : Gosub Send
'SerTxd("init volume set to ", #varB, CR, LF ) ' added to display its value at this time
'pause 2000 ' added pause to see if it helped

read 0,WORD varB 'added to read previous volume from eeprom position 0
'SerTxd("eeprom volume set to ", #varB, CR, LF )

         SEROUT AXE134pin , N2400_4 , ( 254 , 128 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Programming by Rampz")     ; Send to AXE134

SerTxd("Selected USB", CR, LF )
cmd = $09 : arg = $0001 : Gosub Send '0001 for usb, 0002 for sd card
pause 4000

cmd = 0x07 : arg = 0002 : Gosub Send ' EQ rock
SerTxd("Equlizer set to rock", CR, LF )
pause 1000

         SEROUT AXE134pin , N2400_4 , ( 254 , 192 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Equ to Rock, Set USB")     ; Send to AXE134

cmd = 0x06 : arg = varB : Gosub Send   'Volume set at 8 of 30, altered to read varB
    SerTxd("volume set to ", #varB, CR, LF ) 'display volume setting from eeprom hopefully
    
      SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
        SEROUT AXE134pin , N2400_4 , ( "Volume=" , #VarB ," " )     ; Send to AXE134

Pause 1000
Gosub playsong


playsong:
    For varA = 1 To 114    
    SerTxd("Playing song 000", #varA, CR, LF )
    
      SEROUT AXE134pin , N2400_4 , ( 254 , 215 ); Position the cursor (at start of top line)128 top line
        SEROUT AXE134pin , N2400_4 , ( "Playing Song " , #VarA ,"  " )     ; Send to AXE134
    
    cmd = $12 : arg = varA : Gosub Send
    Pause 1000
    Do While BUSY_PIN = 0 
    Pause 100 
    IF BTN = Pressed then
    pause 50  
    Gosub volumeup
    endif
    IF BTN1 = Pressed then 
    pause 50 
    Gosub volumedown
    endif
    IF BTN2 = Pressed then 
    pause 50 
    Gosub playnext
    endif
    Loop
    next
    Pause 1000
do: Gosub playsong: loop 'altered was (return)

Send:
SetFreq BAUD_FREQ
Pause 10
SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
SetFreq MDEFAULT
Return

volumeup:
       varB = VarB + 1 max 30
       write 0,WORD varB 'write value to eeprom positiom 0
          SEROUT AXE134pin , N2400_4 , ( 254 , 154 ) ; Position the cursor (at start of top line)128 top line
            SEROUT AXE134pin , N2400_4 , ( "Volume=" , #VarB ," " )     ; Send to AXE134
       SerTxd("volume ", #varB, CR, LF )
       cmd = $04 : arg = $0000 : Gosub Send
return

Volumedown:
        varB = VarB min 1 - 1
        write 0,WORD varB 'write value to eeprom position 0
           SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Volume=" , #VarB ," " )     ; Send to AXE134
        SerTxd("volume ", #varB, CR, LF )
        cmd = $05 : arg = $0000 : Gosub Send
return

playnext:
       varA = varA + 1
       
       SEROUT AXE134pin , N2400_4 , ( 254 , 215 ); Position the cursor (at start of top line)128 top line
         SEROUT AXE134pin , N2400_4 , ( "Playing Song " , #VarA ," " )     ; Send to AXE134
      
       SerTxd("Playing song 000", #varA, CR, LF )
       cmd = $01 : arg = $0000 : Gosub Send
       pause 500 ;;;;; added to stop double song issue, but slowed skipping song down
return

'cmd = 0x08 : arg = 0001 : Gosub Send 'repeatably play song 0001
'cmd = $12 : arg = 0001 : Gosub Send 'play song 0001
 
Last edited:

Jeff Haas

Senior Member
Try this one:

It's open source software that will normalize the volume of all your MP3s. It's much easier to fix it this way than trying to tweak the playback.
 

AllyCat

Senior Member
Hi,

Yes, IMHO normalising the MP3s is a much better solution, but anyway the varA and varB could/should be renamed, e.g. track and vol respectively and set as byte variables (if they're not byte values, then there are other issues to consider).

I don't know how you would plan to measure (other than as above) the amount of gain change required, but in principle the "lookup" for the gain (change) could be of the form : READ track , volchange , or maybe for the 14M2 and above : READTABLE track , volchange . Then new variables can be used for : setvol = vol + volchange MAX 30 , etc..

Cheers, Alan.
 

tmfkam

Senior Member
Try this one:

It's open source software that will normalize the volume of all your MP3s. It's much easier to fix it this way than trying to tweak the playback.
That's what I used on my Mac, and on Windows now. If it is set to change the file volume (as opposed to just including a "note" in the file headers) the volume stays consistent across multiple devices and operating systems.
 

tmfkam

Senior Member
Hi,

The MP3 file format is quite complex so you probably need to use an "App" of some kind. The most common "free" software is "Audacity", but I haven't used it much myself, and couldn't see an "Automatic Gain Control" mode as such. Personally, I've used a freeware program called "MP3DirectCut" for many, many (20+) years which does have an option to : Edit > Normalise , that quickly sets the peak amplitude to just below clipping (or any other value you select). Only for MP3 files and I recall it may need a few other software resources to be installed, but IMHO worth a try if you find Audacity too overwhelming.

Or of course you could create a simple PICaxe lookup table to relate a volume control level to each track.

Cheers, Alan.
Audacity does have a normalise function - possibly called Amplify - a target db level can be set, something like 89db is what I aim for. The advantage of mp3Gain is that it can be batch controlled to process entire folders of music, setting them all to a target volume level, up or down. I never figured out how to do that with Audacity.
 

Rampz

Well-known member
Thank you Everyone
MP3Gain seems to do the job, i have converted all my tracks and will try later

One other issue, i'm thinking, in my code i specify the number of tracks as below

Code:
playsong:
    For Track = 1 To 114
    SerTxd("Playing song 000", #Track, CR, LF )
Is there a better way to arrive at the number of tracks in the file, currently i will have to alter my code each time i think, i see from the data sheet for the DFplayer mini that it has a command that reads the number of tracks? Could this data then be used instead of my coded number?

Edit

I can see from the DFplayer Mini pdf that under section 2 ref Query the system parameters, 0x47 Query the total number of USB files, i think i need to use SERIN? Will i need say a "Gosub receive"?

Code:
Symbol RX = C.3
Symbol TrackNum = w4

serin RX,N2400,( $7E, $FF, $06, $47, $00, $00, $00, $FE, $B4, $EF ) 'not going well here, trying to i guess send a command and get a
                                                                                                         responce and write it into Tracknum as a number
serin RX,N2400, #TrackNum

playsong:
    For Track = 1 To TrackNum
    SerTxd("Playing song 000", #Track, CR, LF )
    SerTxd("number of files ", #TrackNum, CR, LF ) 'added to read quantity of files
but anyway the varA and varB could/should be renamed, e.g. track and vol respectively and set as byte variables (if they're not byte values, then there are other issues to consider).
Edit

Thank you Alan i have altered my symbols to make them easier to understand, i seems to have sorted the Volume to read and write to eeprom as a byte rather than a word
 
Last edited:

Rampz

Well-known member
Ok so i have tried to set up a "receive" for receiving quantity of tracks from USB, i added some code from a Hippy from a post by 1968neil and the below now reads the number of tracks correctly and appears to work, can anyone see any issues?

Code:
#picaxe 14m2
#no_data
#terminal 4800

Symbol TX = B.4
Symbol RX = C.3
Symbol BUSY_PIN = pinC.2
Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol cmd = b0
Symbol arg = w1 ; b3:b2
Symbol arg.lsb = b2
Symbol arg.msb = b3
Symbol Track = w2
symbol Vol = b6
Symbol BTN = PinB.5 'volume up
Symbol BTN1 = PinB.3 'volume down
Symbol BTN2 = PinB.2 'next song
Symbol AXE134pin = C.1 'connected to screen input
Symbol Pressed = 1
symbol TrackNum = W4

init:


High TX ; set TX pin high for idle high serial
SerTxd("Get ready to Rock", CR, LF )
Pause 3000



'varB = 8 'initial volume setting
'cmd = 0x06 : arg = varB : Gosub Send
'SerTxd("init volume set to ", #varB, CR, LF ) ' added to display its value at this time
'pause 2000 ' added pause to see if it helped

read 0, Vol 'added to read previous volume from eeprom position 0
'SerTxd("eeprom volume set to ", #varB, CR, LF )

         SEROUT AXE134pin , N2400_4 , ( 254 , 128 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Programming by Rampz")     ; Send to AXE134

SerTxd("Selected USB", CR, LF )
cmd = $09 : arg = $0001 : Gosub Send '0001 for usb, 0002 for sd card
pause 2000


cmd = $47
Gosub Receive
SerTxd( "trackNum=", #arg, CR, LF )


pause 1000

cmd = 0x07 : arg = $0002 : Gosub Send ' EQ rock
SerTxd("Equlizer set to rock", CR, LF )
pause 1000

         SEROUT AXE134pin , N2400_4 , ( 254 , 192 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Equ to Rock, Set USB")     ; Send to AXE134

    cmd = 0x06 : arg = Vol : Gosub Send   'Volume set at 8 of 30, altered to read Vol

    SerTxd("volume set to ", #Vol, CR, LF ) 'display volume setting from eeprom hopefully
   
      SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
        SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134

Pause 1000
Gosub playsong


playsong:
    For Track = 1 To TrackNum   
    SerTxd("Playing song 000", #Track, CR, LF )
   
      SEROUT AXE134pin , N2400_4 , ( 254 , 215 ); Position the cursor (at start of top line)128 top line
        SEROUT AXE134pin , N2400_4 , ( "Playing Song " , #Track ,"  " )     ; Send to AXE134
   
    cmd = $12 : arg = Track : Gosub Send
    Pause 1000
    Do While BUSY_PIN = 0
    Pause 100
    IF BTN = Pressed then
    pause 50 
    Gosub volumeup
    endif
    IF BTN1 = Pressed then
    pause 50
    Gosub volumedown
    endif
    IF BTN2 = Pressed then
    pause 50
    Gosub playnext
    endif
    Loop
    next
    Pause 1000
do: Gosub playsong: loop 'altered was (return)

Send:
SetFreq BAUD_FREQ
Pause 10
SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
SetFreq MDEFAULT
Return

Receive:
SetFreq BAUD_FREQ
  Pause 10
  SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
  SerIn  RX, BAUD,   arg, arg, arg, arg, arg, arg.msb, arg.lsb
  SetFreq MDEFAULT
  Return
volumeup:
       vol = Vol + 1 max 30
       write 0, vol 'write value to eeprom positiom 0
          SEROUT AXE134pin , N2400_4 , ( 254 , 154 ) ; Position the cursor (at start of top line)128 top line
            SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134
       SerTxd("volume ", #vol, CR, LF )
       cmd = $04 : arg = $0000 : Gosub Send
return

Volumedown:
        vol = Vol min 1 - 1
        write 0, vol 'write value to eeprom position 0
           SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134
        SerTxd("volume ", #vol, CR, LF )
        cmd = $05 : arg = $0000 : Gosub Send
return

playnext:
       Track = Track + 1
      
       SEROUT AXE134pin , N2400_4 , ( 254 , 215 ); Position the cursor (at start of top line)128 top line
         SEROUT AXE134pin , N2400_4 , ( "Playing Song " , #Track ," " )     ; Send to AXE134
     
       SerTxd("Playing song 000", #Track, CR, LF )
       cmd = $01 : arg = $0000 : Gosub Send
       pause 500 ;;;;; added to stop double song issue, but slowed skipping song down
return

'cmd = 0x08 : arg = 0001 : Gosub Send 'repeatably play song 0001
'cmd = $12 : arg = 0001 : Gosub Send 'play song 0001
Another issue i just noticed, more of a question, i didn't really feel i could notice any different regards the Equalizer, just noticed i have possibly missed "$" from infront of the arg = 0002 below, would that mean that previously it will have just not worked?

Code:
cmd = 0x07 : arg = 0002 : Gosub Send ' EQ rock
SerTxd("Equlizer set to rock", CR, LF )
pause 1000
 
Last edited:

tmfkam

Senior Member
Firstly, after you've printed out the number of tracks you've got an "End" statement so I guess it stops there?

The number of tracks returned *can* include non-music tracks and possibly folders too. I always use this as a best guess. It is normally spot on, but I don't rely on it. If you don't have any non-mp3 files on the disk you may not find this an issue.

I get the number of tracks from the player, then if I attempt to play a track that doesn't load set the value of maximum tracks to be reduced to one less than the track I tried to play.

I also found that I didn't need to initialise the USB disk if no uSD card was fitted. If there was a uSD card and a USB disk attached I would sometimes struggle to get the USB disk to start. With only one present, I had no such problems.

Might the equaliser only work on the headphone (line out)? It isn't something I ever used.
 

Rampz

Well-known member
Firstly, after you've printed out the number of tracks you've got an "End" statement so I guess it stops there?

The number of tracks returned *can* include non-music tracks and possibly folders too. I always use this as a best guess. It is normally spot on, but I don't rely on it. If you don't have any non-mp3 files on the disk you may not find this an issue.

I get the number of tracks from the player, then if I attempt to play a track that doesn't load set the value of maximum tracks to be reduced to one less than the track I tried to play.

I also found that I didn't need to initialise the USB disk if no uSD card was fitted. If there was a uSD card and a USB disk attached I would sometimes struggle to get the USB disk to start. With only one present, I had no such problems.

Might the equaliser only work on the headphone (line out)? It isn't something I ever used.
Thank You tmfkam

I did notice that "end" and removed it, that seemed to run after that, but if i do a download of code in the terminal it shows 114 which is the correct number of songs, but if i cycle the power as say recovery from power cut it shows count as 1 for some reason, then as i play other songs i want the oled to show playing say 1 of 114 on this occasion, but that part isn't working, it just displays 1 both on oled and terminal.
I will have a play with removing the "set to usb" part and see what it does, doesn't seem to matter either with or without
Still some issues but basically getting towards a useable setup

Edit

I used this code from hippy altered to suit my Gosub name etc, wondering how the info received from Serin command knows to end up in TrackNum which is W4, i used a word incase i have more than 255 tracks, i have replaced "arg.lsb" with "TrackNum" and it appears to work


Code:
cmd = $47
Gosub Receive
SerTxd( "TrackNum", #arg, CR, LF )


Receive:
  SetFreq BAUD_FREQ
  Pause 10
  SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
  SerIn  RX, BAUD,   arg, arg, arg, arg, arg, arg.msb, arg.lsb
  SetFreq MDEFAULT
  Return
Current Code
Code:
#picaxe 14m2
#no_data
#terminal 4800

Symbol TX = B.4
Symbol RX = C.3
Symbol BUSY_PIN = pinC.2
Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol cmd = b0
Symbol arg = w1 ; b3:b2
Symbol arg.lsb = b2
Symbol arg.msb = b3
Symbol Track = w2
symbol Vol = b6
Symbol BTN = PinB.5 'volume up
Symbol BTN1 = PinB.3 'volume down
Symbol BTN2 = PinB.2 'next song
Symbol AXE134pin = C.1 'connected to screen input
Symbol Pressed = 1
symbol TrackNum = W4

init:


High TX ; set TX pin high for idle high serial
SerTxd("Get ready to Rock", CR, LF )
Pause 3000



'varB = 8 'initial volume setting
'cmd = 0x06 : arg = varB : Gosub Send
'SerTxd("init volume set to ", #varB, CR, LF ) ' added to display its value at this time

read 0, Vol 'added to read previous volume from eeprom position 0


         SEROUT AXE134pin , N2400_4 , ( 254 , 128 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Programming by Rampz")     ; Send to AXE134

SerTxd("Selected USB", CR, LF )
'cmd = $09 : arg = $0001 : Gosub Send '0001 for usb, 0002 for sd card
'pause 3000


cmd = $47
Gosub Receive
SerTxd( "TrackNum ", #TrackNum, CR, LF )
pause 2000




cmd = 0x07 : arg = $0002 : Gosub Send ' EQ rock
SerTxd("Equlizer set to rock", CR, LF )
pause 1000

         SEROUT AXE134pin , N2400_4 , ( 254 , 192 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Equ to Rock, Set USB")     ; Send to AXE134

    cmd = 0x06 : arg = Vol : Gosub Send   'Volume set at 8 of 30, altered to read Vol

    SerTxd("volume set to ", #Vol, CR, LF ) 'display volume setting from eeprom hopefully
 
      SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
        SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134

Pause 1000
Gosub playsong


playsong:
    For Track = 1 To TrackNum 
    SerTxd("Playing song 000", #Track, CR, LF )
 
      SEROUT AXE134pin , N2400_4 , ( 254 , 212 ); Position the cursor (at start of top line)128 top line
SEROUT AXE134pin , N2400_4 , ( "Play Song " , #Track ," ", "of ", #TrackNum ," " )     ; Send to AXE134
 
    cmd = $12 : arg = Track : Gosub Send
    Pause 1000
    Do While BUSY_PIN = 0
    Pause 100
    IF BTN = Pressed then
    pause 50
    Gosub volumeup
    endif
    IF BTN1 = Pressed then
    pause 50
    Gosub volumedown
    endif
    IF BTN2 = Pressed then
    pause 50
    Gosub playnext
    endif
    Loop
    next
    Pause 1000
do: Gosub playsong: loop 'altered was (return)

Send:
SetFreq BAUD_FREQ
Pause 10
SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
SetFreq MDEFAULT
Return

Receive:
SetFreq BAUD_FREQ
  Pause 10
  SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
  SerIn  RX, BAUD,   arg, arg, arg, arg, arg, arg, TrackNum
  SetFreq MDEFAULT
  Return
volumeup:
       vol = Vol + 1 max 30
       write 0, vol 'write value to eeprom positiom 0
          SEROUT AXE134pin , N2400_4 , ( 254 , 154 ) ; Position the cursor (at start of top line)128 top line
            SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134
       SerTxd("volume ", #vol, CR, LF )
       cmd = $04 : arg = $0000 : Gosub Send
return

Volumedown:
        vol = Vol min 1 - 1
        write 0, vol 'write value to eeprom position 0
           SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134
        SerTxd("volume ", #vol, CR, LF )
        cmd = $05 : arg = $0000 : Gosub Send
return

playnext:
       Track = Track + 1
    
       SEROUT AXE134pin , N2400_4 , ( 254 , 212 ); Position the cursor (at start of top line)128 top line
         SEROUT AXE134pin , N2400_4 , ( "Play Song " , #Track ," ", "of ", #TrackNum ," " )     ; Send to AXE134
   
       SerTxd("Playing song 000", #Track," of ", #TrackNum, CR, LF )
       cmd = $01 : arg = $0000 : Gosub Send
       pause 500 ;;;;; added to stop double song issue, but slowed skipping song down
return

'cmd = 0x08 : arg = 0001 : Gosub Send 'repeatably play song 0001
'cmd = $12 : arg = 0001 : Gosub Send 'play song 0001
when i cycle power it still returns showing playing 1 of 1 even though it will still count upwards eg 1 of 2, 1 of 3, but returns fine when i do a download first, really strange
 
Last edited:

Rampz

Well-known member
Success i have had to Query track numbers twice, one at initial start up and after couple of seconds later before getting to play song, now it shows correctly and plays correctly on OLED and Terminal even after a cycle of the power.
My wife asked me just now if i was trying to mess with her brain today, i was playing with code before work, i seemed to be getting somewhere, but struggled with above issues, told her i left it playing on low and left for work, only to find it has ended up playing the same track for 12 hours, she wasn't impressed
 
Last edited:

tmfkam

Senior Member
One problem you may have is that the track number value(s) are returned as two bytes. You may have to reference TrackNum.msb and TrackNum.lsb to get a word value?

There is also a value returned that indicates "success" in retrieving the value(s). I'll have to dig out my code and see what I noted about track numbers, I'm sure there was something odd but can't recall.

I do recall sometimes only getting "1", again I think a few subsequent calls were needed but I'll have to think about it.
 

Rampz

Well-known member
A strange affect tmfkan, seems i am getting away with receiving twice into TrackNum rather than TrackNum.msb and TrackNum.lsb , i assume it returns into b8 and the second time into b9 making up w4, i noticed previously if i cycled power i must have only ever received b8 part only, which would be 1 and if i cycled power a second time with it resetting the picaxe i assume i got b8 the second time, but if i then did a download of code then the program started again i maybe got b9 section, being 14, after a download it always seemed correct, so maybe the download didn't clear b8, i would have thought a download would have reset all ram memory? i never tried cycling power and doing a download straight away to make it read only once.

I did just turn it off, remove the last track from the usb and powered up and it read correctly, i did just try removing the usb mid song, it starts counting up the track number and not finding anything, re iserted usb and after a few seconds started playing at the next number it found, so thats ok.

Maybe a bit difficult to try and get the "play song" to stop and reset the counter and wait for the usb to be re inserted?
If it gets a Pull-out of the device this is the string 7E FF 06 3B 00 00 02 xx xx EF, after inserted its 7E FF 06 3A 00 00 02 xx xx EF, it works fine but would be a nice touch to recount number of tracks and start from the beginning etc
Thinking further if we receive a TV card inserted and get it to reset everything that could do it?

Another thought i am using cmd = $47 which is to receive data from the TF card but i am using USB, but as you said i din't have to set it to USB?

Below is my code as it stands now

Code:
#picaxe 14m2
#no_data
#terminal 4800

Symbol TX = B.4
Symbol RX = C.3
Symbol BUSY_PIN = pinC.2
Symbol BAUD_FREQ = M8
Symbol BAUD = T9600_8
Symbol cmd = b0
Symbol arg = w1 ; b3:b2
Symbol arg.lsb = b2
Symbol arg.msb = b3
Symbol Track = w2
symbol Vol = b6
Symbol BTN = PinB.5 'volume up
Symbol BTN1 = PinB.3 'volume down
Symbol BTN2 = PinB.2 'next song
Symbol AXE134pin = C.1 'connected to screen input
Symbol Pressed = 1
symbol TrackNum = W4

init:


High TX ; set TX pin high for idle high serial
SerTxd("Get ready to Rock", CR, LF )
cmd = $47
Gosub Receive
Pause 2000



'varB = 8 'initial volume setting
'cmd = 0x06 : arg = varB : Gosub Send
'SerTxd("init volume set to ", #varB, CR, LF ) ' added to display its value at this time

read 0, Vol 'added to read previous volume from eeprom position 0


         SEROUT AXE134pin , N2400_4 , ( 254 , 128 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Programming by Rampz")     ; Send to AXE134

SerTxd("Selected USB", CR, LF )
'cmd = $09 : arg = $0001 : Gosub Send '0001 for usb, 0002 for sd card
'pause 3000


cmd = $47
Gosub Receive
SerTxd( "TrackNum ", #TrackNum, CR, LF )
pause 2000




cmd = 0x07 : arg = $0002 : Gosub Send ' EQ rock
SerTxd("Equlizer set to rock", CR, LF )
pause 1000

         SEROUT AXE134pin , N2400_4 , ( 254 , 192 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Equ to Rock, Set USB")     ; Send to AXE134

    cmd = 0x06 : arg = Vol : Gosub Send   'Volume set at 8 of 30, altered to read Vol

    SerTxd("volume set to ", #Vol, CR, LF ) 'display volume setting from eeprom hopefully
   
      SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
        SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134

Pause 1000
Gosub playsong


playsong:
    For Track = 1 To TrackNum   
    SerTxd("Playing song 000", #Track," of ", #TrackNum, CR, LF )
   
    'cmd = $47 'Query TrackNum a second time helps
    'Gosub Receive
   
SEROUT AXE134pin , N2400_4 , ( 254 , 212 ); Position the cursor (at start of top line)128 top line
SEROUT AXE134pin , N2400_4 , ( "Play Song " , #Track ," ", "of ", #TrackNum ," " )     ; Send to AXE134
   
    cmd = $12 : arg = Track : Gosub Send
    Pause 1000
    Do While BUSY_PIN = 0
    Pause 100
    IF BTN = Pressed then
    pause 50 
    Gosub volumeup
    endif
    IF BTN1 = Pressed then
    pause 50
    Gosub volumedown
    endif
    IF BTN2 = Pressed then
    pause 50
    Gosub playnext
    endif
    Loop
    next
    Pause 1000
do: Gosub playsong: loop 'altered was (return)

Send:
SetFreq BAUD_FREQ
Pause 10
SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
SetFreq MDEFAULT
Return

Receive:
SetFreq BAUD_FREQ
  Pause 10
  SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
  SerIn  RX, BAUD,   arg, arg, arg, arg, arg, arg, TrackNum
  SetFreq MDEFAULT
  Return
volumeup:
       vol = Vol + 1 max 30
       write 0, vol 'write value to eeprom positiom 0
          SEROUT AXE134pin , N2400_4 , ( 254 , 154 ) ; Position the cursor (at start of top line)128 top line
            SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134
       SerTxd("volume ", #vol, CR, LF )
       cmd = $04 : arg = $0000 : Gosub Send
return

Volumedown:
        vol = Vol min 1 - 1
        write 0, vol 'write value to eeprom position 0
           SEROUT AXE134pin , N2400_4 , ( 254 , 154 ); Position the cursor (at start of top line)128 top line
             SEROUT AXE134pin , N2400_4 , ( "Volume=" , #Vol ," " )     ; Send to AXE134
        SerTxd("volume ", #vol, CR, LF )
        cmd = $05 : arg = $0000 : Gosub Send
return

playnext:
       Track = Track + 1
      
       SEROUT AXE134pin , N2400_4 , ( 254 , 212 ); Position the cursor (at start of top line)128 top line
         SEROUT AXE134pin , N2400_4 , ( "Play Song " , #Track ," ", "of ", #TrackNum ," " )     ; Send to AXE134
      
      
       SerTxd("Playing song 000", #Track," of ", #TrackNum, CR, LF )
       cmd = $01 : arg = $0000 : Gosub Send
       pause 500 ' Needed to stop double song issue, but slowed skipping song down
return

'cmd = 0x08 : arg = 0001 : Gosub Send 'repeatably play song 0001
'cmd = $12 : arg = 0001 : Gosub Send 'play song 0001
 
Last edited:

tmfkam

Senior Member
Here's the code I'm using.

It looks as though I request track info for the various devices in turn. Without checking I seem to think that the query for uSD will work for a USB disk, if there is no uSD fitted. It's been a while though since I wrote any of this and I could have "mis-remembered".

As before, this has been written in a different variant of BASIC, but should give you an idea...

SerialData() is an array of Byte values. You might just as easily replace this with b1, b2, b2, b4... and so on.
I found it clearer to actually send the values in each command as it made it easier to understand what each command was doing, and where the differences were.

Code:
Sub Fetch_Tracks

    SerSend 1, 0x7e
    SerSend 1, 0xff
    SerSend 1, 0x06
    SerSend 1, 0x48 'Command for track query uSD disk
    SerSend 1, 0x00 'Return value request
    SerSend 1, 0x00
    SerSend 1, 0x00
    SerSend 1, 0xef
    Serial_Fetch

    'If there are no tracks (folders) found on uSD, try USB
    If ReturnTracks < 1 Then
        Wait 100 mS
        SerSend 1, 0x7e
        SerSend 1, 0xff
        SerSend 1, 0x06
        SerSend 1, 0x47 'Command for track query USB
        SerSend 1, 0x00 'Return value request
        SerSend 1, 0x00
        SerSend 1, 0x00
        SerSend 1, 0xef
        Serial_Fetch
    End If

    'If there are no tracks (folders) found on USB, try Flash disk
    If ReturnTracks < 1 Then
        Wait 100 mS
        SerSend 1, 0x7e
        SerSend 1, 0xff
        SerSend 1, 0x06
        SerSend 1, 0x49 'Command for track query Flash disk
        SerSend 1, 0x00 'Return value request
        SerSend 1, 0x00
        SerSend 1, 0x00
        SerSend 1, 0xef
        Serial_Fetch
    End If

    Wait 100 mS
End Sub

Sub Serial_Fetch

    Let ReturnTracks = 0

    SerReceive 1, SerData(1) '0x7e
    SerReceive 1, SerData(2) '0xff
    SerReceive 1, SerData(3) '0x06
    SerReceive 1, SerData(4)
    SerReceive 1, SerData(5)
    SerReceive 1, SerData(6) 'High Byte of track count
    SerReceive 1, SerData(7) 'Low  Byte of track count
    SerReceive 1, SerData(8) '0xef

'    Locate 1, 0
'    Print SerData(4)'Indicates disk? 72=microSD 71=USB?
'    Print ":"
'    Print SerData(6)
'    Print ":"
'    Print SerData(7)
'    Print "                "
'    Wait 1000 mS

    If SerData(6) > 0 Then
          Let ReturnTracks = SerData(6)
          Let ReturnTracks = ReturnTracks * 256 'High Byte
    End If

    If SerData(7) > 0 Then
          Let ReturnTracks = ReturnTracks + SerData(7) 'Low Byte
    End If

End Sub
 
Last edited:

JaneWat

New member
I have been asked if i can add a Cockrill sound to an animated display, always looking for opportunities to use the picaxe's now, it seems the store is out of Vmusic2 modules so i have ordered one from RS, Firstly what the best picaxe to control it with i have the AXE091 board and it came with a 18m2 that i have never used, is it suitable to control the Vmusic2? So far i have only used the 08m2. Is the Vmusic2 they way to go to add a single mp3 to a project? I did see the french part of the forum speak about a Vmusic3?
The cockrill will need to be quite loud so i will need an external amplifier with volume control
Not asking for help just want to discuss options really at the moment
listen, well, if these guys succeed
, then you will definitely succeed
 

hippy

Technical Support
Staff member
Code:
SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
SerIn  RX, BAUD,   arg, arg, arg, arg, arg, arg.msb, arg.lsb
Code:
SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
SerIn  RX, BAUD,   arg, arg, arg, arg, arg, arg,     TrackNum
The first code is correct. The second code will not work correctly when there are 256 tracks or more.

The best way to get the track count into a word variable 'TrackNum' would be -
Code:
SerOut TX, BAUD, ( $7E, $FF, $06, cmd, $00, arg.msb, arg.lsb, $EF )
SerIn  RX, BAUD,   arg, arg, arg, arg, arg, arg.msb, arg.lsb
TackNum = arg
 

Rampz

Well-known member
Came to the music player this morning, no sound, volume was on 1, played with the buttons I set for the 08m2 all working just fine as expected, but no sound, assume music model has crashed, cycled the power all working fine again.

On the picaxe development board was think not a lot inthe way of capacitor value, wondering if that's the problem, has been fine for 2 weeks I guess 24hrs a day
 

Rampz

Well-known member
Seems about every 10 days the df player mini stops, cycling power to the unit resets it ok apart from the picaxe not sending the volume details which its not coded to do.
I see in the spec there is Reset command, will that fully reset it?
I wonder if it would be a good idea to send a reset and the volume setting at the end of going through all the tracks?

Anyone have experience of these sorts of problems?
 

tmfkam

Senior Member
The "jukebox" I made was used for a source of music for my 1940s valve (tube) clock radios. It ran 24hrs non stop. I never used any reset command. As mentioned before, loading tracks could sometimes cause issues where a track may either appear to load, but not, or appear to not load, but load. This could lead to a loop where the track would be called continually which played the same few milliseconds of silence at the start of the track over and over making it appear to have locked up. Only once I perfected the track loaded test did I fix this.

My only other suggestion would be to format the USD card when adding or removing tracks. I wasn't certain that the player handled deleted and added tracks well.

I also added a few little flags that showed in the LCD display to indicate the status of a track loading and so on. When debugging it helped enormously.
 

Rampz

Well-known member
My only other suggestion would be to format the USD card when adding or removing tracks. I wasn't certain that the player handled deleted and added tracks well.
Yes i was careful to do that whenever i change the tracks, knowing that a deleted track may not count in the number displayed but likely the player would still play it, i'll re-format the USB drive and load the tracks again and see if it helps

Regards altering code further so that it correctly reads is over my head at the moment, flags is an interesting idea as a start, anyone got ideas how i can implement that in the code to give that feed back?
 

hippy

Technical Support
Staff member
Seems about every 10 days the df player mini stops, cycling power to the unit resets it ok
The best, perhaps only, approach is to add diagnostics so one can tell where the code is, what it is doing when it isn't behaving as expected, giving some sort of trace as to how it got there.

The main purpose is to figure out if the PICAXE has stopped because it is waiting for some sort of response from the module, or the module is simply not responding to what the PICAXE is telling it to do. From what it is doing it will hopefully be possible to determine what the issue is, and how to resolve that.

Issuing resets, after all tracks have played, after every track, or some other regime may resolve or overcome the issue. They only way to tell is really to try it.
 
Top