Mostrando entradas con la etiqueta Frecuencia. Mostrar todas las entradas
Mostrando entradas con la etiqueta Frecuencia. Mostrar todas las entradas

Generar sonido con PIC

En los tiempos que corren estamos acostumbrados a vivir rodeados de tecnología, hoy en día cualquier movil supera en millones de operaciones por segundo al primer ordenador que tuve, hasta un PIC puede funcionar a mas velocidad que un 80286, pero hubo un tiempo en que un teléfono movil no estába al alcance de cualquiera, y en esa época no existían aparatos capaces de brindarnos la experiencia multimedia que hoy damos por sentado de que es así. Y estamos hablando de poco menos de 20 años atras, en esa epoca por lo menos los PC normales, no disponían de una placa de sonido y cualquier juego ejecutaba a duras penas un, a veces, desesperante pitido a modo de música.

Bueno, es por eso que en un arrebato de nostalgia se me ocurrió que podría emular esas "dulces" melodías con un PIC y es por eso que ahora tu estás leyendo esto. Inmediatamente despues me acordé de algo muy importante y es que no tengo ni la mas remota idea de música. Entonces decidí comenzar por el lugar mas obvio, o sea por el principio, fue cuando deduje que para que haya música primero tiene que haber sonido, entonces lo primero que hay que hacer es que el PIC emita algo de sonido controlado, ya habrá tiempo de generar notas musicales.

Primero hay que tener un concepto aunque sea básico de lo que el sonido es, en principio el sonido es un golpe en un medio, en nuestro caso el aire y, dependiendo de la frecuencia de ese "golpe", el sonido producido será mas agudo o mas grave; El oido humano puede percibir sonidos con una frecuencia que está comprendida entre los 20Hz y los 20KHz, en otras palabras que una persona puede escuchar frecuencias de esos golpes desde unas 20 veces por segundo hasta unas 20 mil aproximadamente. Entonces aquí ya tenemos un dato: para generar el sonido con el PIC debemos conectar un altavoz a una salida del microcontrolador y hacer alternar su estado de alto a bajo a una frecuencia determinada. Cuanto mas rápido se varíe el estado mas agudo será el sonido y viceversa.

Para obtener la duración del periodo (estado alto o bajo) para una frecuencia f solo hace falta usar la siguiente formula:

tP = 1
f

Para generar un sonido dentro de los margenes perceptibles, digamos de unos 650Hz realizaremos la siguiente operación:

tP = 1
650
= 0,0015385

El resultado obtenido es el tiempo, en segundos, que debe tardar cada periodo para producir un sonido de 650Hz. En este caso es 1538uS que es la medida que nosotros necesitamos para operar con el PIC, recuerda que un PIC con un cristal corriendo a 4 MHz realiza una operacion cada 1uS.

Cada 1538uS o, lo que es lo mismo, cada 1,538mS se debe producir un cambio de estado del la salida del microcontrolador para producir un sonido a 650Hz, entonces lo que necesitamos ahora es dividir ese valor en 2, una mitad para el estado alto y la otra mitad en estado bajo.

Con todo esto tenemos que: 1538 / 2 = 769, si traducimos esta teoría en lenguaje C quedaría de esta forma:

#include <16f876a.h>          // Tipo de microcontrolador
#use delay(clock=4000000)     // Delay con xtal de 4MHz
#use fast_io(all)             // I/O todas rápidas, de esta forma cuando se
                              // escribe en los puertos, no se configura el tris
                              // acelerando el proceso.  
#fuses HS                     // FUSES cristal HS >=4MHz 
#FUSES NOPUT                  // No power up Timer, no espera a estabilizar la tension 
#FUSES NOBROWNOUT             // No Brown out reset, no se resetea si cae la tension  
#define Speaker   PIN_B0      // Altavoz conectado a RB0  

void main(){
   
   set_tris_b(2); // RB<7:2> Salida RB1 entrada (Pulsador) RB0 Salida (Speaker)
   
   do{                              // Bucle infinito
      
      while(input(PIN_B1)){         // Mientras se presione el
                                    // interruptor conectado a RB1.
                                    
         output_high(Speaker);      // Altavoz encendido
         delay_us(769);             // espera 769 uS
         
         output_low(Speaker);       // Altavoz apagado
         delay_us(769);             // espera 769 uS
      }
      
   }while(true);
}

Este ejemplo lo único que hace es emitir un sonido, ni agudo, ni grave, cuando se activa el pulsador conectado a RB1.

Nuestro PIC acaba de emitir su primer sonido!

Ahora podremos crear una funcion que emita un sonido con la frecuencia y duracion deseados.
El siguiente ejemplo hace sonar una sirena cuando se pulsa un interruptor en RB1.

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//                            PICSirena 1.00                               //
//                   (c) 2010 Gerardo Ariel Ramírez.                       //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//       uControlador: PIC16F876A            Lenguaje: CCS C               //
//               Xtal: 4MHz                                                //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////


#include <16f876a.h>          // Tipo de microcontrolador
   
#use delay(clock=4000000)     // Delay con xtal de 4MHz
#use fast_io(all)             // I/O todas rápidas, de esta forma cuando se
                              // escribe en los puertos, no se configura el tris
                              // acelerando el proceso.

#FUSES HS                     // FUSES cristal HS >=4MHz
#FUSES NOPUT                  // No power up Timer, no espera a estabilizar la tension
#FUSES NOBROWNOUT             // No Brown out reset, no se resetea si cae la tension

#define Speaker   PIN_B0      // Altavoz conectado a RB0

void Sound(int16 frecuencia, int16 duracion);

void main(){
   int t;
   set_tris_b(2);
   
   while(true){      //Bucle infinito
   
      if (input(PIN_B1)){                 // Si se activa el pulsador
      
         for (t=0;t<30;t++)               // Bucle ascendente incrementando la
            sound(((int16)t*15)+1600,20); // frecuencia del sonido
         for (t=30;t>0;t--)               // Bucle decrementando
            sound(((int16)t*15)+1600,20); // la frecuencia del sonido
      
      }
   }
}

void Sound(int16 frecuencia, int16 duracion){
   
   int16 mS_Transcurridos=0;
   int16 CiclosL=0;
   int16 uS;
   int32 tmp;
   
   if (frecuencia>=20&&frecuencia<=20000){ //si la frecuancia se encuentra entre
                                           // los margenes de 20Hz y 20 KHz se ejecuta
      tmp=100000;                          // de los contrario no.
      tmp/=frecuencia;           // convierte los Hz a microsegundos para la pausa
      tmp*=5;   
      uS=tmp;
      do{
         output_high(Speaker);   // Genera la frecuancia deseada
         delay_us(uS);           // con los retardos mientras
         CiclosL+=(uS);          // aumenta el contador de ciclos transcurridos
         output_low(Speaker);    // en dos partes para repartir el 
         delay_us(uS);           // trabajo entre estado alto y bajo.
         CiclosL+=(uS);          // 
         CiclosL+=25;            // Compensador.
         
         while(CiclosL>999){     // Se queda en el bucle mientras CiclosL sea
                                 // menor a 1000 (1 mS)
            CiclosL-=1000;       // Le resta 1000 a CiclosL 
            mS_Transcurridos++;  // y le suma 1 a mS_Transcurridos.
            CiclosL+=25;         // Compensador.
         }
      }while (duracion>mS_Transcurridos);// Repite el bucle hasta que haya pasado el
                                         // tiempo indicado.
   }
}

Desde este link te puedes bajar el proyecto y el hex.

Bueno, hasta aquí hemos llegado, ahora resta por hacer que el PIC reproduzca alguna nota musical e interprete alguna canción, pero eso lo veremos en Generar música con PIC.


Tal vez le interese: