|
|
View previous topic :: View next topic |
Author |
Message |
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
18f46k22 uart df mini player |
Posted: Wed Nov 09, 2016 1:40 am |
|
|
Dear all, I want to communicate between pic18f46k22 and df mono player. I send char data, I can see it on Proteus virtual terminal, but I can't get workıng df mini player.
My code:
Code: |
#include <18F46K22.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(internal=32MHz)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
void main()
{
set_tris_d(0XFF);
set_tris_C(0X00);
int i=0;
char calistir[10]={0x7E,0xFF,0x06,0x09,0x00,0x00,0x02,0xFF,0xE6,0xEF};// İLK BAŞLANGICI VERECEK DİZİYİ TANIMLADIK
//putc(0xef);
for(i=0;i<10;i++){
//output_bit(pin_d0,1);
output_d(0xff);
delay_ms(100);
output_d(0x00);
delay_ms(100);
fputc(calistir[i]);
delay_ms(1);} // while(i=10)
} |
|
|
|
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Wed Nov 09, 2016 2:49 am |
|
|
The device takes up to 3 seconds to initialise the external memory. You need to be waiting to see the 'TF card online' data from the controller, before you can start to play.
You are almost certainly sending the command before the controller is ready. You have got a TF card fitted?. |
|
|
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
|
Posted: Wed Nov 09, 2016 5:18 am |
|
|
Ttelmah wrote: | The device takes up to 3 seconds to initialise the external memory. You need to be waiting to see the 'TF card online' data from the controller, before you can start to play.
You are almost certainly sending the command before the controller is ready. You have got a TF card fitted?. |
Yes I have tf card on df mini player. I think ıf I can send start data array for first song, df mını player workıng. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Wed Nov 09, 2016 6:35 am |
|
|
First, are you using 3 Volt or 5 Volt for system? If 5 then you need 1K in TX, RX lines (as per manual...)
2nd, I don't see how you came up with the 'checksum'. I didn't see in the manual how to calculate it either and that's very, very important. If the checksum is wrong, the unit should NOT function. It should timeout or reset or go back to 'command mode' or 'wait for new data....
Without having the hardware here to test I can only go by what's in the manual. You should be able to 'read' some registers to confirm you are talking to it!
I did see some Arduino code in Google, maybe look at it, compare to what you have ??
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Wed Nov 09, 2016 9:05 am |
|
|
The data sheet says the device takes longer to wake for different devices. The Arduino sample code waits a second before trying to send anything. You only have 200mSec. Then the command must complete within a short time or the device will timeout. You are pausing 201mSec between each byte....
The device will be sending you data. You do not read it, and have not got ERRORS in the RS232 setup. Repeat 50* 'I must always use the ERRORS parameter on a hardware UART, unless I am handling errors myself'. The receive UART will therefore go into a hung state.
Then the last two characters will not get sent. Shows the error of believing Proteus....
Then you must have the data in the right format on the card (must be in a directory called mp3), and the card itself must be the right format (for most cards you need to stick with a 2GB max). The TF format is different from SD once you go over 2GB.
Assuming you have got this all right, then try:
Code: |
#include <18F46K22.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(internal=32MHz)
#use rs232(baud=9600, parity=N, UART1, bits=8, ERRORS, stream=PORT1)
void main(void)
{
int i=0;
char calistir[10]={0x7E,0xFF,0x06,0x09,0x00,0x00,0x02,0xFE,0xF0,0xEF};// İLK BAŞLANGICI VERECEK DİZİYİ TANIMLADIK
//variable initialisation should be before any commands
set_tris_d(0XFF);
set_tris_C(0X00);
delay_ms(2300); //allow the worst case wake up time for TF.
output_d(0xff); //flash LED
delay_ms(100);
output_d(0x00);
for(i=0;i<10;i++)
{
fputc(calistir[i], PORT1); //fputc requires a stream name
}
output_d(0xff); //flash LED agin to say finished.
delay_ms(100);
output_d(0x00);
while (TRUE)
; //stop the code dropping off the end.
}
|
As Temtronic says, your checksum is wrong. Have corrected it. The checksum on this chip is simply minus the 16bit sum of the six bytes preceding it.
So: 0xFF+0x06+0x09+0x00+0x00+0x02 = 0x110
Then 0-0x110 = 0xFEF0 sent MSB first.
Many of the online examples seem to have this wrong....
This example has this right:
<https://forum.arduino.cc/index.php?topic=241021.0>
You will see he also has a problem that the module sometimes takes longer to boot (up to 20seconds!....). Really does mean you need to be testing the status bit, or waiting for the signal to say the card is initialised before trying to play. |
|
|
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
|
Posted: Fri Nov 11, 2016 3:28 am |
|
|
thanks a lot Ttelmah and temtronic. it is working .problem is checksum.unfortunately df mını player datasheet wrong calculate checksum.how wrong writing datasheet,ı dont believe .now ı am tryıng calculet to checksum, but ıf ı write cmd (command means) on array
unsigned int ses[i][10]={0X7E, 0xFF, 0x06, cmd, 0x00, 0x00, 0x03, 0xFE, 0xF5,0XEF};// İLK BAŞLANGICI VERECEK DİZİYİ TANIMLADIK
and ı want to fınd seperating msb lsb (0xML) .ıf ı dont fınd ı thınk divide to 8
Best wishes
BULDUK |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Fri Nov 11, 2016 4:06 am |
|
|
Use the CCS function make8, or a union. Much more efficient.
So:
Code: |
void Checksum(unsigned int8 * data)
{
union {
unsigned int8 bytes[2];
unsigned int16 word;
} value; //allows us to talk to a 16bit value, and it's two bytes
unsigned int8 ctr;
value.word=0; //clear the checksum
data++; //skip the first byte
for (ctr=0;ctr<6;ctr++)
value.word+=*(data++); //generate the checksum
value.word = -value.word; //-ve checksum
data[0]=value.bytes[1]; //MSB of result
data[1]=value.bytes[0]; //LSB of result
//remember data has been incremented and now points to the checksum
return;
}
//then in the main
unsigned int ses[10]={0X7E, 0xFF, 0x06, cmd, 0x00, 0x00, 0x03, 0xFE, 0xF5,0XEF};
Checksum(ses); //generate the checksum of bytes 1 to 7
//stores the result in the next two bytes
|
This then fills in the checksum for any command string it is handed |
|
|
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
|
Posted: Fri Nov 11, 2016 6:54 am |
|
|
Wow thanks a lot but ccs c compiler say "expression must evaluate to a constant". Why it array not write don't constant ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Fri Nov 11, 2016 8:27 am |
|
|
That's your 'cmd'. You can't put a variable into a declaration of an array. The code compiles (I #declared cmd). What you should be doing is filling the array with fixed values, then writing into ses[3] your command value, plus any other bytes you want to change to match the command, then generate the checksum. |
|
|
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
|
Posted: Fri Nov 11, 2016 9:00 am |
|
|
you said means that?
#define cmd
....
....
char ses[10]={0X7E, 0xFF, 0x06, "cmd", 0x00, 0x00, 0x03, 0xFE, 0xF5,0XEF};
I was that but agaın same error |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Fri Nov 11, 2016 10:15 am |
|
|
I assumed from your having a value in there called 'cmd', that you want to be able to change this to support something like a variable in future?.
Code: |
#define cmd 0x6 //Or whatever fixed value you want
....
....
char ses[10]={0X7E, 0xFF, 0x06, cmd, 0x00, 0x00, 0x03, 0xFE, 0xF5,0XEF};
|
This will then compile. However 'cmd' would need to be changed at compile time.
If you then want to change the value in the code:
Code: |
ses[3]= 0x8; //change command to 0x8
Checksum[ses]; //calculate the new checksum for this command
|
Now in fact you will have to change other bytes (according to what the command 'is'). But the basic behaviour remains the same. Change the bytes, then calculate the checksum. |
|
|
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
|
Posted: Mon Nov 14, 2016 1:19 am |
|
|
if I define all array it is working, but checksum is not calculate. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Mon Nov 14, 2016 4:07 am |
|
|
As posted:
Code: |
//header for chip with RS232 setup here
void Checksum(unsigned int8 * data)
{
union {
unsigned int8 bytes[2];
unsigned int16 word;
} value; //allows us to talk to a 16bit value, and it's two bytes
unsigned int8 ctr;
value.word=0; //clear the checksum
data++; //skip the first byte
for (ctr=0;ctr<6;ctr++)
value.word+=*(data++); //generate the checksum
value.word = -value.word; //-ve checksum
data[0]=value.bytes[1]; //MSB of result
data[1]=value.bytes[0]; //LSB of result
return;
}
void print_check(unsigned int8 * data)
//diagnostic routine to print the checksum to the serial
{
// The checksum is bytes 7 and 8 in the ses array
printf("MSB = %02x, LSB = %02x\n\r", data[7], data[8]);
}
void main()
{
unsigned int ses[10]={0X7E, 0xFF, 0x06, 6, 0x00, 0x00, 0x03, 0x00, 0x00,0XEF};
//Initilise array with checksum empty
print_check(ses); //print the checksum - should be zero here
Checksum(ses); //generate the checksum - bytes 1 to 7
//stores the result in the next two bytes
print_check(ses); //now display the calculated checksum
ses[3]=0x8; //change command to 8
ses[5]=1; //playback mode folder repeat
Checksum(ses); //calculate new checksum
print_check(ses); //and print the checksuk for this
while(TRUE)
{ //stop and do nothing else
}
}
|
This merrily prints:
MSB = 00, LSB = 00
MSB = fe, LSB = f2
MSB = fe, LSB = ef
So it is filling in the checksum (0xFEF2), then changing the command, and recalculating the checksum. |
|
|
craftsman42
Joined: 08 Nov 2016 Posts: 8
|
|
Posted: Mon Nov 14, 2016 4:35 am |
|
|
thanks now checksum is working |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|