sábado, 8 de diciembre de 2012

Proyecto #7

Continuando con el tema del control de luces mediante Arduino, me decidí a crear una de mis cajas de luz de forma que cada placa de metacrilato pintado pudiera retroiluminarse separadamente y, así, poder crear una "animación", por decirlo de alguna manera. Lo siguiente será que la secuencia de iluminación pueda cambiar según la intensidad de la luz (mediante un LDR) o mediante la lectura del volumen de sonido circundante (mediante un mini-micrófono). Ahí os dejo el prototipo. Menudo tute de soldar leds (en total 100 bombillitas).


miércoles, 17 de octubre de 2012

Proyecto #6

Después de tanto trasiego soldando diodos led y resistencias, decidí cambiar de tercio y volver a los motores. Tenía 9 servos que me funcionaban, de los que giran 180º, y me puse a probar cómo montarlos para crear algo que tuviera cierto efecto óptico. El prototipo resultante, sin dejar de ser muy simple, produce una sensación curiosa. Con ciertos ajustes y con un mayor número de servos (con Arduino Mega se pueden usar hasta 48 servos con alimentación externa) se podría hacer un montaje bastante interesante. Lo próximo será hacer que los servos reaccionen cuando alguien se mueva delante de la pieza, usando un sensor PIR que me encontré en la basura y que, después de probarlo, demostró estar a pleno rendimiento con una alimentación de 5V.


martes, 11 de septiembre de 2012

Proyecto #5

En la senda del anterior proyecto, en el que jugaba con la aleatoriedad del sonido generado gracias a la librería pitches.h de Arduino, he construido una caja de 81 leds que se iluminan de forma simétrica, conforme a la estructura de un cuadrado. Las luces se encienden aleatoriamente de 4 en 4 cada vez que algún ruido hace reaccionar el micrófono incorporado, creando una secuencia imprevisible, tanto de forma como de sonido. Aún no está terminado pues me gustaría añadir filtros de color a los leds, pero ahí os dejo el prototipo funcionando:



miércoles, 16 de mayo de 2012

Proyecto #4

Llevo un tiempo trabajando en un nuevo proyecto en el que he querido aunar movimiento, sonido e interacción. Aprovechando un montón de ventiladores de refrigeración de ordenadores viejos que me ofreció un amigo, decidí aprovecharlos para crear algo con ellos y ARDUINO. El resultado es un cuadro cinético que interactúa con el espectador de una forma muy simple. Cuando alguien hace algún ruido que sobrepase cierto nivel de decibelios la pieza se pone en funcionamiento haciendo girar los motores en una secuencia de duración aleatoria (gracias al uso de una placa de 8 relés). Además, a cada motor en movimiento le acompaña una nota musical también aleatoria, originada gracias a la librería pitches.h para ARDUINO y a dos altavoces viejos que me encontré en un punto limpio colocados a derecha e izquierda de la estructura. El resultado es un prototipo que funciona y que puede servir para plantearme proyectos futuros de mayor envergadura.

Mecanismo interno


Esquema de la circuitería interior:


Programa de Arduino (incluye la librería pitches.h):
#include "pitches.h"
int sensorPin1 = A0;
int Knock1 = 52;
int Knock2 = 53;
int sensorValue1 = 0;

#define RELAY_ON 0
#define RELAY_OFF 1

#define Relay_1  2 
#define Relay_2  3
#define Relay_3  4
#define Relay_4  5
#define Relay_5  6
#define Relay_6  7
#define Relay_7  8

void setup()  
{
pinMode(Knock1, OUTPUT);
pinMode(Knock2, OUTPUT);
Serial.begin(9600);
 
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF);
  digitalWrite(Relay_5, RELAY_OFF);
  digitalWrite(Relay_6, RELAY_OFF);
  digitalWrite(Relay_7, RELAY_OFF); 
 
  pinMode(Relay_1, OUTPUT);  
  pinMode(Relay_2, OUTPUT); 
  pinMode(Relay_3, OUTPUT); 
  pinMode(Relay_4, OUTPUT);
  pinMode(Relay_5, OUTPUT); 
  pinMode(Relay_6, OUTPUT); 
  pinMode(Relay_7, OUTPUT); 
  delay(1000);

}

void loop() 
{
sensorValue1 = analogRead(sensorPin1);
Serial.println(sensorValue1);
 
   if (sensorValue1 > 500) {
     
  digitalWrite(Relay_1, RELAY_ON);
  tone(Knock1, random(5000), 200);
  delay(random(200, 800));  
       
  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_ON);
  tone(Knock2, random(5000), random(100, 200));
  delay(200); 
         
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_ON);
  tone(Knock1, random(5000), random(100, 300));
  delay(300); 
           
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_ON);
  tone(Knock2, random(4000), random(50, 100));
  delay(random(100, 800));
           
  digitalWrite(Relay_4, RELAY_OFF);
  digitalWrite(Relay_5, RELAY_ON);
  tone(Knock1, random(5000), random(100, 300));
  delay(300);  
          
  digitalWrite(Relay_5, RELAY_OFF);
  digitalWrite(Relay_6, RELAY_ON);
  tone(Knock2, random(5000), random(50, 100));
  delay(random(100, 1000));  
          
 digitalWrite(Relay_6, RELAY_OFF);
 digitalWrite(Relay_7, RELAY_ON);
 tone(Knock1, random(5000), random(100, 400));
 delay(400);  
           
 digitalWrite(Relay_7, RELAY_OFF);
  }

}


lunes, 9 de abril de 2012

Proyecto #3. Jugando con sonido/2

Aquí seguimos investigando las posibilidades sonoras de los sensores LDR combinados con la funcion tone() y la librería pitches.h (notas en MIDI) creada por Tom Igoe para tocar tonos musicales con piezoeléctricos y bafles convencionales. En esta ocasión sólo trabajo con Arduino, conectado a 4 sensores LDR mediante resistencias de 10K que leen la intensidad de la luz de un disco perforado. Dichos sensores reconocen las diferencias de intensidad de la luz de manera que disparan una nota musical o varias, según el caso. Se pueden manipular las escalas mediante un potenciómetro (el cual se podría adaptar a cada uno de los sensores por separado). Seguiré investigando para poder crear algún tipo de armonía sonora que luego, mediante Processing, se pueda convertir también en alguna armonía "cromática".


A continuación el código para Arduino:

#include "pitches.h"

  int melody1[] = {
  NOTE_C4, NOTE_G3,NOTE_G3};

  int melody2[] = {
  NOTE_C5, NOTE_A7, NOTE_G2};
 
  int noteDurations[] = {
  8, 16, 8 };

  int sensorPin1 = A0;
  int sensorPin2 = A1;
  int sensorPin3 = A2;
  int sensorPin4 = A3;

  int potenciometroPin = A4;
    
  int Knock1 = 2;
  int Knock2 = 3;
  int Knock3 = 4;
  int Knock4 = 5;

  int sensorValue1 = 0;
  int sensorValue2 = 0;
  int sensorValue3 = 0;
  int sensorValue4 = 0;

  int potenciometro = 0;

void setup() {

  pinMode(Knock1, OUTPUT);
  pinMode(Knock2, OUTPUT);
  pinMode(Knock3, OUTPUT);
  pinMode(Knock4, OUTPUT);
 
  Serial.begin(9600);
 
}

void loop() {

  sensorValue1 = analogRead(sensorPin1);
  sensorValue2 = analogRead(sensorPin2);
  sensorValue3 = analogRead(sensorPin3);
  sensorValue4 = analogRead(sensorPin4);
 
  potenciometro = analogRead(potenciometroPin);
 
  Serial.println(potenciometro);
  delay(50);
 
  if (sensorValue3 > 900) {
      tone(Knock3, potenciometro , 70);
     // delay(50);
    }
  if (sensorValue4 > 900) {
      tone(Knock4, potenciometro*2 , 70);
     // delay(50);

}
   if (sensorValue1 > 900) {
   
      for (int thisNote = 0; thisNote < 3; thisNote++) {
      int noteDuration = 1000/noteDurations[thisNote];
      tone(Knock1, melody1[thisNote],noteDuration);
   
      int pauseBetweenNotes = noteDuration;
      delay(pauseBetweenNotes);
   
      noTone(Knock1);
  }
    }
   

    if (sensorValue2 > 900) {
      //tone(Knock2, random(31,potenciometro*2) , 100);
      //delay(50);
       for (int thisNote = 0; thisNote < 3; thisNote++) {
       int noteDuration = 1000/noteDurations[thisNote];
       tone(Knock2, melody2[thisNote],noteDuration);
   
       int pauseBetweenNotes = noteDuration;
       delay(pauseBetweenNotes);
   
       noTone(Knock2);
    }


    }
}


A continuación el tab que hay que incluir en el parche con el nombre pitches.h (cada número corresponde con una nota musical):


 /*************************************************
 * Public Constants
 *************************************************/

#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978

miércoles, 28 de marzo de 2012

Proyecto #3. Jugando con sonido/1

Hace tiempo descubrí la web CreativeApplications.net en la que varios artistas envueltos en el uso de tecnología muestran sus proyectos y prototipos. De entre ellos llamó poderosamente mi atención el trabajo de dos grupos de artistas que trabajan con Arduino y Processing:

1) El colectivo www.the-product.org y su obra Soundmachines, y
2) Bartholomäus Traubeck y su obra Years.

Ambos proyectos buscan convertir en sonido códigos de imágenes. El primero, Soundmachines, utiliza algo así como discos perforados que al iluminarse permiten la lectura de códigos de luz que generan loops de sonido, de forma que podemos crear música de baile de forma fácil e intuitiva. El segundo es más poético. Se trata de un giradiscos capaz de leer las líneas de tiempo de un troco de árbol. Las diferencias de intensidad en las líneas generan una música al piano en apariencia caótica, incluso aleatoria. Al final se percibe cierta armonía.

Digamos que me quedé un tanto boquiabierto ante piezas tan sugerentes y, actualmente, estoy intentando emular técnicamente lo que tales artistas han logrado, para luego crear mis propias piezas en las que imagen y sonido interactúen. Mi idea inicial, parecida a la de Soundmachines, consistiría en crear un giradiscos en el que cualquiera pudiera insertar su propio disco dibujado, al modo de los discos perforados de los organillos antiguos. 

Dichos dibujos serían leídos mediante un cabezal que tuviera diferentes sensores LDR que fueran sensibles a los cambios de luminosidad y convirtieran dichos cambios en señales para hacer saltar notas musicales, un archivo sonoro, etc. A su vez, tales cambios de luminosidad podrían convertirse de nuevo en imágenes a través de Processing. A continuación os muestro mi primer intento de hacer esta idea realidad. He utilizado un motorcito de microondas para hacer girar el disco, 2 LDR conectados a una placa Arduino Mega mediante resistencias de 10K y una bombilla para iluminar el disco y aumentar el contraste de la lectura. En cuanto al software, he usado la librería Firmata(StandardFirmata) de Arduino para controlar la microcontroladora directamente desde Processing. En Processing he utilizado un programa que utiliza la librería SoundCipher que permite utilizar diferentes sonidos de forma muy fácil. A lo anterior he añadido un sencillo dibujo mediante curveVertex(). A medida que vaya avanzando iré descargando más información. Más abajo os dejo un video y el código de este primer prototipo que iré complicando y puliendo a medida que vaya trabajando. Por cierto, se admiten sugerencias.


Código para Processing:

//Importar libreria SoundCipher para controlar sonidos con Processing

import arb.soundcipher.*;

SoundCipher sc1 = new SoundCipher(this);
SoundCipher sc2 = new SoundCipher(this);

//Importar libreria Serie para conectar Arduino con Processing
//(Hay que tener previamente descargada en la microcontroladora la libreria Firmata)

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;

//Pines analogicos de los sensores LDR

int potPin1=0;
int potPin2=1;

//Valores analogicos de los sensores LDR

int val1;
int val2;

//Declaramos los puntos del dibujo que variaran con los datos de los sensores LDR

float point_level_1, point_level_2, point_level_3;

void setup() {
 
size(400, 400);

//Elegimos puerto serie para la placa arduino

arduino = new Arduino(this, Arduino.list()[0], 57600);

smooth();

}

void draw() {
 
  background (255);
  noFill ();
 
//Reduce la lectura analogica de los ensores LDR a una cuarta parte

val1 = arduino.analogRead(potPin1)/4;
val2 = arduino.analogRead(potPin2)/4;

//Mapea los valores entrantes de los sensores LDR a valores adaptados a la ventana de Processing

float grey1= map(val1, 190, 240, 0, 400);
float grey2= map(val2, 190, 240, 0, 400);

//Escribe los valores de los sensores LDR que estan conectados a Arduino

println("val1");
println(val1);
println("val2");
println(val2);

 //Dibujo de la pantalla de Processing
 //1
  point_level_1=map(grey1, 0, width, 25, 50);
  fill (44, 215, 230, 255);
  curveTightness (map(grey1, 0, height, 20, -5));
  beginShape ();
  curveVertex (width/2-point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2-point_level_1);
  curveVertex (width/2-point_level_1, height/2-point_level_1);
  curveVertex (width/2-point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2+point_level_1);
  curveVertex (width/2+point_level_1, height/2-point_level_1);
  endShape ();
  //2
  point_level_2=map(grey2, 0, height, 30, 60);
  fill (255, 59, 142, 200);
  curveTightness (map(grey2, 0, width, -7, 25));
  beginShape ();
  curveVertex (width/2-point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2-point_level_2);
  curveVertex (width/2-point_level_2, height/2-point_level_2);
  curveVertex (width/2-point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2+point_level_2);
  curveVertex (width/2+point_level_2, height/2-point_level_2);
  endShape ();
  //3
  point_level_3=map(grey2, 0, height, -60, -10);
  fill (0, 0, 0, 20);
  curveTightness (map(grey2, 0, height, -5, 20) );
  beginShape ();
  curveVertex (width/2-point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2-point_level_3);
  curveVertex (width/2-point_level_3, height/2-point_level_3);
  curveVertex (width/2-point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2+point_level_3);
  curveVertex (width/2+point_level_3, height/2-point_level_3);
  endShape();

//A partir de un nivel de luz lanzar una nota musical

if(val1 > 230){
 
sc1.playNote(70, 500, 0.2);
delay(800);

}else if(val2 > 230){
sc2.playNote(40, 500, 0.2);

delay(600);

}

}

jueves, 23 de febrero de 2012

Proyecto #2

Seguimos trabajando con Arduino y luces. En este caso pasamos de utilizar relés con bombillas de 220V a usar bombillitas led de 3.3V. Este proyecto básicamente consiste en crear una obra de carácter cinético que consta de luces que se apagan y se encienden siguiendo una secuencia de tiempo descargada en la microcontroladora. El programa que vamos a cargar en la placa Arduino es una versión del código básico del famoso BLINK contenido en los ejemplos del IDE de Arduino. La placa está conectada a 12 luces led, utilizando resistencias de 220 Ohm para que no se fundan con los 5V que los pines digitales de la microcontroladora dan por defecto. A continuación se muestran los diferentes elementos que componen el cuadro, un video con el resultado final y el código que lo hace funcionar.

Materiales:

- 12 diodos led
- 12 resistencias de 220 Ohm
- Arduino Duemilanove
- 2 Regletas fluorescentes de 14V
- Adaptador de corriente 220V/9V
- Maderas
- Metacrilato
- Pintura acrílica y óleo

La estructura consta en su interior de dos tubos de luz fluorescente para iluminar la imagen frontal, realizada usando óleo sobre una plancha de metacrilato. La cara posterior es la que consta de una iluminación mediante leds controlados por la placa Arduino.

Vista frontal

Vista lateral

Interior del cuadro

Placa ARDUINO conectada a las luces led

A continuación el código para la placa Arduino. Es muy simple:

//Definimos los pines para cada led.

int ledPin1 = 1;
int ledPin2 = 2;
int ledPin3 = 3;
int ledPin4 = 4;
int ledPin5 = 5;
int ledPin6 = 6;
int ledPin7 = 8;
int ledPin8 = 9;
int ledPin9 = 10;
int ledPin10 = 11;
int ledPin11 = 12;
int ledPin12 = 13;

// El Setup () sólo se lee UNA vez (como en Processing).

void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(ledPin7, OUTPUT);
pinMode(ledPin8, OUTPUT);
pinMode(ledPin9, OUTPUT);
pinMode(ledPin10, OUTPUT);
pinMode(ledPin11, OUTPUT);
pinMode(ledPin12, OUTPUT);
}

// El Loop () se lee constantemente.

void loop() {
 
digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin5, HIGH);
digitalWrite(ledPin7, HIGH);
digitalWrite(ledPin9, HIGH);
digitalWrite(ledPin11, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin4, LOW);
digitalWrite(ledPin6, LOW);
digitalWrite(ledPin8, LOW);
digitalWrite(ledPin10, LOW);
digitalWrite(ledPin12, LOW);
delay(1000);

// Esperamos 1000 milisegundos (1 seg)

digitalWrite(ledPin1, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin5, LOW);
digitalWrite(ledPin7, LOW);
digitalWrite(ledPin9, LOW);
digitalWrite(ledPin11, LOW);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin4, HIGH);
digitalWrite(ledPin6, HIGH);
digitalWrite(ledPin8, HIGH);
digitalWrite(ledPin10, HIGH);
digitalWrite(ledPin12, HIGH);
delay(1000);

// Esperamos 1000 milisegundos (1 seg)

digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin5, HIGH);
digitalWrite(ledPin8, HIGH);
digitalWrite(ledPin10, HIGH);
digitalWrite(ledPin11, HIGH);
digitalWrite(ledPin4, LOW);
digitalWrite(ledPin6, LOW);
digitalWrite(ledPin12, LOW);
delay(1000);

digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin4, HIGH);
digitalWrite(ledPin6, HIGH);
digitalWrite(ledPin7, HIGH);
digitalWrite(ledPin9, HIGH);
digitalWrite(ledPin12, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin5, LOW);
digitalWrite(ledPin8, LOW);
digitalWrite(ledPin10, LOW);
digitalWrite(ledPin11, LOW);
delay(1000);

digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, HIGH);
digitalWrite(ledPin6, HIGH);
digitalWrite(ledPin5, HIGH);
digitalWrite(ledPin7, HIGH);
digitalWrite(ledPin8, HIGH);
digitalWrite(ledPin9, HIGH);
digitalWrite(ledPin10, HIGH);
digitalWrite(ledPin11, HIGH);
digitalWrite(ledPin12, HIGH);
delay(1000);

digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin6, LOW);
digitalWrite(ledPin7, LOW);
digitalWrite(ledPin10, LOW);
digitalWrite(ledPin11, LOW);
delay(1000);

digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin3, HIGH);
digitalWrite(ledPin4, LOW);
digitalWrite(ledPin5, LOW);
digitalWrite(ledPin6, HIGH);
digitalWrite(ledPin7, HIGH);
digitalWrite(ledPin8, LOW);
digitalWrite(ledPin9, LOW);
digitalWrite(ledPin10, HIGH);
digitalWrite(ledPin11, HIGH);
digitalWrite(ledPin12, LOW);
delay(1000);

digitalWrite(ledPin1, HIGH);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin6, LOW);
digitalWrite(ledPin7, LOW);
digitalWrite(ledPin10, LOW);
digitalWrite(ledPin11, LOW);

delay(500);

}

//Puedes cambiar las ordenes encendido/apagado como quieras.

Este es el resultado final:


miércoles, 22 de febrero de 2012

Proyecto #1

A continuación os detallo mi primer trabajo artístico utilizando la microcontroladora opensource ARDUINO. Se trata de una caja de luz en la que, mediante una placa de 4 relés conectados a una Arduino Mega, se logra controlar el encendido y apagado de 4 grupos de luces diferentes.

ARDUINO Mega
Placa de 4 relés a 5V

Todo el tinglado está embutido en una caja de madera de DM de dimensiones 100 x 100 x 10 cms, pintada con acrílico y en la que se han hecho diferentes orificios con una taladradora. En dichos orificios hay una placa de metacrilato con diferentes filtros coloreados. El resultado se muestra en las siguientes fotos:

Estructura interna
Placa ARDUINO + placa de 4 relés

Las 4 fases de luz

A continuación unas líneas de código para quien esté interesado:

/* YourDuino Example: Relay Control 1.10
  Handles "Relay is active-low" to assure
  no relay activation from reset until
  application is ready.
   terry@yourduino.com */

/*-----( Import needed libraries )-----*/
/*-----( Declare Constants )-----*/

#define RELAY_ON 0
#define RELAY_OFF 1

/*-----( Declare objects )-----*/
/*-----( Declare Variables )-----*/

#define Relay_1  2  // Arduino Digital I/O pin number
#define Relay_2  3
#define Relay_3  4
#define Relay_4  5

void setup() 
   /****** SETUP: RUNS ONCE ******/
{
//-------( Initialize Pins so relays are inactive at reset)----

  digitalWrite(Relay_1, RELAY_OFF);
  digitalWrite(Relay_2, RELAY_OFF);
  digitalWrite(Relay_3, RELAY_OFF);
  digitalWrite(Relay_4, RELAY_OFF); 
 
//---( THEN set pins as outputs )---- 

  pinMode(Relay_1, OUTPUT);  
  pinMode(Relay_2, OUTPUT); 
  pinMode(Relay_3, OUTPUT); 
  pinMode(Relay_4, OUTPUT);   
  delay(4000); 
//Check that all relays are inactive at Reset

} 

//--(end setup )---

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
//---( Turn all 4 relays ON in sequence)---

  digitalWrite(Relay_1, RELAY_ON);
  delay(1000);        
  digitalWrite(Relay_2, RELAY_ON);
  delay(1000);            
  digitalWrite(Relay_3, RELAY_ON);
  delay(1000);           
  digitalWrite(Relay_4, RELAY_ON);
  delay(4000);           
 
//---( Turn all 4 relays OFF in sequence)--- 

  digitalWrite(Relay_1, RELAY_OFF);
  delay(1000);             
  digitalWrite(Relay_2, RELAY_OFF);
  delay(1000);            
  digitalWrite(Relay_3, RELAY_OFF);
  delay(1000);             
  digitalWrite(Relay_4, RELAY_OFF);
  delay(4000);             
 
}
//--(end main loop )---