ARDUINO MUSICAL:

En esta práctica expondremos como hacer música con Arduino una LDR y un potenciometro, si bien los objetivos que se pretende trabajar son los siguientes:

OBJETIVOS:

  1. Salida digital.
  2. Entradas analógicas: con potenciometro y con LDR.
  3. Monitorización de los parametros de entrada.
  4. Matrices múltiples.

Para ver como se han calculado las frecuencias de las notas musicales así como los semiperiodos de estas, pica en el siguiente vinculo:
Calculo de las frecuencias de las notas musicales

PROGRAMA:

#include <SoftwareSerial.h> //Para monitorizar las entradas y salidas de datos

/*
*Programa para reproducir tonos, toda la escala musical,
*en función de la señal de una LDR, y el valor de un potenciometro
*
* El cálculo de los tonos se realiza mediante la operación:
* timeHigh = 1/(2 * FrequenciaTono) = periodo / 2
*/


//VARIABLES
int altavozOut = 9; // conectaremos el altavoz al pin digital 9
int niveLuz=18; //establecemos un valor tal que al dividir la señal mas alta de la LDR entre este número nos de 12 (la nota 0-11)
int nivePot=125; //establecemos un valor tal que al dividir la señal mas alta del potenciometro entre este número nos de 7(la octava 0-8)
int aR0=0; int aR1=1; //bits analógicos 0 y 1 LDR Y POTENCIOMETRO
int ValLDR = 0; int ValPot = 0; //valor de LDR y potenciometro
int nota=12; int octava=4; //valor de nota y octava
//TIEMPOS DE LOS SEMIPERIODOS DE CADA NOTA MUSICAL
// Definimos una matriz doble con todos los semiperiodos de las notas [octava][semiperiodo de la nota]
int tonos[][12] = {
{7645,7215,6810,6428,6067,5727,5405,5102,4816,4545,4290,4050},
{3822,3608,3405,3214,3034,2863,2703,2551,2408,2273,2145,2025},
{1911,1804,1703,1607,1517,1432,1351,1276,1204,1136,1073,1012},
{956,902,851,804,758,716,676,638,602,568,536,506},
{478,451,426,402,379,358,338,319,301,284,268,253},
{239,225,213,201,190,179,169,159,150,142,134,127},
{119,113,106,100,95,89,84,80,75,71,67,63},
{60,56,53,50,47,45,42,40,38,36,34,32}
};

//INICIALIZACIÓN DE ARDUINO
void setup() {
pinMode(aR0, INPUT); // pin analógico 0 como entrada LDR
pinMode(aR1, INPUT); // pin analógico 1 como entrada POTENCIOMETRO
pinMode(altavozOut, OUTPUT); //PIN DIGITAL 9 COMO SALIDA DE Altavoz
Serial.begin(9600); //definimos frecuencia de la salida serie en baudios
}

//SALIDA DEL SONIDO (NOTA) CORRESPONDIENTE
void suena(int tono){
digitalWrite(altavozOut, HIGH);
delayMicroseconds(tono);
digitalWrite(altavozOut, LOW);
delayMicroseconds(tono);
}

//BUCLE REPETITIVO
void loop() {
ValLDR = analogRead(aR0); //Leemos el valor de la LDR en la entrada 0
ValPot = analogRead(aR1); //Leemos el valor del potenciometro en la entrada 1
nota=(ValLDR/niveLuz); //Obtención de la nota musical
octava=(ValPot/nivePot)-1; //Obtención de la octava
if (octava>7) octava=7;
Serial.print("nota="); //monitorización de la nota musical
Serial.print(nota);
Serial.print(", octava="); //monitorización de la octava
Serial.println(octava);
if(nota<12) for (int i=0; i<=12; i++) suena(tonos[octava][nota]); //REPETIMOS LA NOTA 12 VECES PARA QUE SUENE MEJOR
}

CALIBRACIÓN:

Sera necesario calibrar las variables niveLuz y nivePot en función del valor máximo de iluminación, y del valor del potenciometro y resistencia asociada a esté, para ello pondremos a uno estas variables, y el valor obtenido (lo vemos en el monitor nota y octava), lo dividimos entre 13 para niveLuz y entre 8 para nivePot, la parte entera obtenida sera el valor que hemos de dar a estas variables, la justificación es obvia; ya que son son 12 notas (con máxima luz no debe sonar) y 8 octavas.
Veanse las líneas en rojo del código siguiente:

#include <SoftwareSerial.h> //Para monitorizar las entradas y salidas de datos

/*
*Programa para reproducir tonos, toda la escala musical,
*en función de la señal de una LDR, y el valor de un potenciometro
*
* El cálculo de los tonos se realiza mediante la operación:
* timeHigh = 1/(2 * FrequenciaTono) = periodo / 2
*/


//VARIABLES
int altavozOut = 9; // conectaremos el altavoz al pin digital 9
int niveLuz=1; //Ponemos a 1 para calcular su valor dividiendo el valor monitorizado de la nota entre 13
int nivePot=1; //Ponemos a 1 para calcular su valor dividiendo el valor monitorizado de la octava entre 8

int aR0=0; int aR1=1; //bits analógicos 0 y 1 LDR Y POTENCIOMETRO
int ValLDR = 0; int ValPot = 0; //valor de LDR y potenciometro
int nota=12; int octava=4; //valor de nota y octava
//TIEMPOS DE LOS SEMIPERIODOS DE CADA NOTA MUSICAL
// Definimos una matriz doble con todos los semiperiodos de las notas [octava][semiperiodo de la nota]
int tonos[][12] = {
{7645,7215,6810,6428,6067,5727,5405,5102,4816,4545,4290,4050},
{3822,3608,3405,3214,3034,2863,2703,2551,2408,2273,2145,2025},
{1911,1804,1703,1607,1517,1432,1351,1276,1204,1136,1073,1012},
{956,902,851,804,758,716,676,638,602,568,536,506},
{478,451,426,402,379,358,338,319,301,284,268,253},
{239,225,213,201,190,179,169,159,150,142,134,127},
{119,113,106,100,95,89,84,80,75,71,67,63},
{60,56,53,50,47,45,42,40,38,36,34,32}
};

//INICIALIZACIÓN DE ARDUINO
void setup() {
pinMode(aR0, INPUT); // pin analógico 0 como entrada LDR
pinMode(aR1, INPUT); // pin analógico 1 como entrada POTENCIOMETRO
pinMode(altavozOut, OUTPUT); //PIN DIGITAL 9 COMO SALIDA DE Altavoz
Serial.begin(9600); //definimos frecuencia de la salida serie en baudios
}

//SALIDA DEL SONIDO (NOTA) CORRESPONDIENTE
void suena(int tono){
digitalWrite(altavozOut, HIGH);
delayMicroseconds(tono);
digitalWrite(altavozOut, LOW);
delayMicroseconds(tono);
}

//BUCLE REPETITIVO
void loop() {
ValLDR = analogRead(aR0); //Leemos el valor de la LDR en la entrada 0
ValPot = analogRead(aR1); //Leemos el valor del potenciometro en la entrada 1
nota=(ValLDR/niveLuz); //Obtención de la nota musical
octava=(ValPot/nivePot)-1; //Obtención de la octava
// if (octava>7) octava=7; comentamos esta línea para leer el valor máximo del potenciometro
Serial.print("nota="); //monitorización de la nota musical
Serial.print(nota);
Serial.print(", octava="); //monitorización de la octava
Serial.println(octava);
if(nota<12) for (int i=0; i<=12; i++) suena(tonos[octava][nota]); //REPETIMOS LA NOTA 12 VECES PARA QUE SUENE MEJOR
}

CIRCUITO ELECTRICO:

esquema foto

El LED1 y su resistencia asociada son opcionales, podemos prescindir de ellos, simplemente se han puesto para ver las oscilaciones de la salida.
Es de suponer que si sustituimos el piezoelectrico por un altavoz de cierta calidad, el sonido mejore.
De igual forma si sustituimos la LDR (PH1) por un detector de proximidad, el control de las notas será más efectivo.

APLICACIONES SIMILARES:

http://arduino.cc/es/Ejercicios/Piezo. http://arduino.cc/es/Ejercicios/TonosPuertoSerie. http://www.arduino.cc/en/Tutorial/PlayMelody