jueves, 19 de noviembre de 2015

Tutorial-Generar una melodía con Psoc Creator


Saludos lectores, en esta entrada les enseñaremos el procedimiento de como logramos reproducir una melodía con ayuda del microcontrolador Psoc Cy8ckit-059.

Antes de empezar debemos tener en claro como se representa el sonido físicamente. El sonido es una onda de presiones en la cual el tono de dicho sonido dependerá de la frecuencia de la onda, su volumen de la amplitud y el timbre de la forma de la onda.

Al procesar sonidos de manera eléctrica, se debe utilizar una señal analógica como si fuera la señal de presiones del sonido ya que ésta se convertirá en una onda de sonido al pasar por algún amplificador o bocina.  

Para empezar necesitamos generar una señal en la cual debemos ir variando su frecuencia y su duración para generar la melodía. Para eso utilizamos en el Psoc Creator un generador de onda "WaveDAC8".

Como solo utilizaremos una onda de salida debemos colocar un "0" lógico en el pin "ws", además tendremos que declarar un pin de salida para la onda generada.

La configuración del "WaveDAC8" es la siguiente:
Configurando un Clock externo para poder ir variando las frecuencias. Las variables de forma de la onda, amplitud y número de muestras pueden variar y eso no afectará a la melodía más que en el "timbre" del sonido.

Después debemos colocar diversos Clocks a un Multiplexor Digital, configurado con las entradas que sean necesarias, que nos permitirá switchear éstos.

La frecuencia de cada Clock dependerá de la nota que se quiera generar, por ejemplo:
La frecuencia de una nota "La" es de 440 Hz, y sabemos que la frecuencia de salida de la onda será la frecuencia de muestra (dada por el Clock) entre el número de muestras (120 en nuestro caso), entonces haciendo un pequeño cálculo llegamos a que el Clock deberá tener una frecuencia de 52.8 kHz para que la nota de sálida sea ese "La".

A continuación hay un gráfico que muestra las frecuencias de las notas musicales en diversas escalas.  

Cabe señalar que con éste microprocesador tenemos la limitante de que solo podemos utilizar 8 Clocks a la vez ya que en una Octava musical hay 12 tonos diferentes lo que nos límita a solo poder tener 8 tonos diferentes.

Por último necesitamos controlar el multiplexor, para esto haremos uso del componente "Control Register" configurado a 3 salidos en modo "Bus". 


La conexión final correspondiente a este proyecto es la siguiente:

El código utilizado, el cuál ya tiene programada una pequeña parte de una canción del videojuego de The Legend of Zelda, es el siguiente:

#include <project.h>

int main()
{
    CyGlobalIntEnable;  
    Wave_Start();
    float negra;
    negra=700;
    
    for(;;)
    {
    Wave_Enable();
    Control_Write(7);
    CyDelay(negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(4);
    CyDelay(1.75*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(0);
    CyDelay(.25*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(0);
    CyDelay(.25*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(1);
    CyDelay(.25*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(2);
    CyDelay(.25*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(3);
    CyDelay(.25*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(4);
    CyDelay(2.5*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
     Control_Write(4);
    CyDelay(.5*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(4);
    CyDelay(negra/3);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(5);
    CyDelay(negra/3);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(6);
    CyDelay(negra/3);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(7);
    CyDelay((2+1/3)*negra);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(7);
    CyDelay(negra/3);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(7);
    CyDelay(negra/3);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(6);
    CyDelay(negra/3);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(5);
    CyDelay(negra/3);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(6);
    CyDelay(negra*.75);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(5);
    CyDelay(negra*.25);
    
    Wave_Stop();
    CyDelay(10);
    
    Wave_Enable();
    Control_Write(4);
    CyDelay(negra*2);
    
    Wave_Stop();
    CyDelay(10);
    }
}

Entre nota y nota agregamos el código:

Wave_Stop();
 CyDelay(10);
Wave_Enable();

Para poder separar los sonidos pues sin ese pequeño paro en la onda, algunas notas se escuchan como una sola.
  

2 comentarios:

  1. Hola.
    En verdad me gusto mucho su entrada del blog, es realmente detallada, desde lo mas básico, como que es el sonido, hasta los diagramas y sus respectivas explicaciones.

    Saludos :)

    ResponderEliminar
  2. Gracias a su trabajo pude entender como hacer el mio. Intentaron implementar la función de wave1Setup? Saludos.

    ResponderEliminar