Introducción
Hace tiempo me encontré por internet una página en la que se explicaba cómo construirse un arpa láser casera. La idea es sencilla: se tiene un láser que encendemos y apagamos a muy alta velocidad contra un espejo montado sobre un motor a pasos que va cambiando de posición de forma sincronizada con el láser, de tal manera que por persistencia de la visión da lugar a una serie de haces de luz muy espectaculares, si el láser tiene la potencia adecuada y/o la luz ambiente es apropiada. Si disponemos una célula fotoeléctrica que detecte cuándo uno de los haces de láser ha sido interrumpido y vemos en qué posición está el láser en ese momento, podemos asociar a cada posición del láser una nota musical, que se envía por MIDI a un teclado o al ordenador, o podemos también hacer sonar con un pequeño altavoz.
Como además estaba preparando un concierto para unos meses más tarde en el que podría quedar muy bien hacer una parte con el arpa láser, decidí construirme una.
En esta página describo todo el proceso de montaje de un arpa láser plenamente funcional, tratando de explicar las pruebas que hice y todos los pasos que seguí, así como las referencias que consulté siempre que he podido. Ojo, que muchas de las páginas de internet sobre arpas láser no son del todo funcionales, o se quedan a la mitad y no lo llevan hasta el final, o directamente cuentan cosas que no son del todo creíbles.
Para llegar al arpa que empleé en el concierto, construí varios prototipos parciales y uno completo antes del arpa definitiva. Las fotos que pongo en la página pueden corresponder a alguno de los prototipos o a la definitiva en proceso de montaje.
Aviso al navegante: si tienes intención de hacer algo parecido a las arpas láser de Jean Michel Jarre ya puedes ir preparándote para un gran desembolso económico y para dedicarle mucho tiempo…
Y el aviso más importante, y no es broma: trabajar con láseres, especialmente de alta potencia como el que empleo en este arpa, supone un riesgo muy alto y existe la posibilidad de quedarse ciego si se mira accidentalmente al láser (o un reflejo de éste en alguna superficie reflectante) ya que puedes quemarte la retina en un tiempo menor del tiempo de reacción de cerrar el ojo o apartar la mirada. Así que hay que emplear en todo momento gafas protectoras, adecuadas al láser que empleemos, evitar que haya más gente donde estemos trabajando y ser muy cuidadoso…
Material y lista de la compra
- Arduino Nano: 2.59 €. También valdría un Arduino UNO, pero es más grande y algo más caro: 5.99 € (pirata).
- Láser TTL 300mw 532 nm: 80 €
- Gafas protectoras láser 532&1064 nm: 35 €
- Motor paso a pasop (stepper) He probado muchos motores con diferentes resultados. Si se tiene suerte, puede valer uno de una impresora vieja. El que empleé finalmente fue este (19.69 €)
- A3967 EasyDriver: 4.29 €
- Soporte del motor: 2.59 €
- Espejo: 2 € o gratis de cualquier juguete (o, mejor y también gratis, un trozo de un disco duro, que es una superficie muy reflectante frontal)
- Conector MIDI (2 unidades por 5 €: 2.5 €)
- Cable MIDI: 2.17€. (no sería necesario si vamos a conectarlo a un ordenador, en cuyo caso necesitaríamos una interfaz MIDI-USB como esta, por 3.31 €)
- Interruptor de pie (2.75 €)
- Interruptor final de carrera (3 unidades por 1 €: 0.33 €)
- Fotorresitor (15 unidades por 2.38 €: 0.16 €)
- Potenciómetro 5kΩ (10 unidades por 1.68€: 0.17 €)
- Protoboard de 400 puntos: 1.35 €
- Adaptador de corriente de 12 V o más (rescatado de un alimentador de un portátil o similar)
- Regulador de voltaje: 2.57 €
General:
- Cables (pueden ser normales o tipo Dupont)
- Cola térmica
- Soldador
- Resistencias varias
- Madera o caja de aproximadamente 32 x 20 cm
Opcional:
- Teclado MIDI al que conectar el arpa láser y que genere los sonidos.
- Interfaz MIDI – USB (4.86 €) sólo necesario si no disponemos de un sintetizador o teclado MIDI que genere los sonidos.
- Conector DC 12 V 2.1 mm x 5.5 mm (3 unidades por 2.58 €: 0.86 €) Opcional pues podemos cortar y soldar los cables directamente…
- Jack conector hembra audio 3.5 mm (2 unidades por 1.45 €) Sólo necesario si queremos que el arpa genere sonidos por sí sola, sin
- Altavoz piezoeléctrico: de cualquier juguete o altavoz malo
- Transistor NPN 2N222 (10 unidades por 1.62 €: 0.16 €) Solo necesario si el láser no viene con su propio driver.
- 1 LED
- Módulo lector de tarjeta SD (1.99 €) y una tarjeta SD. Solo necesario si queremos que al arrancar el arpa láser se reproduzca un archovo wav con el sonido de un sable láser encendiéndose.
TOTAL: Configuración mínima: unos 150€, que podría llegar a ser unos 80 € si usamos un láser malucho (no se verían los haces salvo en una habitación con humo). También depende de los elementos que ya tengamos reciclados de otros inventos.
El láser
Probé con varios láseres, desde los baratos tipo puntero hasta uno «bueno» de 300 mW. Ojo con estos láseres que generalmente vienen de China. Venden diferentes modelos de diferentes potencias, pero luego descubres que te llega exactamente el mismo y que lo único es juegas con el potenciómetro. Así que en caso de utilizar estos láseres, es mejor comprar el de menor potencia y luego ajustar el potenciómetro. Yo alguna vez he jugado con este de 50 mW (11€), y este de 5 mW (5€), y me llegaron exactamente iguales.
El que finalmente utilicé fue este de 300 mW, por unos 80 €. Un láser bueno «de discoteca» puede costar varios cientos de euros o incluso miles. Lo importante es que sea TTL y que tenga cuanta más potencia os podáis permitir, pues entonces podrá verse el haz de láser mejor, o con mayor luz ambiente. Los más típicos (y baratos) son los láseres verdes de 532 nm de longitud de onda.
No penséis en ningún momento que puede verse el haz del láser a plena luz del día o, o en una sala muy iluminada. Es necesario que esté en un entorno oscuro, y lo ideal es emplear humo para que se vea mejor…
Advertencia. Jugar con láseres es muy peligroso, y no es una advertencia banal. En menos tiempo de lo que el ojo puede reaccionar un láser dirigido al ojo, o reflejado en una superficie brillante puede dañar permanentemente tu visión. Para toda la vida. Por ello, es necesario llevar siempre unas gafas protectoras adecuadas al láser específico que estemos manejando. En mi caso empleo láseres de 532 nm, pero ojo, algunos láseres chinos de mala calidad emiten a la vez a 1064 nm, por lo que opté por protegerme para ambas frecuencias y compré estas gafas por unos 35 €.
Estas son las características que da el fabricante del láser:
- Output Wavelength:532nm
- Output Power:300mW with 5%
- operating Voltage:DC12V
- Lifepan:>5000 hours
- Laser Shape: DOT
- Focusable:Yes (By Tool)
- Working Temperature:+10dgC-+40dgC
- Working Temperature:+10dgC-+50dgC
- Focus lens:Glass
- Cooling mode:Heatsink and Fan
- TTL signal:0~30K
El motor
Aquí está el quid de la cuestión. El láser es importante, sí, pero sólo depende de cuánto me quiera gastar en comprar un láser de mayor potencia, así que hay pocas incógnitas. En cambio con el motor es bastante más delicado. Debe ser muy rápido, y además permitir un control preciso del ángulo de giro para que se dé el efecto de persistencia de la visión y que al reflejar el láser de forma sincronizada con los giros sobre un espejo en el eje del motor dé la sensación de tener varios haces de luz.
Hice muchísimas pruebas con diversos motores y drivers (ver esta entrada). Lo primero, que se pregunta mucho en otras páginas, es dejar claro que el típico stepper de todos los kits de iniciación a la electrónica, el 28BYJ-48 no vale para un arpa láser, es muy lento. Hablo sobre este motor aquí.
En varias páginas se dice que con un motor sacado de una vieja impresora funciona. Yo probé con un MITSUMI M35SP-9, sacado de una vieja impresora Deskjet HP. Puede valer, aunque obtuve mejores resultados con otros motores.
Lo ideal sería emplear un galvanómetro (lo que se emplea en láseres de discoteca) que son capaces de girar a más de 20.000 revoluciones por minuto, pero son extremadamente caros, así que lo descarté desde el principio.
El motor que finalmente empleé fue este de Adafruit, aunque estuve a punto de utilizar uno que rescaté de una vieja impresora.
También es muy importante qué driver (controlador) del motor empleamos. En mi caso empleé el A3967 EasyDriver. Aquí se explica de forma muy sencilla su manejo.
En esta entrada explico cómo hacer funcionar el motor con este driver.
MIDI
El protocolo MIDI es bastante sencillo. En esencia, Arduino no genera música, sino que envía comandos por este protocolo para que otra máquina genere la música con el instrumento que queramos. En mi caso, como ya tenía un teclado MIDI (Casio CT-655), solo he tenido que comprar el enchufe MIDI y un cable. También se puede hacer sin un teclado/sintetizador, conectando el cable MIDI al ordenador por un adaptador USB, y configurar el ordenador para que se encargue de generar el sonido que queramos (ver más abajo).
Lo primero es hacer una pequeña prueba para ver que hemos conectado bien todo y que nuestro teclado/sintetizador/ordenador es generar de interpretar lo que Arduino le manda por MIDI y produce sonidos. Podemos seguir el tutorial sencillo que viene en el SDK y la página web de Arduino.
En la siguiente página se explica en profundidad el protocolo MIDI y la estructura de comandos. Voy a conectar el arpa láser a un teclado CASIO CT-655, y me interesa, además de las notas en concreto, poder decirle al teclado que cambie a un instrumento determinado.
Por cierto, cada vez que actualicemos el código de Arduino y lo subamos a la placa, debemos desconectar el cable MIDI, pues si no el teclado puede recibir instrucciones erróneas y el resultado que obtendremos sonará muy raro…
Audio
Como es un poco trabajoso tener que conectar el arpa láser a un teclado MIDI o a un ordenador para producir algún sonido, he probado a que además de enviar el sonido por MIDI produzca sonido digital directamente, a través de un pequeño altavoz piezo, y un jack de 2.5mm al que se puede conectar unos auriculares.
[Explicar más]
Secuencia de audio al inicio
Se me ocurrió que podía añadir un sonido de encendido de espada láser de Star Wars, así que le añadí un módulo lector de tarjeta SD, busqué por internet y descargué un audio con el sonido de espada láser, lo convertí a wav con el Audacity y pasándolo a mono, 16.000 Hz, 32 bits y grabado como «Unsigned 8-bit PCM». Aquí está el audio final:
Diagrama fritzing
Código
El código de Arduino empleado en este proyecto es el siguiente:
#include // Cargo la librería de motores a pasos #include // Cargo la librería SD, para reproducir audio al comienzo por altavoz #define SDPin 10 // Conecto el CS al pin 10, para reproducir audio al comienzo por altavoz #include // Cargo la librería TMRpcm, para reproducir audio al comienzo por altavoz #include // Cargo la librería SPI, para reproducir audio al comienzo por altavoz TMRpcm audio; // Creo el objeto audio int pinStep = 7; // Pin de Step del EasyDriver int pinDirec = 8; // Pin de Direction del EasyDriver int micropausa = 600; // microsegundos de pausa entre (micro)paso y (micro)paso (velocidad del motor) int micropausaInicio = 15000; //microsegundos de pausa entre (micro)paso y (micro)paso en la secuencia de inicio int posVert = 465; // Número de (micro)pasos que deja el espejo para que el láser esté en su sitio al comienzo int sensor = 155; // Umbral de sensibilidad del fotorresitor. Cuanto más bajo, más sensible a la luz. En cuarto oscuro funciona bien con 160 int micropausaLaser = 2000; // Tiempo que se queda encendido el láser (microsengudos). En mi caso, va bien con 2000 int micropausaSensor = 2000; // Pausa tras apagar láser y antes de girar, para dar tiempo al sensor a reaccionar (microsengudos). En mi caso, va bien con 2000 int haces = 6; // Número de notas / haces de láser int pasosHaces = 12; // Número de (micro)pasos entre haz y haz int pinLaser = 4; // Pin donde tengo conectado el láser int pinLed = 6; // Pin donde tengo conectado el LED de estado int pinAudio = 9; // Pin donde está conectado el altavoz piezo. Debe ser el Pin 9 en Arduino Uno y Nano, y 11 en el Mega int pinBoton = 3; // Pin donde está conectado el interruptor de fin de carrera del motor int valBot = 0; //Estado del botón del motor int noteStatus[] = {0,0,0,0,0,0}; // Inicializo el estado de las notas (sonando/no sonando). Debe haber el mismo número que número de haces int notasMIDI[] = {58,62,65,70,72,74}; // Nota asignada a cada haz. Debe haber el mismo número que número de haces void setup() { pinMode(pinLaser, OUTPUT); // Declaro el pin del laser digitalWrite(pinLaser, LOW); // Apago el laser pinMode(pinLed, OUTPUT); // Declaro el pin del Led de status digitalWrite(pinLed, LOW); // Dejo el Led de estatus apagado // Para que suene el sable láser al arrancar audio.speakerPin = pinAudio; // Debe ser el Pin 9 en Arduino Uno y Nano, y 11 en el Mega Serial.begin(9600); // Para reproducir el audio al comienzo pinMode(SDPin, OUTPUT); ajusteMotor(); // Llamo a la función ajusteMotor() para colocar el espejo en su sitio y arrancar la secuencia de incio //Arranco MIDI: Serial.begin(31250); // Especifico el canal de comunicación para MIDI Serial.write(192); // Byte para cambiar de instrumento en canal 0 Serial.write(15); // Número de instrumento delay(100); } // Pongo el motor/espejo en su sitio al comienzo y secuencia de inicio: void ajusteMotor() { int numpasosini; //número de pasos en la secuencia de inicio (se calcula automáticamente) int contini=0; // contador secuencia de inicio (se calcula automáticamente) pinMode(pinBoton, INPUT); // Declaro el pin del boton como input pinMode(pinDirec, OUTPUT); pinMode(pinStep, OUTPUT); digitalWrite(pinDirec, LOW); digitalWrite(pinStep, LOW); for (int pos = 0; pos < 4000; pos++) { valBot = digitalRead(pinBoton); if (valBot == LOW) { // si el botón está pulsado: //digitalWrite(pinLed, HIGH); // Enciendo el led digitalWrite(pinDirec, HIGH); // Cambio la dirección for (int pos2 = 0; pos2<posVert; pos2++) { digitalWrite(pinStep, LOW); digitalWrite(pinStep, HIGH); delayMicroseconds(micropausa); } digitalWrite(pinLaser, HIGH); // Enciendo el laser // Reproduzco el sonido de sable láser: if (SD.begin(SDPin)) { // Solo ejecuto si la tarjeta está accesible audio.volume(6); // Fijo el volumen (min=0, max=7) audio.play("laser.wav"); } // Secuencia abanico desplegado totalmente, acelerando linealmente: numpasosini=(haces-1)*pasosHaces*17/2; // Calculo el número de pasos en la secuencia de inicio // Compruebo la célcula fotoeléctrica, y mando arrancar la secuencia de inicio cuando se active: while(true) { if ( (analogRead(0) > sensor*2 ) ) // Si el sensor recibe señal { digitalWrite(pinLed, HIGH); // Enciendo el led digitalWrite(pinDirec, LOW); // Cambio la dirección for (int pos2 = 0; pos2<((haces-1)*pasosHaces/2); pos2++) { digitalWrite(pinStep, LOW); digitalWrite(pinStep, HIGH); digitalWrite(pinLaser, HIGH); // Enciendo el laser delayMicroseconds(micropausaInicio-(micropausaInicio-micropausa)/numpasosini*contini++); digitalWrite(pinLaser, LOW); // Apago el laser } for (int pos3 = 0; pos3<4; pos3++) { digitalWrite(pinDirec, HIGH); // Cambio la dirección for (int pos2 = 0; pos2<((haces-1)*pasosHaces); pos2++) { digitalWrite(pinStep, LOW); digitalWrite(pinStep, HIGH); digitalWrite(pinLaser, HIGH); // Enciendo el laser delayMicroseconds(micropausaInicio-(micropausaInicio-micropausa)/numpasosini*contini++); digitalWrite(pinLaser, LOW); // Apago el laser } digitalWrite(pinDirec, LOW); // Cambio la dirección for (int pos2 = 0; pos2<((haces-1)*pasosHaces); pos2++) { digitalWrite(pinStep, LOW); digitalWrite(pinStep, HIGH); digitalWrite(pinLaser, HIGH); // Enciendo el laser delayMicroseconds(micropausaInicio-(micropausaInicio-micropausa)/numpasosini*contini++); digitalWrite(pinLaser, LOW); // Apago el laser } } break; } } // // Si quiero ahorrarme la secuencia de inicio, habría que comentar la sección anterior. // // Dejo el espejo en la posición del primer haz: // digitalWrite(pinDirec, LOW); // Cambio la dirección // for (int pos2 = 0; pos2<((haces-1)*pasosHaces/2); pos2++) // { // digitalWrite(pinStep, LOW); // digitalWrite(pinStep, HIGH); // delayMicroseconds(micropausa); // } break; } else { // el botón no está pulsado: digitalWrite(pinLed, LOW); // Mantengo el led apagado digitalWrite(pinStep, LOW); digitalWrite(pinStep, HIGH); delayMicroseconds(micropausa); } } } void loop() { for (int pos = 1; pos < haces; pos++) { // En una dirección digitalWrite(pinDirec, HIGH); // Establezco la dirección del motor digitalWrite(pinLaser, HIGH); // Enciendo el láser delayMicroseconds(micropausaLaser); // Dejo el láser encendido el tiempo micropausaLaser // Compruebo la célcula fotoeléctrica, y mando tocar/parar de tocar la nota correspondiente: if ( (analogRead(0) > sensor ) && ( noteStatus[pos] == 0 )) // Si el sensor recibe señal, y la nota no está sonando { noteMIDI(0x90, notasMIDI[pos-1], 0x45); // Que se toque la nota por MIDI //tone(pinAudio,notas[pos-1]); // Que se toque la nota por el piezo/auriculares digitalWrite(pinLed, HIGH); // Enciendo el Led de estado noteStatus[pos]++; // Cambio el estado de esa nota a "sonando" } else if (analogRead(0) < sensor ) // Si el sensor no recibe señal { if (noteStatus[pos] >= 1) // Si hay una nota tocando (porque aún no la he apagado, aunque no haya señal) { //if (noteStatus[pos]++ == 2) //Solo para de sonar si ya han pasado tres ciclos sin recibir señal... //{ noteMIDI(0x90, notasMIDI[pos-1], 0x00); // Parar de tocar la nota por MIDI //noTone(pinAudio); // Parar de tocar la nota por el piezo/auriculares digitalWrite(pinLed, LOW); // Apago el led de estado noteStatus[pos]=0; // Cambio el estado de esa nota a "apagada" //} } } digitalWrite(pinLaser, LOW); // Apago el láser delayMicroseconds(micropausaSensor); // Antes de pasar al siguiente haz, pequeña pausa para reacción del sensor fotoeléctrico //Muevo el motor al siguiente haz: for (int pos2 = 0; pos2<pasosHaces; pos2++) // Avanzo un haz (el número de (micro)pasos definidos en la variable pasosHaces { digitalWrite(pinStep, LOW); digitalWrite(pinStep, HIGH); delayMicroseconds(micropausa); } } for (int pos = haces; pos > 1; pos--) { // En la otra dirección digitalWrite(pinDirec, LOW); // Pongo el motor en el sentido contrario digitalWrite(pinLaser, HIGH); // Enciendo el láser delayMicroseconds(micropausaLaser); // Dejo el láser encendido el tiempo micropausaLaser // Compruebo la célcula fotoeléctrica, y mando tocar/parar de tocar la nota correspondiente: if ( (analogRead(0) > sensor ) && ( noteStatus[pos] == 0 )) // Si el sensor recibe señal, y la nota no está sonando { noteMIDI(0x90, notasMIDI[pos-1], 0x45); // Que se toque la nota //tone(pinAudio,notas[pos-1]); // Que se toque la nota por el piezo/auriculares digitalWrite(pinLed, HIGH); // Enciendo el Led de estado noteStatus[pos]++; // Cambio el estado de esa nota a "sonando" } else if (analogRead(0) < sensor ) // Si el sensor no recibe señal { if (noteStatus[pos] >= 1) // Si hay una nota tocando (porque aún no la he apagado, aunque no haya señal) { //if (noteStatus[pos]++ == 2) //Solo para de sonar si ya han pasado dos ciclos sin recibir señal... //{ noteMIDI(0x90, notasMIDI[pos-1], 0x00); // Parar de tocar la nota por MIDI //noTone(pinAudio); // Parar de tocar la nota por el piezo/auriculares digitalWrite(pinLed, LOW); // Apago el led de estado noteStatus[pos]=0; // Cambio el estado de esa nota a "apagada" //} } } digitalWrite(pinLaser, LOW); // Apago el láser delayMicroseconds(micropausaSensor); // Antes de pasar al siguiente haz, pequeña pausa para reacción del sensor fotoeléctrico //Muevo el motor al siguiente haz: for (int pos2 = 0; pos2<pasosHaces; pos2++) // Avanzo un haz (el número de (micro)pasos definidos en la variable pasosHaces { digitalWrite(pinStep, LOW); digitalWrite(pinStep, HIGH); delayMicroseconds(micropausa); } } } void noteMIDI(int cmd, int pitch, int velocity) { Serial.write(cmd); Serial.write(pitch); Serial.write(velocity); }
Puede descargarse aquí.
Pruebas iniciales y montaje
Detalles
Referencias
http://www.instructables.com/id/Frameless-Laser-Harp/
http://www.instructables.com/id/Easy-and-cheap-Laser-Harp/
http://open-source-energy.org/?topic=1129.0
http://hacknmod.com/hack/create-techno-with-a-laser-harp/
https://gist.github.com/mlorenz92/9775363
http://thecreatorsproject.vice.com/blog/make-peaches-laser-harp-how-to
http://harplaser.blogspot.com.es/
http://laserharpseniorproject.blogspot.com.es/2015/05/tutorial-parts-and-setup.html