Lunda: La luz que "para" el tiempo

Acerca del proyecto

Este proyecto juega con la percepción provocando ilusiones ópticas en el cerebro del observador. Así objetos con movimiento repetitivo se perciben como si estuviesen quietos o moviéndose a una velocidad o sentido diferentes a los reales.

Los objetos que utilizamos fueron un ventilador y una goma elástica. Otros móviles diferentes provocarían el mismo efecto siempre que mantengan una frecuencia constante.


Componentes y herramientas


Materiales

Lcd I2C 1602 1
Led blanco 5mm 10
Alambre de acero
Cable de cobre
Borneras 2
Cartón
pcb 1
Condensador 22pf 2
Cristal de cuarzo 16MHz 1
Atmega328p 1
Resistencia 10 Ohm 2W 1
Resistencia 10k 1/4W 3
Transistor 2N2222A 1
Botón 1
Rotary encoder 1
Jack de alimentación hembra 1
Jack de alimentación macho 1
Palitos de helado 2-3


Herramientas

Soldador
Pegamento instantáneo
Destornillador de punta plana



Funcionamiento

El móvil ha de permanecer a oscuras, iluminado tan solo por una luz intermitente con una frecuencia variable controlada por nosotros a través de un mando.
Este montaje hace que el usuario solo pueda ver ciertas posiciones del objeto en cuestión, las iluminadas, y si el parpadeo del led es lo suficientemente rápido (mínimo 24 pulsos por segundo), el cerebro unirá las imágenes como un continuo creando así una percepción del movimiento distinta a la real.

VENTILADOR
En principio se mueve a una velocidad tal que es imposible distinguir las palas pero utilizando nuestro controlador logramos percibirlas inmóviles, girando lentamente hacia delante o atrás e incluso ver algo escrito o dibujado en ellas.

Podemos hacer que este "se mueva" de 3 formas distintas:

1. Quieto: En este caso cada vez que la luz se enciende las aspas están en la misma posición así que al unirse en el cerebro del espectador todas las instantáneas, el ventilador se percibe estático.

2. Rotando en el sentido de las agujas del reloj: Cada vez que la luz se enciende ilumina las aspas en una posición adelantada con respecto a la iluminada anteriormente. Cuanto más adelantada esté, más rápido parecerá girar.

3. Rotando en el sentido contrario a las agujas del reloj: Ocurre exactamente igual que lo descrito anteriormente salvo que las posiciónes de cada instantánea están rotadas cada una con respecto a la otra en el sentido contrario.


Vídeos

A continuación adjuntamos dos videos en los que se puede ver el efecto.


Montaje

Presentamos el proyecto en dos cajas de cartón:
La primera, de 13x8x2cm está destinada a mantener el circuito y la otra, de 36x32x32cm, cubre al móvil en cuestión, tiene incorporados los leds y proporciona la suficiente oscuridad para que el efecto sea posible.

La primera caja puede abrirse por la parte superior mediante un cierre hecho con palos de helado






La segunda caja tiene una ventana frontal y carece de suelo; podemos así ponerla encima del objeto al que queramos aplicar el efecto.




Código


A continuación presentamos la programación del microcontrolador arduino. Con ella modificamos el parpadeo del led a través de una interfaz que permite al usuario interactuar con el proyecto.


#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f ,16, 2);
#define clk 11
#define data 10
#define btn 9
#define tra 13
int on = 200;
boolean bluestate = false;
int preciso = 0, impreciso = 0;
int Millis = 0, Micros = 0;
long reach = 1000000;
//Encoder
int last = LOW, n;
//Menus
String principal[] = {"Calibrar", "Frecuencia"};
String calibrar[] = {"Millis: "+ (String)impreciso, "Micros: " + (String)preciso};

void setup() {
  Serial.begin(9600);
  lcd.begin();
  lcd.backlight();
  Serial.println(reach);
}

int cnt = 0;
void loop() {
  switch (menu(principal, 2)) {
    case 0:
    calibrar[0] = "10*Micros: " +(String)impreciso;
    calibrar[1] = "Micros: " + (String)preciso;
      if (menu(calibrar, 2) == 0) {
        boolean canps = false;
        setlcd("10Microsegundos:", (String)impreciso);
        while (!canps) {
          encoder(&impreciso, &canps, 1);
          setlcd("10*Microsegundos", (String)impreciso);
        }
      } else {
        boolean canps = false;
        setlcd("Microsegunos:", (String)preciso);
        while (!canps) {
          encoder(&preciso, &canps, 1);
          setlcd("Microsegundos:", (String)preciso);
        }
      }
      break;
      case 1:
      double frq = 0;
      boolean canps = false;
        while(!canps) {
          frq = 1/((preciso+impreciso*10.0)/1000000.0);
          if(digitalRead(btn) == LOW) {
          encoder(&preciso, &canps, 1);  
          }
          setlcd("Frecuencia", (String)frq); 
        }
      break;
  }
}

boolean encbuff = false;
void encoder(int *cnt, boolean *butn, int jump) {
  int buff = *cnt;
  while (true) {
    n = digitalRead(clk);
    if (digitalRead(btn) == HIGH && encbuff == false) {
      *butn = true;
      encbuff = true;
      break;
    } else if (digitalRead(btn) == LOW) {
      encbuff = false;
    }
    if ((last == LOW) && (n == HIGH)) {
      if (digitalRead(data) == LOW) {
        *cnt = *cnt + jump;
      } else {
        if (*cnt != 0) {
        *cnt = *cnt - jump;
        }
      }
    } else {
      //Encendido y apagado del led
      if (micros() >= reach) {
        digitalWrite(tra, 1);
        delayMicroseconds(on);
        digitalWrite(tra, 0);
        reach = (preciso)+(impreciso*10)+micros();
      }
      //------------------------------------
    }
    last = n;
    if (buff != *cnt) {
      break;
    }
  }
}

void setlcd(String a, String b) {
  lcd.clear();
  lcd.print(a);
  lcd.setCursor(0, 1);
  lcd.print(b);
}
//Menus
int menu(String menus[], int cnt) {
  setlcd(menus[0], menus[1]);
  lcd.setCursor(15, 0);
  int current = 0;
  boolean boton = false; 
  while (true) {
    encoder(&current, &boton, 1);
    if (current >= cnt) {
      current = cnt-1;
    } else if (current <= 0) {
      current = 0;
    }
    if (boton == true) {
      boton = false;
      return current;
    }
    if (current % 2 == 0) {
      setlcd(menus[current], menus[current+1]); 
      lcd.setCursor(15, 0);
      lcd.print("*");
    } else {
      setlcd(menus[current-1], menus[current]);
      lcd.setCursor(15, 1);
      lcd.print("*");
    }
  }
}

Esquema


Estas serían las conexiones entre los diferentes componentes.

Comentarios