lunes, 24 de junio de 2013

Proyecto #8

Último trabajo utilizando filas de leds de 3mm. Parecido en lo técnico a proyectos anteriores, aunque más complejo en su realización, sobre todo por el cambio de formato. En breve añadiré un video para que lo veáis en movimiento. La verdad es que ha quedado muy vistoso.

PD.: Hasta que me di cuenta de que debía usar los pines digitales PWM para encender los leds y controlar el fade. Cosas de novato... Por cierto, la arduino nano V3.0 sólo funciona correctamente con fuente de alimentación a 14V.





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);

}

}