Hello. I'm hoping someone can point me in the right direction regarding serial coms using a Pic.
I'm trying to communicate with an DFPlayerMini MP3 module. The serial protocol required is described as:
Support for asynchronous serial communication mode via PC serial sending commands
Communication Standard:9600 bps
Data bits :1
Checkout :none
Flow Control :none
I thought that this would be set using CGB with the following command:
InitSer 1, r9600, 1, 8, 1, none, normal
and that the command (7E FF 06 CommandByte 00 01 01 ParameterMSB ParameterLSB EF ) would be issued using:
Sub Serial_Send(Cmd as Byte ,A_lsb as Byte, Optional A_msb=0x0)
SerSend 0x7e, 0xff, 0x06, Cmd, 0x00, A_msb, A_lsb, 0xef
Wait 100 mS
SendAHigh 'Idle High
End Sub
Does this look as though uit will send in the format I need or have I lost it. Again...
Last edit: mkstevo 2016-02-12
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You should look at the GCBasic help under serial communication ,rsr232 (software).
The InitSer looks ok for now and you know that it is channel 1.
You are missing the initialization of the ports. Look at the example in Help.
#define SendAHigh Set PORTB.2 ON
#define SendALow Set PORTB.2 OFF
Sub Serial_Send(Cmd as Byte ,A_lsb as Byte, Optional A_msb=0x0)
'SerSend 0x7e, 0xff, 0x06, Cmd, 0x00, A_msb, A_lsb, 0xef
' should be broken into a series of SerSends directed to channel 1
SerSend 1, 0x7e
SerSend 1, 0xff
SerSend 1, 0x06
SerSend 1, Cmd
SerSend 1, 0x00 ' is there more bytes here? CommandByte 00 01 01?
SerSend 1,A_msb
SerSend 1,A_lsb
SerSend 1,0xef
Wait 100 mS
'SendAHigh 'I don't think you want this here'Idle High?
End Sub
Be nice to see the your program.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
'Pic 16F1829 DFPlayer MP3 Audio Interface
#Chip 16F1829, 32
'###########################################################################
#Config CP=On
'Read protected
'###########################################################################
#Define Player_Busy PortC.7 'DFPlayer Busy (-) Pin9 Pin16 DFPlayer
#Define SerTX PortB.5 'Serial Out (-) Pin12 Pin2 DFPlayer
#Define SendAHigh Set SerTX On 'Serial Out (-) Pin12 Pin2 DFPlayer
#Define SendALow Set SerTX Off 'Serial Out (-) Pin12 Pin2 DFPlayer
#Define Track As Byte
#Define Folder As Byte
#Define MaxFolders As Byte
#Define MaxTracks = 0x254
#Define Disk_Chk As Byte
#Define Play_FxxTxx = 0x0F 'Play from numbered folder - Needs the folder and track number to be sent as arguments (max 63 folders, 254 tracks)
#Define Play_FMP3 = 0x12 'Play from /MP3/ folder - Needs the track number to be sent as arguments (max 9999 tracks)
#Define Play_FAdv = 0x13 'Play from /Advert/ folder - Needs the track number to be sent as arguments (max 9999 tracks)
#Define Play_FxTxxx = 0x14 'Play from numbered folder - Needs the folder and track number to be sent as arguments (max 15 folders, 999 tracks)
#Define Play_RMP3 = 0x15 'Resume playing MP3 and stop the advert
#Define Stop_Play = 0x16 'Stop play
#Define Volume = 0x06 'Set volume - needs volume level sending as a parameter
#Define Disk_Set = 0x09 'Change the disk - needs source setting with arguments (0x01=USB, 0x02=MicroSD)
#Define USB_Disk = 0x01 'Argument for USB source
#Define Micro_SD = 0x02 'Argument for MicroSD source
Dir Player_Busy In 'DFPlayer Busy (-) Pin9 Pin16 DFPlayer
Dir SerTX Out 'Serial Out (-) Pin12 Pin2 DFPlayer
InitSer 1, r9600, 1, 8, 1, none, normal
SendAHigh 'Idle High
Main:
Wait 1 S
Serial_Send(Volume,0x0)
Serial_Send(Disk_Set,Usb_Disk)
Wait 4 S
Serial_Send(Play_FxxTxx,0x1,0x1)
Wait 400 mS
If Player_Busy = 0 Then
Do
'Disk found
Play_Track(1,1)
Do
Wait 100 mS
Loop Until Player_Busy = 1
While 0
End If
End
Sub Play_Track(Fdr As Byte, Trk As Byte)
'The Folder and track are deliberately
'reversed below as folder needs sending
'last to match the 'optional' parameter
'in the serial out routine.
Serial_Send(Play_FxxTxx,Trk,Fdr)
End Sub
'SerOut TX, BAUD, ( 0x7E, 0xFF, 0x06, cmd, 0x00, arg.msb, arg.lsb, 0xEF )
Sub Serial_Send(Cmd as Byte ,A_lsb as Byte, Optional A_msb=0x0)
SerSend 0x7e, 0xff, 0x06, Cmd, 0x00, A_msb, A_lsb, 0xef
Wait 100 mS
SendAHigh 'Idle High
End Sub
Though I now understand from mmotte that the SerSend should be re-written as:
'SerOut TX, BAUD, ( 0x7E, 0xFF, 0x06, cmd, 0x00, arg.msb, arg.lsb, 0xEF )
Sub Serial_Send(Cmd as Byte ,A_lsb as Byte, Optional A_msb=0x0)
SerSend 1, 0x7e
SerSend 1, 0xff
SerSend 1, 0x06
SerSend 1, Cmd
SerSend 1, 0x00
SerSend 1, A_msb
SerSend 1, A_lsb
SerSend 1, 0xef
Wait 100 mS
SendAHigh 'Idle High
End Sub
The reason for the 'trailing' SendAHigh' is because the original (PicAxe) program suggested that the serial port should 'idle high'. Not understanding if this was taken care of automatically or not, I included it as the example PicAxe program did.
The fifth argument (SerSend 1, 0x00) is a command that indicates whether or not a response from the DFPlayer is required. 0x00 = no response required, 0x01 = response required.
This is from the DFPlayer instruction manual:
Format:
$S,VER,Len,CMD,Feedback,para1,para2,checksum,$O
$SEachcommandstartswith$S0x7EVERVersionLenthenumberofbytesafter“Len”ChecksumsarenotcountedCMDCommandssuchasplay/pause,etc.FeedbackCommandfeedback1:feedback,0:nofeedbackpara1highdatabytepara2lowdatabytechecksum(ignored)
$OEndbit0xEFForexample,Specifyfolder01of001.mp37EFF060F000101xxxxEFxx=don't care, not checked.
I did try reading the manual, but I admit some of it only made partial sense. I like to work through paper instructions with a few examples before I can be confident. I'm truly grateful for your help and I do now hope to be able to get some music out of the module. They are fabulous units, I've had it working under PicAxe very well. My only problem is that this may become a commercial product and the cost of the PicAxe processors is rather more than the equivalent base PIC. I love PicAxe, and it is very quick to program and use and I will use it if I need to, but if I can convert my existing program for the VLSI mp3 module to the DFPlayer version it will save me some time and money. It is just the initialisation commands, and the command sending protocol I'm struggling to pick up.
I will let Mike support you but a few points. Why would you not use hardware serial communications? And, I would recommend upgrading to the latest version of Great Cow BASIC - the serial communication protocols have been improved in terms of the buad rates.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, You have an exciting project. I haven't seen this little board/player until now. Last year I was trying to make a talking scada to annonouce some times and status over a handitalkie.I was working with the WTV020. I did get it counting the numbers to 120.
I have been looking on the net for info on the DFplayer and first thing is the manual's first example has a wrong checksum.
For example, if we specify play NORFLASH, you need to send: 7E FF 06 09 00 00 04 **FF DD** EF
Data length is 6, which are 6 bytes [FF 06 09 00 00 04]. Not counting the start, end, and verification.
Their "FF DD is wrong. They used the right 6 values.
Dim checksum as word
'Calculate the checksum (2 bytes)
checksum = 0 -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2)
Next I would agree with Evan that the 16F1829 has a USART and it would be easy to use. Unless you need "inverted" output or you have already made a board and you have to cut traces to get to the usart pins.
How about this for the cmd_line?
DIM CMD_Line( 10)
Dim CK as Word
...
SendCmd(0x09,0x04,0x00)
...
Sub SendCmd(Cmd as Byte ,A_lsb as Byte, Optional A_msb=0x0)
CK = 0 -(0x7e + 0xff + Cmd + 0x00 + A_msb + A_lsb)
CMD_Line = 0x7e, 0xff, 0x06, Cmd, 0x00,A_msb, A_lsb, CK_H, CK_L, 0xef
For index = 1 to 10
SerSend 1,CMD_Line(index) 'For Hardware USART "HSerSend CMD_Line(index)"
next
That's all i got for now. i will be looking at this more. This is not tested code. I have concern about how CK will calculate. Am i even close to what your question is?
I will plug is you code and work with it.
BR
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I originally thought I'd use the software serial as I thought I understood 'better' how to set it up. The hardware serial setup examples made rather less sense to me than the software setup examples.
At the moment my project has not progressed further than the feature list, so any pins can be used. The version of the program I have already that reads the inputs and currently plays audio via the VLSI Mp3 module has the pins for input and output currently allocated, but I've no particular preference otherwise.
According to the DFPlayer manual, the checksum is ignored so can probably be any value, the values I used were lifted straight from the PicAxe example program that I've used and modified to do as I need.
I, again, lifted the commands I wanted to use from a combination of the PicAxe example programs and the DFPlayer manual. I perhaps haven't included those that I am not interested in using. I gave those I was interested in using constant values so that I could more easily see what I was doing.
I'll add the PicAxe example manual.
The following program attempts to locate Track 01, in Folder 01 on a USB drive. If it fails to find the track on a USB disk it attempts to find Track 01, in Folder 01 on a MicroSD card.
Once started it will try to play Track 01 in Folder 01, then Track 01 from Folder 02, and so on until it runs out of folders. It then tries to play Track 02 of Folder 01 until it runs out of tracks, it then repeats. Not a great program, but proves the module is working. A portion of the program was copied wholesale from the given examples.
NOTE: The following is the PicAxe version of the program. IT WILL NOT WORK FOR Great Cow Basic, or a standard PIC.
'14M2 MP3 Test Version'DFPlayer Mini Command set'All commands to be sent in Hexadecimal format'$01 $00 $00 Next '$02 $00 $00 Previous '$03 $nn $nn Specify track 0000-0BB7 '$04 $00 $00 Increase volume '$05 $00 $00 Decrease volume '$06 $00 $vv Volume, vv=00-1E (1E=full volume) '$07 $00 $00 Specify EQ Normal '$07 $00 $01 Specify EQ Pop '$07 $00 $02 Specify EQ Rock '$07 $00 $03 Specify EQ Jazz '$07 $00 $04 Specify EQ Classic '$07 $00 $05 Specify EQ Base '$08 $00 $00 Playback mode normal '$08 $00 $01 Playback mode repeat folder '$08 $00 $02 Playback mode repeat single '$08 $00 $03 Playback mode repeat random '$09 $00 $01 Source is USB-Disk '$09 $00 $02 Source is TF (microSD) Card '$09 $00 $03 Source is Aux '$09 $00 $04 Sleep '$09 $00 $05 Source is Flash memory '$0A $00 $00 Stand by '$0B $00 $00 Normal working '$0C $00 $00 Reset module '$0D $00 $00 Resume play (un-pause) '$0E $00 $00 Pause '$0F $ff $tt Play from folder ff=01-63, track tt=01-FF '$10 $00 $vv Volume gain, vv=00-1F '$10 $01 $vv Open volume adjust, vv=00-1F '$11 $00 $00 Repeat Play Off '$11 $00 $01 Repeat Play On '$12 $tt $tt Play from MP3 folder, track tt=0001-270F '$13 $tt $tt Play from ADVERT folder, track tt=0001-270F '$14 $ft $tt Play from folder f=1-F, track ttt=001-3E7 '$15 $00 $00 Stop advert, resume original track '$16 $00 $00 Stop#Picaxe14M2#No_Data#DefineLow_Volume'#Define Show_Debug'#Define LED_Active#IfDefShow_DebugThen#Terminal4800#EndIfSymbolTX=B.4'Symbol RX = C.3#IfDefLED_ActiveThenSymbolmSD_Active=B.2SymbolUSB_Active=B.5#EndIfSymbolBUSY_PIN=pinC.2SymbolBAUD_FREQ=M8SymbolBAUD=T9600_8Symbolcmd=b0Symbolarg=w1;b3:b2Symbolarg.lsb=b2Symbolarg.msb=b3SymbolTrack=b2SymbolFolder=b3SymbolvarA=w2SymbolMaxFolders=b4SymbolMaxTracks=$254SymbolDisk_Chk=b5SymbolPlay_FxxTxx=$0F'Play from numbered folder - Needs the folder and track number to be sent as arguments (max 63 folders, 254 tracks)SymbolPlay_FMP3=$12'Play from /MP3/ folder - Needs the track number to be sent as arguments (max 9999 tracks)SymbolPlay_FAdv=$13'Play from /Advert/ folder - Needs the track number to be sent as arguments (max 9999 tracks)SymbolPlay_FxTxxx=$14'Play from numbered folder - Needs the folder and track number to be sent as arguments (max 15 folders, 999 tracks)SymbolPlay_RMP3=$15'Resume playing MP3 and stop the advertSymbolStop_Play=$16'Stop playSymbolVolume=$06'Set volume - needs volume level sending as a parameterSymbolDisk_Set=$09'Change the disk - needs source setting with arguments ($01=USB, $02=MicroSD)SymbolUSB_Disk=$01'Argument for USB sourceSymbolMicro_SD=$02'Argument for MicroSD sourceHighTX;setTXpinhighforidlehighserial#IfDefLED_ActiveThenLowUSB_ActiveLowmSD_Active#EndIf#IfDefShow_DebugThenSerTxd("14M2 DFPlayer controller",CR,LF)SerTxd("V2.4")SerTxd(CR,LF)#EndIfPause2000LetDisk_Chk=USB_DiskGoSubDisk_SetUpLetcmd=Volume#IfDefLow_VolumeThenLetarg=$05#ElseLetarg=$15#EndIf#IfDefShow_DebugThenSerTxd("Set volume ")#EndIfGosubSendPause1000#IfDefShow_DebugThenSerTxd("System ready",CR,LF)SerTxd(CR,LF)#EndIfLetMaxFolders=$1ForTrack=$1ToMaxTracksForFolder=$1ToMaxFolders#IfDefShow_DebugThenSerTxd("Play ")#EndIfcmd=Play_FxxTxx'arg = varA'Track and Folder directly set the MSB and LSB through b2 and b3GosubSendPause500LetTime=0IfBUSY_PIN=0ThenIfTrack=1ThenIfMaxFolders=MaxFoldersThenLetMaxFolders=MaxFolders+1EndIfEndIf#IfDefShow_DebugThenSerTxd("Playing from folder ",#Folder," Track number ",#Track,CR,LF)#EndIfDoWhileBUSY_PIN=0Pause100Loop#IfDefShow_DebugThenSerTxd("Track play time ",#Time,CR,LF)#EndIfElse#IfDefShow_DebugThenSerTxd("Track not found",CR,LF)#EndIfEndIfNextNext#IfDefShow_DebugThenSertxd("Done",CR,LF)#EndIfStopDisk_SetUp:DoLetcmd=Volume'arg = $15Letarg=$0#IfDefShow_DebugThenSerTxd("Volume ")#EndIfGosubSendPause1000Letcmd=Disk_SetLetarg=Disk_ChkIfDisk_Chk=USB_DiskThen#IfDefShow_DebugThenSerTxd("Select USB ")#EndIf#IfDefLED_ActiveThenHighUSB_ActiveLowmSD_Active#EndIfElse#IfDefShow_DebugThenSerTxd("Select MicroSD ")#EndIf#IfDefLED_ActiveThenLowUSB_ActiveHighmSD_Active#EndIfEndIfGosubSendPause4000#IfDefShow_DebugThenSerTxd("Locating disk ")#EndIfLetcmd=Play_FxxTxxLetTrack=$1LetFolder=$1GosubSendPause500IfBusy_Pin=1Then#IfDefShow_DebugThenSerTxd("Disk Failed",CR,LF)#EndIfIfDisk_Chk=USB_DiskThenLetDisk_Chk=Micro_SDElseLetDisk_Chk=USB_DiskEndIfElse#IfDefShow_DebugThenSerTxd("Disk Success",CR,LF)#EndIfIfDisk_Chk=USB_DiskThen#IfDefShow_DebugThenSerTxd("USB Found",CR,LF)#EndIfElse#IfDefShow_DebugThenSerTxd("MicroSD Found",CR,LF)#EndIfEndIfEndIfLoopUntilBusy_Pin=0#IfDefShow_DebugThenSerTxd("Starting disk ")#EndIfLetcmd=Stop_PlayLetarg=$0GosubSendPause500#IfDefShow_DebugThenSerTxd("Disk ready",CR,LF)#EndIfReturnSend:#IfDefShow_DebugThenSerTxd("$7E, $FF, $06, C",#Cmd,"C $00, F",#arg.msb,"F T",#arg.lsb,"T $EF",CR,LF)#EndIfSetFreqBAUD_FREQPause10SerOutTX,BAUD,($7E,$FF,$06,cmd,$00,arg.msb,arg.lsb,$EF)SetFreqMDEFAULTReturn
I'd like to again thank you all for your kind help.
Sadly I won't be able to test the given example for at least two weeks as my work schedule will not give me time to do so. I really appreciate you taking the time to point me in the right direction. I will upgrade my GCB to V0.95 as soon as time allows. Once I've had time to try the module again I'll post my GCB version of the above program for comparison in the hope that it might assist others who may want to use this fabulously versatile Mp3 module.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I found an error in the send_cmd:
I was putting the cmd byte in the 3rd array element and it should be the 4th element.
sub DF_Send_Cmd ( cmd, arg As word)
CMD_Line(4) = cmd
CMD_Line(6) = arg_H
CMD_Line(7) = arg
Please change in your program.
I'm going to buy one of these modules for trying in one of my projects. Thanks for bringing my attention to this simpler mp3 than the wtv020 which took a special type of file. Then I will try finishing the subroutine drivers for this device.
Just a quick note of thanks for everyone's help so far.
I'm back at my desk today, in front of the PC, with time to look at this again.
I've gone with the software UART for the time being. Mostly I find the initialisation requirements much simpler to understand and the flexibility it offers allows me to map the serial out onto a pin of the PIC16F1825 which directly matches those of the PicAxe 14M2 device, allowing me to plug the PIC directly into the existing PicAxe demonstration PCB and run immediately.
I've compiled the following code which simply attempts to change to an external USB, sets the play volume to zero, checks to see if Track '01.mp3' can be played from Folder '01', if so it stops, sets the volume to 15, starts playback, waits until playback has finished and then plays Track '01.mp3' again.
'Pic 16F1825 DFPlayer MP3 Audio Interface Test Only Version
#Chip 16F1825, 32
'###########################################################################
#Config CP=On
'Read protected
'###########################################################################
#Define Player_Busy PortC.5 'DFPlayer Busy (-) Pin9 Pin16 DFPlayer
#Define SerTX PortC.1 'Serial Out (-) Pin12 Pin2 DFPlayer
#Define SendAHigh Set SerTX On 'Serial Out (-) Pin12 Pin2 DFPlayer
#Define SendALow Set SerTX Off 'Serial Out (-) Pin12 Pin2 DFPlayer
#Define Track As Byte
#Define Folder As Byte
#Define MaxFolders As Byte
#Define MaxTracks = 0xff
#Define Disk_Chk As Byte
#Define Play_FxxTxx = 0x0F 'Play from numbered folder - Needs the folder and track number to be sent as arguments (max 63 folders, 254 tracks)
#Define Play_FMP3 = 0x12 'Play from /MP3/ folder - Needs the track number to be sent as arguments (max 9999 tracks)
#Define Play_FAdv = 0x13 'Play from /Advert/ folder - Needs the track number to be sent as arguments (max 9999 tracks)
#Define Play_FxTxxx = 0x14 'Play from numbered folder - Needs the folder and track number to be sent as arguments (max 15 folders, 999 tracks)
#Define Play_RMP3 = 0x15 'Resume playing MP3 and stop the advert
#Define Stop_Play = 0x16 'Stop play
#Define Volume = 0x06 'Set volume - needs volume level sending as a parameter
#Define Disk_Set = 0x09 'Change the disk - needs source setting with arguments (0x01=USB, 0x02=MicroSD)
#Define USB_Disk = 0x01 'Argument for USB source
#Define Micro_SD = 0x02 'Argument for MicroSD source
Dir Player_Busy In 'DFPlayer Busy (-) Pin9 Pin16 DFPlayer
Dir SerTX Out 'Serial Out (-) Pin12 Pin2 DFPlayer
InitSer 1, r9600, 1, 8, 1, none, normal
SendAHigh 'Idle High
Main:
Wait 1 S
Serial_Send(Volume,0x0)
Serial_Send(Disk_Set,Usb_Disk)
Wait 4 S
Serial_Send(Play_FxxTxx,0x1,0x1)
Wait 400 mS
If Player_Busy = 0 Then
Serial_Send(Stop_Play)
Serial_Send(Volume,0x15)
Do
'Disk found
Play_Track(1,1)
Do
Wait 100 mS
Loop Until Player_Busy = 1
Loop While Player_Busy = 1
End If
End
Sub Play_Track(Fdr As Byte, Trk As Byte)
'The Folder and track are deliberately
'reversed below as folder needs sending
'last to match the 'optional' parameter
'in the serial out routine.
Serial_Send(Play_FxxTxx,Trk,Fdr)
End Sub
'SerOut TX, BAUD, ( 0x7E, 0xFF, 0x06, cmd, 0x00, arg.msb, arg.lsb, 0xEF )
Sub Serial_Send(Cmd as Byte ,A_lsb as Byte, Optional A_msb=0x0)
SerSend 1, 0x7e
SerSend 1, 0xff
SerSend 1, 0x06
SerSend 1, Cmd
SerSend 1, 0x00
SerSend 1, A_msb
SerSend 1, A_lsb
SerSend 1, 0xef
Wait 100 mS
SendAHigh 'Idle High
End Sub
Should a valid file/folder not be found on a USB device, the DFPlayerMini appears to silently default to the on board MicroSD Card(if fitted) as I only test to see if a file can be played to test if the USB is present, this could present a problem. The DFPlayerMini does have the option of returning serial data back to the host microprocessor which could possibly be read in order to determine more accurately whether the USB disk is present. I actually want the capability of falling back to the on board MicroSD card if the USB isn't found, so my simple method suits my needs.
Now to convert my PicAxe program to GCB...
Thanks again for the kind help, it has been greatly appreciated.
Last edit: mkstevo 2016-03-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yesterday (Easter Monday) I spent some time at work to try to progress this project a little farther with no other work related interruptions. I now have the bulk of my project working, with only one or two minor adjustments required.
I want to thank everyone who provided guidance regarding the serial initialisation required. I am truly grateful for your generosity.
I am also eternally grateful for all who have contributed to all the component parts that make up GCB. I really, really appreciate the hard work.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Mkstevo, have been following this thread for a while. I am glad to see you made significant progress, and I agree, this forum is simply awesome! GCB is just wonderful and the fact that it is free on top of it, is the icing on the cake for sure. Would love to see your final code to make this module work correctly, if you care to share that is. This would be a good one to create a library for, I think.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The 'final' code is really the code I posted on 26th February but with the addition of the input detection that initiates playback of the appropriate track, at the appropriate time. I'm not sure I'm using it 'correctly'. I'm just making it work... Mmotte's code was much better and more flexible than mine is, it had checks for correctly calculating the checksum among other things. Things which I don't need, so have wilfully ignored.
This is for an old motor driven game. When the motor moves left/right, sound 1 is played, when it moves front/back sound 2 is played, when not moving sound 3 is played, when no game is being played background music is played. There are further sounds for win/lose situations and so on, but you get the idea.
For example, to play sound one :
If Motor_LR=1 Then
Play_Track(1,1)
End If
and for sound two:
If Motor_LR=1 Then
Play_Track(1,2)
End If
some sounds I want to play until they finish without being interrupted so for these:
If Game_Idle=1 Then
Play_Track(1,7)
Do
Wait 100 mS
Loop Until Player_Busy = 1 'Low=Playing, High=play has stopped
End If
The original sound was played through a large number of peripheral chips (processor, eprom, a/d, clock generators etc.) which I'm hoping to replace with a single processor (16C57 to 16F1829) and the DFPlayer module. This will give the option of playback from USB, rather than eprom meaning the sound files can be 'user updateable'.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello. I'm hoping someone can point me in the right direction regarding serial coms using a Pic.
I'm trying to communicate with an DFPlayerMini MP3 module. The serial protocol required is described as:
Support for asynchronous serial communication mode via PC serial sending commands
Communication Standard:9600 bps
Data bits :1
Checkout :none
Flow Control :none
I thought that this would be set using CGB with the following command:
InitSer 1, r9600, 1, 8, 1, none, normal
and that the command (7E FF 06 CommandByte 00 01 01 ParameterMSB ParameterLSB EF ) would be issued using:
Does this look as though uit will send in the format I need or have I lost it. Again...
Last edit: mkstevo 2016-02-12
Not a problem, hopefully.
Can you tell use the version of GCB? What chip? Attach your code then we can see the initialisation etc.
You should look at the GCBasic help under serial communication ,rsr232 (software).
The InitSer looks ok for now and you know that it is channel 1.
You are missing the initialization of the ports. Look at the example in Help.
Be nice to see the your program.
Thanks for your suggestions.
The chip is a 16F1829. My GCB version is 0.94
The full code I had is:
Though I now understand from mmotte that the SerSend should be re-written as:
The reason for the 'trailing' SendAHigh' is because the original (PicAxe) program suggested that the serial port should 'idle high'. Not understanding if this was taken care of automatically or not, I included it as the example PicAxe program did.
The fifth argument (SerSend 1, 0x00) is a command that indicates whether or not a response from the DFPlayer is required. 0x00 = no response required, 0x01 = response required.
This is from the DFPlayer instruction manual:
I did try reading the manual, but I admit some of it only made partial sense. I like to work through paper instructions with a few examples before I can be confident. I'm truly grateful for your help and I do now hope to be able to get some music out of the module. They are fabulous units, I've had it working under PicAxe very well. My only problem is that this may become a commercial product and the cost of the PicAxe processors is rather more than the equivalent base PIC. I love PicAxe, and it is very quick to program and use and I will use it if I need to, but if I can convert my existing program for the VLSI mp3 module to the DFPlayer version it will save me some time and money. It is just the initialisation commands, and the command sending protocol I'm struggling to pick up.
I greatly appreciate the kind assistance.
Last edit: mkstevo 2016-02-15
I will let Mike support you but a few points. Why would you not use hardware serial communications? And, I would recommend upgrading to the latest version of Great Cow BASIC - the serial communication protocols have been improved in terms of the buad rates.
Ok, You have an exciting project. I haven't seen this little board/player until now. Last year I was trying to make a talking scada to annonouce some times and status over a handitalkie.I was working with the WTV020. I did get it counting the numbers to 120.
I have been looking on the net for info on the DFplayer and first thing is the manual's first example has a wrong checksum.
Their "FF DD is wrong. They used the right 6 values.
0 - ( FF + 06 + 09 + 00 + 00 + 04) = 0 - 0x0112 = 0x FEED
Next I would agree with Evan that the 16F1829 has a USART and it would be easy to use. Unless you need "inverted" output or you have already made a board and you have to cut traces to get to the usart pins.
How about this for the cmd_line?
That's all i got for now. i will be looking at this more. This is not tested code. I have concern about how CK will calculate. Am i even close to what your question is?
I will plug is you code and work with it.
BR
Mike
Please have a look at the attached program.
There are things to fix but it figures the right checksum and sends the right bytes.
I used Hardware Serial instead of soft serial. Check the pins! They have changed.
Have to figure out how to use the "Busy" signal.
The DFPlayer manual does have all the commands?? Where did you find the others?
@mkstevo. I think you may have to use a later version of the compiler to take advantage of the new functionality in GCB.
I originally thought I'd use the software serial as I thought I understood 'better' how to set it up. The hardware serial setup examples made rather less sense to me than the software setup examples.
At the moment my project has not progressed further than the feature list, so any pins can be used. The version of the program I have already that reads the inputs and currently plays audio via the VLSI Mp3 module has the pins for input and output currently allocated, but I've no particular preference otherwise.
According to the DFPlayer manual, the checksum is ignored so can probably be any value, the values I used were lifted straight from the PicAxe example program that I've used and modified to do as I need.
I, again, lifted the commands I wanted to use from a combination of the PicAxe example programs and the DFPlayer manual. I perhaps haven't included those that I am not interested in using. I gave those I was interested in using constant values so that I could more easily see what I was doing.
I'll add the PicAxe example manual.
The following program attempts to locate Track 01, in Folder 01 on a USB drive. If it fails to find the track on a USB disk it attempts to find Track 01, in Folder 01 on a MicroSD card.
Once started it will try to play Track 01 in Folder 01, then Track 01 from Folder 02, and so on until it runs out of folders. It then tries to play Track 02 of Folder 01 until it runs out of tracks, it then repeats. Not a great program, but proves the module is working. A portion of the program was copied wholesale from the given examples.
NOTE: The following is the PicAxe version of the program. IT WILL NOT WORK FOR Great Cow Basic, or a standard PIC.
Last edit: mkstevo 2016-02-16
I'd like to again thank you all for your kind help.
Sadly I won't be able to test the given example for at least two weeks as my work schedule will not give me time to do so. I really appreciate you taking the time to point me in the right direction. I will upgrade my GCB to V0.95 as soon as time allows. Once I've had time to try the module again I'll post my GCB version of the above program for comparison in the hope that it might assist others who may want to use this fabulously versatile Mp3 module.
I found an error in the send_cmd:
I was putting the cmd byte in the 3rd array element and it should be the 4th element.
Please change in your program.
I'm going to buy one of these modules for trying in one of my projects. Thanks for bringing my attention to this simpler mp3 than the wtv020 which took a special type of file. Then I will try finishing the subroutine drivers for this device.
Just a quick note of thanks for everyone's help so far.
I'm back at my desk today, in front of the PC, with time to look at this again.
I've gone with the software UART for the time being. Mostly I find the initialisation requirements much simpler to understand and the flexibility it offers allows me to map the serial out onto a pin of the PIC16F1825 which directly matches those of the PicAxe 14M2 device, allowing me to plug the PIC directly into the existing PicAxe demonstration PCB and run immediately.
I've compiled the following code which simply attempts to change to an external USB, sets the play volume to zero, checks to see if Track '01.mp3' can be played from Folder '01', if so it stops, sets the volume to 15, starts playback, waits until playback has finished and then plays Track '01.mp3' again.
Should a valid file/folder not be found on a USB device, the DFPlayerMini appears to silently default to the on board MicroSD Card(if fitted) as I only test to see if a file can be played to test if the USB is present, this could present a problem. The DFPlayerMini does have the option of returning serial data back to the host microprocessor which could possibly be read in order to determine more accurately whether the USB disk is present. I actually want the capability of falling back to the on board MicroSD card if the USB isn't found, so my simple method suits my needs.
Now to convert my PicAxe program to GCB...
Thanks again for the kind help, it has been greatly appreciated.
Last edit: mkstevo 2016-03-02
Yesterday (Easter Monday) I spent some time at work to try to progress this project a little farther with no other work related interruptions. I now have the bulk of my project working, with only one or two minor adjustments required.
I want to thank everyone who provided guidance regarding the serial initialisation required. I am truly grateful for your generosity.
I am also eternally grateful for all who have contributed to all the component parts that make up GCB. I really, really appreciate the hard work.
Hi Mkstevo, have been following this thread for a while. I am glad to see you made significant progress, and I agree, this forum is simply awesome! GCB is just wonderful and the fact that it is free on top of it, is the icing on the cake for sure. Would love to see your final code to make this module work correctly, if you care to share that is. This would be a good one to create a library for, I think.
The 'final' code is really the code I posted on 26th February but with the addition of the input detection that initiates playback of the appropriate track, at the appropriate time. I'm not sure I'm using it 'correctly'. I'm just making it work... Mmotte's code was much better and more flexible than mine is, it had checks for correctly calculating the checksum among other things. Things which I don't need, so have wilfully ignored.
This is for an old motor driven game. When the motor moves left/right, sound 1 is played, when it moves front/back sound 2 is played, when not moving sound 3 is played, when no game is being played background music is played. There are further sounds for win/lose situations and so on, but you get the idea.
For example, to play sound one :
If Motor_LR=1 Then
Play_Track(1,1)
End If
and for sound two:
If Motor_LR=1 Then
Play_Track(1,2)
End If
some sounds I want to play until they finish without being interrupted so for these:
If Game_Idle=1 Then
Play_Track(1,7)
Do
Wait 100 mS
Loop Until Player_Busy = 1 'Low=Playing, High=play has stopped
End If
The original sound was played through a large number of peripheral chips (processor, eprom, a/d, clock generators etc.) which I'm hoping to replace with a single processor (16C57 to 16F1829) and the DFPlayer module. This will give the option of playback from USB, rather than eprom meaning the sound files can be 'user updateable'.