sábado, 1 de febrero de 2014

Arduino reproductor de voz mediante tarjeta SD - Interface LCD

Página principal

Arduino reproductor de voz mediante tarjeta SD

Interface LCD

wav - 8bits -11KHz

xsetaseta@gmail.com

Continuando con mi anterior montaje  Arduino reproductor de voz mediante SD, ahora realizo un interface mediante 2 botones, un potenciómetro y un LCD.
La elección del potenciómetro para seleccionar las canciones es un motivo práctico, de fácil realización y sencillo.
Mediante el potenciómetro seleccionamos las canciones que deben estar creadas en la SD como números del 0 al 63 y con la extensión wav , ejemplo: 1.wav . Para su reproducción pulsamos el botón PLAY y para parar el botón STOP.
Las canciones tienen que estar en formato wav, mono , resolución 8bits y con una frecuencia de 11KHz.
En este formato cada minuto ocupa 0.65M, con lo cual con una tarjeta de 4G  tendremos 6153 minutos, unas 102 horas.
La tasa de frecuencia de muestreo de 11KHz es suficiente para la reproducción de voz .

Esquema del circuito.


Montaje del circuito.

Vídeo del funcionamiento



Muestra de una señal de 500Hz.


//SETA43
//xsetaseta@gmail.com
//arduvoc  Reproductor de audio con arduino
//01/02/2014


#include <LiquidCrystal.h>

LiquidCrystal lcd(7,6,5,4,3,2);

int sensorValue ;
int oldsensorValue=-1;

#include <SD.h>
File dataFile;

String inputString = ""; 
char fileplay[20] ;
boolean stringComplete = false; 

byte valor;
byte bufer0[100];
byte bufer1[100];
int din=0;
int dout=0;
byte nf=0;
byte vacio=1;
byte fin=1;

byte e1Pin=18;
byte e2Pin=19;

void setup()
{
  lcd.begin(16, 2);
  pinMode(9, OUTPUT); //Salida audio

 // pinMode(4, OUTPUT);    // si utilizamos la salida 4 como CS de la tarjeta SD
 // if(!SD.begin(4)){    // 
   pinMode(10, OUTPUT);    // si utilizamos la salida 4 como CS de la tarjeta SD
  if(!SD.begin(10))
  {
    lcd.print("ERROR Tarjeta ");    // Texto informativo
    return;
  }
  else
  {
    lcd.print("Tarjeta OK ");    // Texto informativo
  }   
  delay(900);
  lcd.clear();
  lcd.print("Arduino VOC");
  delay(500);
  lcd.clear();
   
 cli();//stop interrupts

  //timer1 PWM 31KHz
  TCCR1A = 0x81;
  TCCR1B = 0x01;
  OCR1A = 255;
  TIMSK1=0;

  //set timer2 interrupt at 11kHz
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2  = 0;
  OCR2A = 182;
  TCCR2A =2;
  TCCR2B =2;     
  TIMSK2=2;
 
sei();//allow interrupts
 
}
//end setup


ISR(TIMER2_COMPA_vect)  //timer1 interrupt 11kHz toggles
{
 if(fin==0)
  {
  if(nf==0)
    valor=bufer1[dout];
   else
    valor=bufer0[dout];
   
  dout++;
  if(dout>99)
    {
     vacio=1;
     dout=0;
     if(nf==1)
       nf=0;
      else
       nf=1;      
    } 
  OCR1AH = 0;
  OCR1AL = valor;    
  }
}


void loop()
{
    if(!digitalRead(e2Pin))
        {
         clearBuffer();        
         lcd.clear();
         lcd.setCursor(0, 0); lcd.print("PLAY WAV "); lcd.print(inputString);
         inputString.toCharArray(fileplay,19);
         dataFile.close();
         dataFile = SD.open(fileplay,FILE_READ);
         //dataFile = SD.open("11.wav",FILE_READ);
         while(!digitalRead(e2Pin));
         if (dataFile)
          {          
           for(din=0;din<200;din++) dataFile.read(); //quita 200 bytes del wav
           fillBuffer(); 
           fin=0;         
          }
          else
          {
           lcd.setCursor(0, 0); lcd.print("NO   WAV ");          
          }                           
        }
       
    if(!digitalRead(e1Pin))
        {           
         clearBuffer();
         dataFile.close(); 
         lcd.setCursor(0, 0); lcd.print("STOP WAV ");  
         while(!digitalRead(e1Pin));        
        }

  sensorValue = analogRead(A0)>>4;
  if(oldsensorValue != sensorValue)
    {
    inputString=String(sensorValue,DEC);
    inputString+=".wav";
    lcd.setCursor(0, 1);
    lcd.print(inputString);
    lcd.print("    ");
    }
  oldsensorValue = sensorValue;
  fillBuffer();
}


//Borrar buffer
void clearBuffer()
{
   fin=1;
   for(din=0;din<100;din++){ bufer0[din]=128;  bufer1[din]=128;} //vacia bufer
}

//llenado de buffer
void fillBuffer()
{  
  if(vacio == 1 && fin == 0)
    {    
     if(nf==0)
       for(din=0;din<100;din++) bufer0[din] = dataFile.read();
      else
       for(din=0;din<100;din++) bufer1[din] = dataFile.read();
      
     vacio=0;
     if(!dataFile.available())
       {
         lcd.setCursor(0, 0); lcd.print("END  WAV ");
         fin=1;
         for(din=0;din<100;din++){ bufer0[din]=128;  bufer1[din]=128;} //vacia bufer        
       }
    }  
}

Código fuente.




Saludos
Juan Galaz



Bibliografía:
http://ravc00cs.blogspot.com.es/2012/07/pwm.html
https://github.com/TMRh20/TMRpcm/wiki
http://apcmag.com/arduino-project-5-digital-audio-player.htm
http://arduino-info.wikispaces.com/Arduino-PWM-Frequency
http://hykrion.com/?q=node/153
http://arduino.cc/es/Tutorial/SecretsOfArduinoPWM