Autor Tema: DFPlayer Mini  (Leído 6015 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
DFPlayer Mini
« en: 08 de Junio de 2017, 16:44:51 »
Hola gente del foro, estaba tratando de manejar el dfplayer mini pero no entiendo como se controla, no entiendo los comando, alguien tiene una libreria o me da un ejemplo de reproduccion de un MP3 guardado en la memoria? Gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:DFPlayer Mini
« Respuesta #1 en: 08 de Junio de 2017, 16:50:41 »
Todavia estas con ese modulo?, recuerdo que no sabias como se enviaba el comando, y te lo supe explicar. O estas buscando un ejemplo funcionando ?

https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299
« Última modificación: 08 de Junio de 2017, 17:00:57 por KILLERJC »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:DFPlayer Mini
« Respuesta #2 en: 09 de Junio de 2017, 16:52:58 »
Hola no estoy todavia sino que volvi, la verdad no entendi lo que me quisiste explicar, me supera. Quizas con algunos ejemplos logre controlarlo o consiga una libreria ya hecha, gracias por responder

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:DFPlayer Mini
« Respuesta #3 en: 09 de Junio de 2017, 17:13:55 »
.

Yo compré hace tiempo algunos de esos DFMini player y otros, y todos tenían sus pegas. Ese en concreto recuerdo que para disparar sonidos con envolvente de subida rápida me daba problemas, seguramente porque ese reproductor tiene algún tipo de control automático de volumen que mata las envolventes rápidas.

Otros reproductores de ese tipo, no me permitían reproducir el mismo sonido varias veces con rapidez, no podías reproducir el mismo sonido hasta que había acabado (mi aplicación era para una máquina recreativa que podía disparar el mismo sonido con repetición, antes de que acabara de reproducirse el propio sonido).

Al final, la mejor solución, la más versátil y además totalmente programable y configurable por el usuario es utilizar un Teensy (o una placa propia con el mismo microcontrolador Kinetis, MKL20, MK64, MK66) y las librerías de audio de PJRC (todo gratuito), con su generador online para construir tu dispositivo de audio a medida, sin necesidad de programar prácticamente nada, diseñas el dispositivo online en modo gráfico.

https://www.pjrc.com/teensy/td_libs_Audio.html
https://www.pjrc.com/teensy/gui/index.html



« Última modificación: 09 de Junio de 2017, 17:20:37 por planeta9999 »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:DFPlayer Mini
« Respuesta #4 en: 09 de Junio de 2017, 17:53:57 »
Muchas gracias por responder, la intencion es usar un PIC, una duda que me surgio leyendo el data del dfplayer es que no se como generar el byte de verificacion, alguien me da una idea?

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:DFPlayer Mini
« Respuesta #5 en: 14 de Junio de 2017, 11:46:56 »
Hola
Hola gente del foro, estaba tratando de manejar el dfplayer mini pero no entiendo como se controla, no entiendo los comando, alguien tiene una libreria o me da un ejemplo de reproduccion de un MP3 guardado en la memoria? Gracias
La verdad no entendi como es, si me ayudan solo quiero reproducir un mp3 desde la memoria sd y usar el comando next, a lo mejor entre todos podemos hacerlo,gracias

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:DFPlayer Mini
« Respuesta #7 en: 19 de Junio de 2017, 09:29:27 »
Gracias por responder, mi idea es no usar arduino

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:DFPlayer Mini
« Respuesta #8 en: 19 de Junio de 2017, 12:59:56 »
.

Eso da igual, los fuentes de Arduino te sirven de base para PIC, cambia cuatro cosas (si es necesario) y a funcionar. En esos fuentes puedes ver que comandos envía y como los envía. Es C, igual para todos los micros, y si por el compilador que usas alguna instrucción difiere, la cambias.

Yo no le veo la menor complejidad a lo que quieres hacer, es una simple comunicación serie, solo necesitabas saber que comandos enviar para cada función, y en esos fuentes lo tienes todo.

Estableces una comunicación serie a 9600bps y a enviar comandos. En este fuente tienes los comandos a enviar para cada función (reproducir, siguiente, anterior, volumen, ecualizador, bucle, etc...):

Código: [Seleccionar]
//
void mp3_play_physical (uint16_t num) {
mp3_send_cmd (0x03, num);
}

//
void mp3_play_physical () {
mp3_send_cmd (0x03);
}

//
void mp3_next () {
mp3_send_cmd (0x01);
}

//
void mp3_prev () {
mp3_send_cmd (0x02);
}

//0x06 set volume 0-30
void mp3_set_volume (uint16_t volume) {
mp3_send_cmd (0x06, volume);
}

//0x07 set EQ0/1/2/3/4/5    Normal/Pop/Rock/Jazz/Classic/Bass
void mp3_set_EQ (uint16_t eq) {
mp3_send_cmd (0x07, eq);
}

//0x09 set device 1/2/3/4/5 U/SD/AUX/SLEEP/FLASH
void mp3_set_device (uint16_t device) {
mp3_send_cmd (0x09, device);
}

//
void mp3_sleep () {
mp3_send_cmd (0x0a);
}

//
void mp3_reset () {
mp3_send_cmd (0x0c);
}

//
void mp3_play () {
mp3_send_cmd (0x0d);
}

//
void mp3_pause () {
mp3_send_cmd (0x0e);
}

//
void mp3_stop () {
mp3_send_cmd (0x16);
}

//play mp3 file in mp3 folder in your tf card
void mp3_play (uint16_t num) {
mp3_send_cmd (0x12, num);
}

//
void mp3_get_state () {
mp3_send_cmd (0x42);
}
// Wait for mp3_get_state reply
int mp3_wait_state () {
return mp3_recv_int_cmd(0x42);
}

//
void mp3_get_volume () {
mp3_send_cmd (0x43);
}
// Wait for mp3_get_volume reply
int mp3_wait_volume () {
return mp3_recv_int_cmd(0x43);
}

//
void mp3_get_u_sum () {
mp3_send_cmd (0x47);
}
// Wait for mp3_get_u_sum reply
int mp3_wait_u_sum () {
return mp3_recv_int_cmd(0x47);
}

//
void mp3_get_tf_sum () {
mp3_send_cmd (0x48);
}
// Wait for mp3_get_tf_sum reply
int mp3_wait_tf_sum () {
return mp3_recv_int_cmd(0x48);
}

//
void mp3_get_flash_sum () {
mp3_send_cmd (0x49);
}
// Wait for mp3_get_flash_sum reply
int mp3_wait_flash_sum () {
return mp3_recv_int_cmd(0x49);
}

//
void mp3_get_tf_current () {
mp3_send_cmd (0x4c);
}
// Wait for mp3_get_tf_current reply
int mp3_wait_tf_current () {
return mp3_recv_int_cmd(0x4c);
}

//
void mp3_get_u_current () {
mp3_send_cmd (0x4b);
}
// Wait for mp3_get_u_current reply
int mp3_wait_u_current() {
return mp3_recv_int_cmd(0x4b);
}

//
void mp3_get_flash_current () {
mp3_send_cmd (0x4d);
}
// Wait for mp3_get_flash_current reply
int mp3_wait_flash_current () {
return mp3_recv_int_cmd(0x4d);
}

//
void mp3_single_loop (boolean state) {
mp3_send_cmd (0x19, !state);
}

//add
void mp3_single_play (uint16_t num) {
mp3_play (num);
delay (10);
mp3_single_loop (true);
//mp3_send_cmd (0x19, !state);
}

//
void mp3_DAC (boolean state) {
mp3_send_cmd (0x1a, !state);
}

//
void mp3_random_play () {
mp3_send_cmd (0x18);
}

// Query total file numbers of a folder
void mp3_get_folder_sum (uint16_t folder) {
mp3_send_cmd (0x4E, folder);
}
// Wait for mp3_get_folder_sum reply
int mp3_wait_folder_sum () {
return mp3_recv_int_cmd(0x4E);
}

// Play mp3 file in selected folder
void mp3_play_file_in_folder (uint8_t folder, uint32_t num) {
mp3_send_cmd (0x14, folder, num);
}




« Última modificación: 19 de Junio de 2017, 13:11:07 por planeta9999 »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:DFPlayer Mini
« Respuesta #9 en: 19 de Junio de 2017, 16:57:59 »
Fijate aca: https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299 a ver si me podes decir que es par1 y par2 y como se calcula checksum

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:DFPlayer Mini
« Respuesta #10 en: 19 de Junio de 2017, 17:23:17 »
.

En el enlace que pones no sale ni par1 ni par2, y checksum como variable, tampoco.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:DFPlayer Mini
« Respuesta #11 en: 19 de Junio de 2017, 18:41:48 »
es para1 y para2. Algunas instrucciones ademas del byte de comando, poseen parametros. Y es alli donde van, no todos lo poseen.

http://www.picaxe.com/docs/spe033.pdf

En el punto 3, se enceuntra la tabla.

Respecto al Checksum y como calcularlo se lo habia explicado en otro tema que habia abierto soymoe

http://www.todopic.com.ar/foros/index.php?topic=47536.msg395740#msg395740

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:DFPlayer Mini
« Respuesta #12 en: 19 de Junio de 2017, 19:01:47 »
.

Prueba con el terminal Hercules, y le envías desde el PC el comando con todos sus parámetros en hexadecimal, y vas viendo si responde el reproductor. Cualquier respuesta que te devuelva el DFPLayer también la verás en la pantalla del terminal.

http://www.hw-group.com/products/hercules/index_es.html


En cuanto al cálculo del checksum, lo tienes en la librería para Arduino del enlace que te puse, ahí de hecho está todo, usar esa librería desde un PIC u otro microcontrolador es muy fácil.


Cálculo del checksum. Muy sencillo, lo hace con los elementos 1 a 6 del array a enviar de 10 elementos, y es tan simple como sumar esos 6 elementos (multiplicado por -1), eso es todo.

Código: [Seleccionar]
//calc checksum (1~6 byte)
uint16_t mp3_get_checksum (uint8_t *thebuf) {
uint16_t sum = 0;
for (int i=1; i<7; i++) {
sum += thebuf[i];
}
return -sum;
}

//fill checksum to send_buf (7~8 byte)
void mp3_fill_checksum () {
uint16_t checksum = mp3_get_checksum (send_buf);
fill_uint16_bigend (send_buf+7, checksum);
}


//
static void fill_uint16_bigend (uint8_t *thebuf, uint16_t data) {
*thebuf = (uint8_t)(data>>8);
*(thebuf+1) = (uint8_t)data;
}


La construcción del buffer completo para enviar el comando con su checksum.

Código: [Seleccionar]
//
void mp3_send_cmd (uint8_t cmd, uint16_t high_arg, uint16_t low_arg) {
unsigned long d = abs(millis() - _last_call);
if (d < 50) {
delay(50 - d);
}

send_buf[3] = cmd;

send_buf[5] = high_arg;
send_buf[6] = low_arg;

mp3_fill_checksum ();
send_func ();

_last_call = millis();
}



Función para enviar el buffer por puerto serie. Se trata de un array de 10 elementos. En el elemento 3 está el comando, en el 5 y 6 los parámetros (si el comando necesita parámetros), en el elemento 7 está el checksum, etc... el detalle de cada elemento lo tienes en tu enlace sobre el producto. Haz las pruebas con el terminal Hercules desde el PC, y descubriras con facilidad como funciona todo, antes de ponerte a programar con el PIC, aunque si usas la librería que te indiqué, ya está todo programado.
 
Código: [Seleccionar]
//
void h_send_func () {
for (int i=0; i<10; i++) {
_hardware_serial->write (send_buf[i]);
}
}







« Última modificación: 20 de Junio de 2017, 10:45:02 por planeta9999 »

Desconectado soymoe

  • PIC18
  • ****
  • Mensajes: 456
    • El blog de Moe
Re:DFPlayer Mini
« Respuesta #13 en: 20 de Junio de 2017, 09:11:53 »
quiero saber como seria el checksum en este caso:
1).For example, select the first song played, seria
l transmission section: 7E FF 06 03 00 00 01 FF E6
EF
7E --- START command
FF --- Version Information
06 --- Data length (not including parity)
03 --- Representative No.
00 --- If need to acknowledge [0x01: need answering
, 0x00: do not need to return the response]
00 --- Tracks high byte [DH]
01 --- Tracks low byte [DL], represented here is th
e first song played
FF --- Checksum high byte
E6 --- Checksum low byte
EF --- End Command

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:DFPlayer Mini
« Respuesta #14 en: 20 de Junio de 2017, 12:31:22 »
.

Guíate por las rutinas de la librería que te he indicado, o directamente usa esa rutina, y no te compliques la vida. Además el ejemplo del manual está mal calculado, en los foros del producto los propios creadores reconocen las erratas del manual, pero confirman que las rutinas funcionan.

Si buscas por internet, te volverás mico, porque cada persona lo interpreta como le da la gana, y lo calcula de las formas más variopintas, yo he leído algunos de esos post, y no entiendo ni PAPA de como lo están calculando. Más bien parece que cada uno lo acomoda a su gusto o para que el resultado cuadre con lo esperado aunque no tengan ni idea de porque lo hacen así (es lo que parece).


A ver, rutina 1 del cálculo del checksum, esta no tiene ningún misterio, suma los elementos 1 a 6 y el resultado lo multiplica por -1.

Código: [Seleccionar]
//calc checksum (1~6 byte)
uint16_t mp3_get_checksum (uint8_t *thebuf) {
uint16_t sum = 0;
for (int i=1; i<7; i++) {
sum += thebuf[i];
}
return -sum;
}


Rutina 2 (y 3), la madre del cordero, el byte 1 del checksum, lo sacan desplazando 8 bits a la derecha el cálculo anterior.
*thebuf =   (uint8_t)(data>>8 );

Y el segundo byte es el mismo checksum calculado en la rutina anterior, sin ninguna otra alteración.
*(thebuf+1) =   (uint8_t)data;

 ¿ Porque lo hacen así ?, ni puñetera idea, ni se explica así ni de ninguna manera en el manual (castaña de manual, pésimo, para hacer fuego en invierno).

Código: [Seleccionar]
//fill checksum to send_buf (7~8 byte)
void mp3_fill_checksum () {
uint16_t checksum = mp3_get_checksum (send_buf);
fill_uint16_bigend (send_buf+7, checksum);
}

//
static void fill_uint16_bigend (uint8_t *thebuf, uint16_t data) {
*thebuf = (uint8_t)(data>>8);
*(thebuf+1) = (uint8_t)data;
}



Yo tengo un lema en la vida, "TODO, absolutamente TODO (sin excepción), es MUY sencillo, cuando se explica correctamente y con intención de que sea entendido", de lo contrario o está mal documentado o mal explicado.

Esto del cálculo del checksum para este producto, es el típico ejemplo de como marear al usuario para que no entienda nada, no documentándolo, como dios manda, en el manual del producto. Resumiendo, usa esas rutinas en tu código y no te calientes la cabeza, meter eso en un PIC no tiene mayor complicación.
« Última modificación: 20 de Junio de 2017, 13:01:41 por planeta9999 »


 

anything