Si creciste viendo los conciertos de Jean-Michel Jarre en los 80, seguramente recuerdes ese momento icónico en el que tocaba un instrumento hecho de haces de luz verde. Hoy vamos a construir nuestra propia versión: el arpa láser.
Este proyecto es, posiblemente, uno de los más vistosos que puedes hacer. Visualmente tiene ese punto de “toco el aire y suena música”, que queda fenomenal en una demo.
Pero desde el punto de vista de la ingeniería, es una excusa fantástica para dominar uno de los conceptos más importantes en electrónica analógica: el Divisor de Tensión Variable y la Calibración de Sensores.
Seguridad ante todo: Vamos a trabajar con láseres. Aunque usemos módulos de 5V de baja potencia (<5mW), NUNCA debemos mirar directamente al emisor ni apuntar a los ojos de personas o animales. El reflejo en superficies metálicas también puede ser peligroso.
Detectar la ausencia de luz
A diferencia de un pulsador que cierra un circuito mecánico, aquí estamos detectando una interrupción óptica.
El sistema consta de dos partes alineadas:
- Emisor: Un diodo láser que envía un haz concentrado de luz.
- Receptor: Una Fotorresistencia (LDR) o un fotodiodo que recibe ese haz constantemente.
Mientras no tocamos el arpa, el láser incide en la LDR. La LDR baja su resistencia drásticamente (hay mucha luz). Cuando ponemos la mano, bloqueamos el haz, la LDR queda en “sombra” y su resistencia aumenta.
Divisor de tensión
Arduino no puede medir resistencia directamente, solo voltaje. Para convertir la variación de resistencia de la LDR en un voltaje legible (0-5V), usamos un divisor de tensión.
- Estado Reposo (Luz):
R_LDRes baja (ej. 500Ω).Voutserá alto, porque la LDR está conectada a 5V. - Estado Activo (Sombra):
R_LDRes alta (ej. 50kΩ).Voutserá bajo, porque domina la resistencia fija a GND.
Esto asume que ponemos la LDR en la parte “alta” del divisor, tal como hacemos en el montaje. Si la ponemos abajo, la lógica se invierte. Ambas son válidas siempre que lo tengamos en cuenta en el código.
Componentes
- [1x|blue] Arduino Uno | El cerebro del proyecto
- [3x|red] Módulos Láser de 5V | Emisores de luz {punto rojo estándar}
- [3x|orange] Fotorresistencias (LDR) | Receptores de luz {GL5528 o similar}
- [3x|gray] Resistencia de 10kΩ | Divisores de tensión pull-down
- [1x|purple] Zumbador piezoeléctrico pasivo | Generación de sonido
- [Varios|gray] Estructura rígida | Madera, PVC o impresión 3D {alineación crítica}
- Estructura rígida (madera, PVC o impresión 3D) para mantener los láseres alineados con las LDRs. La alineación es crítica.
Esquema de conexión
Vamos a conectar las LDRs a las entradas analógicas.
Láseres
Los láseres estarán siempre encendidos mientras el arpa esté alimentada. Montadlos bien alineados y sin apuntar a los ojos.
[ { “from”: “Láseres VCC (todos)”, “to”: “5V Arduino”, “color”: “red”, “note”: “Siempre encendidos” }, { “from”: “Láseres GND (todos)”, “to”: “GND Arduino”, “color”: “black” } ]
Sensores LDR
Cada cuerda tiene una LDR y una resistencia de 10kΩ formando un divisor pull-down.
[ { “from”: “LDR 1 + 10kΩ”, “to”: “Pin A0”, “color”: “orange”, “note”: “Pull-down: LDR a 5V, R a GND” }, { “from”: “LDR 2 + 10kΩ”, “to”: “Pin A1”, “color”: “orange”, “note”: “Pull-down: LDR a 5V, R a GND” }, { “from”: “LDR 3 + 10kΩ”, “to”: “Pin A2”, “color”: “orange”, “note”: “Pull-down: LDR a 5V, R a GND” }, { “from”: “Resistencias 10kΩ”, “to”: “GND Arduino”, “color”: “black” } ]
Buzzer
El buzzer o transductor pasivo genera la nota de la cuerda activa.
[ { “from”: “Buzzer (+)”, “to”: “Pin 8”, “color”: “purple” }, { “from”: “Buzzer (-)”, “to”: “GND Arduino”, “color”: “black” } ]
Hemos configurado un divisor Pull-Down.
- Mucha luz (Láser dando) = Lectura Alta (~1023).
- Poca luz (Mano cortando) = Lectura Baja (~200).
El código
El reto de programación aquí es la calibración y la polifonía (o falta de ella).
Arduino Uno solo puede generar un tono a la vez con la función tone(). Si intentas tocar dos cuerdas a la vez, sonará una o la otra, o hará cosas raras.
Para gestionar las notas, usaremos un fichero de cabecera estándar pitches.h que contiene las frecuencias de las notas musicales, o definiremos las frecuencias manualmente para simplificar.
Definiciones y configuración
// Frecuencias de las notas (Do4, Mi4, Sol4)
// Puedes añadir más notas para completar una escala
#define NOTE_C4 262
#define NOTE_E4 330
#define NOTE_G4 392
const int numCuerdas = 3;
const int pinesLDR[] = {A0, A1, A2};
const int notas[] = {NOTE_C4, NOTE_E4, NOTE_G4};
const int pinBuzzer = 8;
// --- CALIBRACIÓN ---
// Este valor es CRÍTICO. Debes mirar el Monitor Serie para ajustarlo.
// Si el láser da en la LDR, leerás ~900. Si pones la mano, leerás ~300.
// El umbral debe estar en medio.
const int UMBRAL = 600;
void setup() {
Serial.begin(9600);
pinMode(pinBuzzer, OUTPUT);
}
Bucle principal
Vamos a leer constantemente los sensores. Si detectamos que una lectura cae por debajo del umbral, activamos el sonido.
Implementaremos una lógica de prioridad: si interrumpes varios haces, sonará la cuerda con el índice más alto, porque cada detección posterior sobrescribe la anterior y el zumbador es monofónico.
void loop() {
int cuerdaActiva = -1; // -1 significa que nadie toca nada
// Recorremos todas las cuerdas
for (int i = 0; i < numCuerdas; i++) {
int lectura = analogRead(pinesLDR[i]);
// Debugging: Descomenta esto para ver los valores y calibrar
/*
Serial.print("Cuerda "); Serial.print(i);
Serial.print(": "); Serial.println(lectura);
*/
// Lógica Pull-Down con LDR a 5V y resistencia a GND:
// Luz = R_ldr baja = V_out ALTO.
// Sombra = R_ldr alta = V_out BAJO.
// Por tanto, si lectura < UMBRAL -> Estamos tocando.
if (lectura < UMBRAL) {
cuerdaActiva = i;
}
}
// Gestión del Sonido
if (cuerdaActiva != -1) {
// Si hay una cuerda activa, tocamos su nota
tone(pinBuzzer, notas[cuerdaActiva]);
} else {
// Si no, silencio
noTone(pinBuzzer);
}
delay(10); // Pequeña pausa para estabilidad
}
Solución de problemas comunes
- El arpa suena sola: Significa que el láser no está apuntando perfectamente al centro de la LDR, o que hay demasiada luz ambiente en la habitación que confunde al sensor.
- Solución: Usa tubos negros (termoretráctil o pajitas pintadas) alrededor de las LDRs para que solo “vean” la luz del láser y no la del sol.
- Tengo que poner la mano muy cerca para que suene: Tu umbral está mal calibrado. Abre el Monitor Serie, mira qué valor da cuando no tocas y qué valor da cuando tocas, y pon la constante
UMBRALjusto en la mitad. - El sonido es molesto: Un piezo pasivo produce un timbre muy marcado. Puedes reducir el nivel con una resistencia en serie elegida para el transductor. Un altavoz de 8 Ω no debe conectarse directamente al pin: necesita una etapa con transistor o amplificador.
Salida MIDI por USB
Hacer ruidos con un buzzer es divertido, pero ¿y si usamos el arpa para controlar un sintetizador profesional en el ordenador?
Si usas un Arduino Leonardo o Micro (con USB nativo), puedes usar una librería MIDI USB compatible. En lugar de llamar a tone(), enviarías mensajes noteOn y noteOff al ordenador.
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
MidiUSB.flush();
}
De esta forma, tu arpa láser podría sonar como un piano de cola, un violín o… bueno, como los sintetizadores de Jean-Michel Jarre, que es lo suyo.