Hiparco

Recetas y trucos de GNU/Linux e informática en general

Alojado en http://guimi.net

Arduino: Theremin de luz

El circuito (realizado con Fritzing):

/*
 * Este programa lee el valor de un sensor (fotoresistencia o sensor de luz) y vuelca una frecuencia 
 * en un vibrador piezo-electrico, que emite distinto sonido segn la luz recibida.
 * Ademas al inicio del programa se realiza una calibracion del sensor.
 *
 * Basado en Arduino Projects Book
 *
 * 2014 - Guimi (http://guimi.net)
 */

// VARIABLES
//----------
const byte led=13; // Usamos el LED de la placa para indicar el periodo de calibracion.
const byte sensor=0; // Variable que indica el pin del sensor (fotoresistencia, LDR o sensor de luz)
const byte altavoz=12; // Constante que indica el pin del altavoz

int valorSensor=0; // Variable para guardar el valor del sensor [0-1023]
int valorMax=0;    // Variable que guarda el valor maximo, para calibracion.
int valorMin=1023; // Variable que guarda el valor maximo, para calibracion.

const byte duracion=10; // Variable que almacena la duracion del sonido, y marca la pausa entre iteraciones del bucle
int frecuencia=50; // Variable que guarda el valor de frecuencia que debe emitir el piezo-electrico.

// FUNCION SETUP
//--------------
void setup(){
  // Definimos cada pin como entrada o salida
  pinMode(led,OUTPUT);
  pinMode(sensor,INPUT);

  // Encendemos el LED para indicar que estamos calibrando
  digitalWrite(led, HIGH);
  
  // En un bucle, durante 5 segundos guardamos el valor mas alto y el valor mas bajo leidos
  // El usuario, durante la calibracion, deja que el sensor reciba la maxima y la minima luz posible
  while (millis()<5000) {
    // Leemos el valor del sensor
    valorSensor=analogRead(sensor);

    // Guardamos el valor maximo leido
    if (valorSensor>valorMax) {
      valorMax=valorSensor;
    }
    
    // Guardamos el valor minimo leido
    if (valorSensor<valorMin) {
      valorMin=valorSensor;
    }
    
  }

  // Apagamos el LED para indicar que ya no estamos calibrando
  digitalWrite(led, LOW);

  // Preparamos la comunicacion mediante el puerto serie
  //Serial.begin(9600);
}


// FUNCION LOOP
//-------------
void loop(){
  // Cuanta mas luz recibe, menor es la resistencia y el valor leido
  // Valores leidos: 550-750 muy iluminado; 885-895 luz normal; >990 tapado con el dedo
  
  // Si invertimos la polaridad, cuanta mas luz recibe, mayor es el valor leido
  // <30 tapado con el dedo; unos 150 con luz normal y unos 300 muy iluminado
  
  // Leemos el valor del sensor [0-1023]
  valorSensor = analogRead(sensor);    
  // Mostramos informacion por el puerto serie
  //Serial.println(valorSensor);
  // Convertimos el valor leido a la frecuencia a emitir, teniendo en cuenta los datos de calibracion
  frecuencia = map(valorSensor, valorMin, valorMax, 50, 4000);
  // Enviamos la senal al piezo para que emita sonido
  tone(altavoz,frecuencia,duracion*2);

  // Esperamos un tiempo de reaccion para los componentes
  delay(duracion);
}