Reproductor MP3 – Music Maker Feather Wing con ARDUINO MKR1000

Luego de probar con ARDUINO UNO, ahora vamos a explorar el ARDUINO MKR1000 con el Music Maker de Adafruit

Esta publicación se basa en mucho en el video sobre el mismo tema ubicado acá: https://www.youtube.com/watch?v=EtmxK0SjqAY

También se basa en el tutorial inicial del Music Maker Featherwing ubicado acá: https://learn.adafruit.com/adafruit-music-maker-featherwing/overview

Materiales

  • 1x Music Maker Feather Wing de Adafruit
  • 1x Arduino MKR1000
  • 10x Cables de conexión H/M de diversos colores.

La siguiente imagen muestra un diagrama de bloques que ejemplifica cada componente.

El controlador ejecuta un programa que se encarga de controlar al reproductor. Este controlador es programado mediante una PC y un software llamado el IDE de ARDUINO. Nótese que para controlar el reproductor, se usan dos canales de comunicación: uno de tipo SPI (para enviar comandos) y otro de tipo control (para “hablar” con los diferentes circuitos del reproductor MP3)

El reproductor lee la información de la tarjeta SD y ejecuta la música.

Figura 1 – Diagrama de Bloque

Conexiones

Haz clic acá para ver los pines del MKR1000
Pines del MKR1000

Tenemos tres grupos de conexión.

Puerto SPI: Por un lado los pines 8, 9 y 10 del MKR1000 que se conectan a los pines MOSI, SCK y MISO del Wing.

Puerto de Control: Por otro lado tenemos los pines 6,7,11,12 del MKR1000 que se conectan a los pines DREQ, MP3CS, SDCS y XDCS respectivamente en el Wing.

Finalmente los pines VCC, GND y RESET van en sus equivalentes en el Wing.

(!) Inicialmente probamos con otros pines de control (3,4,6,7) pero no funcionaba. Creemos que esta falla se debía a algun tipo de incompatibilidad con los puertos PWM del MKR1000 pues al moverlos a puertos que no son PWM todo funcionó bien.

También es importante notar que el WING es muy suceptible a fallas de conexión en sus pines. Por eso en esta ocasión omitimos el protoboard.


Figura 2 – Conexiones entre Music Maker y MKR1000

Programación

El programa propuesto en el video está basado en el programa que viene como ejemplo en la librería de Adafruit VS1053

Haz clic para ver el programa
// ADAPTADO DEL TUTORIAL DE ADAFRUIT
// INCLUIR LIBRERIAS PARA SPI, MP3 and SD
#include <SPI.h>
#include <SD.h>
#include <Adafruit_VS1053.h>

/*PINES CONECTADOS A ARDUINO UNO*/
#define VS1053_RESET   -1     // PIN DE RESET DEL VS1053. -1 = NO SE USA.
#define VS1053_CS       7     // PIN DE SELECCION DE CHIP VS1053
#define VS1053_DCS      12     // XDCS: PIN DE DATOS/COMANDOS DE CHIP VS1053
#define CARDCS          11     // PIN DE SELECCION DE TARJETA SD
#define VS1053_DREQ     6     // (!) INT PIN DE SOLICITUD DE INTERRUPCION/DATOS PARA CHIP VS1053

/*VALORES DE PINES DE REFERENCIA PARA CONEXION SPI*/
#define MISO           12
#define MOSI           11
#define SCK            13

//INSTANCIAR EL MUSIC PLAYER
Adafruit_VS1053_FilePlayer musicPlayer = 
  Adafruit_VS1053_FilePlayer(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ, CARDCS);

//FUNCION SETUP SE EJECUTA SOLO UNA VEZ AL INICIAR EL PROGRAMA
void setup() {
  //INICIALIZAMOS EL PUERTO SERIAL (para poder tener resultados en la pantalla de monitor serial)
  Serial.begin(115200);
  delay(2000); //Esperamos 2 segundos para que el puerto responda.
  
  Serial.println("\n\nAdafruit VS1053 Feather Test");

  //INICIALIZAMOS EL MUSIC PLAYER
  if (! musicPlayer.begin()) {
     Serial.println(F("NO SE ENCONTRÓ EL VS1053. ¿Están bien conectados los pines?"));
     while (1);
  }

  Serial.println(F("ENCONTRÉ EL VS1053"));

  //GENERAMOS UN TONO DE VERIFICACIÓN....
  musicPlayer.setVolume(3,3); //VOLUMEN (EL MAS ALTO SERÍA 0,0)
  musicPlayer.sineTest(0x44, 2000);

  //INICIALIZAMOS LA TARJETA SD
  if (!SD.begin(CARDCS)) {
    Serial.println(F("LA TARJETA SD HA FALLADO O NO HAY TARJETA. ¿Será que la tarjeta es de tecnología muy reciente o muy grande?"));
    while (1);  // PARALIZAR
  }
  Serial.println("SD OK!");
  
  // LISTAR ARCHIVOS DE LA TARJETA SD
  printDirectory(SD.open("/"), 0);
  
  // SUBIMOS EL VOLUMEN AL MAXIMO
  musicPlayer.setVolume(0,0);

  //DEFINIMOS PUERTO DE INTERRUPCIONES
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
    
  // REPRODUCIMOS UN ARCHIVO COMPLETO, SE REQUIERE EL USO DE INTERRUPCIONES PARA PARAR!!!
  Serial.println(F("Playing full track 001"));
  musicPlayer.playFullFile("/TRACK001.MP3");
  musicPlayer.setVolume(3,3);
  
  // REPRODUCIMOS UN ARCHIVO EN EL BACKGROUND
  Serial.println(F("Playing track 002"));
  musicPlayer.startPlayingFile("/TRACK002.MP3");
}

void loop() {
  //ACA IMPLEMENTAMOS LÓGICA DE CONTROL DEL BACKGROUND
  Serial.print(".");

  //DETERMINAR SI EL MUSICPLAYER ESTÁ DETENIDO...
  if (musicPlayer.stopped()) {
    Serial.println("HE TERMINADO DE REPRODUCIR MUSICA");

    //CICLO ETERNO QUE NO HACE NADA:
    while (1) {
      delay(10);  
    }
  }

  //DETERMINAR SI HAY DATOS EN EL PUERTO SERIAL ENVIADOS AL ARDUINO UNO.
  if (Serial.available()) {
    char c = Serial.read();
    
    // SI EL COMANDO ES LA LETRA 's' DETENEMOS LA EJECUCIÓN
    if (c == 's') {
      musicPlayer.stopPlaying();
    }
    
    // SI EL COMANDO ES UNA 'p' HACEMOS PAUSA O LA QUITAMOS
    if (c == 'p') {
      if (! musicPlayer.paused()) {
        Serial.println("Paused");
        musicPlayer.pausePlaying(true);
      } else { 
        Serial.println("Resumed");
        musicPlayer.pausePlaying(false);
      }
    }
  }
  delay(100);
}

/// HACE UNA LISTA DE TODOS LOS ARCHIVOS EN LA TARJETA SD
void printDirectory(File dir, int numTabs) {
   while(true) {
     
     File entry =  dir.openNextFile();
     if (! entry) {
       // NO HAY MÁS ARCHIVOS
       Serial.println("** NO HAY MÁS ARCHIVOS**");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}

Notas Importantes

  1. Pin de Interrupción: El pin del WING DREQ debe estar conectado a un pin en el MKR1000 que tenga capacidad de generar interrupciones. Por eso usamos el pin 6 en el MKR1000 para tal efecto.
  2. Archivos: En las líneas 62 y 66 queda claro que se necesita que haya un archivo de nombre “TRACK001.MP3” y otro de nombre “TRACK002.MP3” en la carpeta raíz de la tarjeta SD.
  3. Problemas SD: Interesantemente la tarjeta SAMSUNG de 32GB EVO Plus no presentó problemas de funcionamiento. En el artículo anterior sobre ARDUINO UNO experimentamos problemas con esa tarjeta.
  4. Conector de Audífonos: También es importante destacar que el conector de audífonos de 4 canales (los que traen los celulares) no funciona bien en el reproductor, hay que introducirlo a medio camino para que suene bien. El conector que si funciona es el de tres canales (L/R/GND) que no trae conexion de micrófono ni circuitería de control de volumen.

Retos

¿Qué tal modificar el programa para que ejecute el primer archivo MP3 que aparece en la raiz de la tarjeta SD?

¿Y si hacemos que ejecute de forma continua sin parar todos los archivos MP3 que vengan en la tarjeta SD?

¿Qué tal agregar botones para pausa, reaundación y cambio de canción?

Figura 3 – Conexiones del MKR1000

60 total views, 2 views today

0Shares

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.