Introduction: An Animation Inside a Water Drop by Physalia
The final result of the piece you have seen has absolutely no CGI, and was shot in stopmotion so as to be able to project inside the waterdrop the logo formation, previously animated in 3D and then printed in paper and placed behind the water drop falling. There were 320 frames printed and replaced frame by frame in the animation, and over 2000 frames compose the final shot- this meaning that the drop you see is never the same, there are 2000 different drops in the piece. In order to be able to photograph each one in exactly the right place as to be able to see a fluid fall, we created an Arduino-based system in which, after having the drop cross a laser pointer, we would have the absolute precision of when to trigger the flashes and camera to see the drop in the right position. We worked very hard to synch this mechanism to our Motion Control system, and the final piece is the result of a 3-week testing process in which we shot about 45 splashing tests with over 20000 pictures taken, before we produced the final shot.
Step 1: Detecting the Water Drop: Laser Beam-photodiode
We also investigated the fastest electronic component that measures interruption of a laser beam. Among a choice of photoresistors, phototransistors and other components capable of measuring light variations, we ended up using a photodiode. After some testing, we added some resistances in parallel so as it wouldn’t be so sensitive and would only be affected by interruptions of the laser beam, and not ambiance light for example. This tiny circuit is enough to allow the photodiode to work as a digital switch putting out 5v when the laser hits the photoreceptor, and 0 when a water drop interrupts the laser beam. We also placed a cinefoil (a black matte aluminium sheet used in photography) pierced with a needle was placed in front of the laser pointer so as to make it even more precise to the dripping.
Step 2: Triggering the Flashes
One of the big limitations we also encountered to this effect were the number of flashes used to light the set. Shortly after starting, we realized that lighting the water drops with just two flashes for the whole downward course of the drop was nearly impossible. The picture was underexposed either at the beginning or the end of the journey, and proper constant lighting was impossible to achieve. We decided then to rent two more flashes and build two more flash-trigger circuit boards, but after a new picture, a new problem ensued: the older flashes were much faster than the rented, newer Canon flashes, with the result of a double-exposed picture.
We tried to solve this by programming a delay in the old flashes, and although we almost matched the two speeds, they never really flashed at the same time. So, in the end, we had to make do with just two flashes. The conclusion was that, for a project like this, where a difference of microseconds is paramount, same model and brand flashes are needed. This, added to the limited space in our Lightbox, compromised the final result of the piece.
Step 3: Triggering the Camera (any DSLR or Remotely Triggered Camera)
When considering the present exercise- shooting a water drop- we need to bear in mind that, although the camera is capable of shooting really fast, it is much easier to work in complete darkness and work with the shutter in B, letting the flash be the one capturing the droplet in the air. For minimizing synch problems, we programmed it so the shutter opens when the first droplet passes through the laser beam and the flashes are triggered when the second droplet is in the desired position.
Step 4: Water Course
Step 5: Following the Water Drop – Motion Control
Step 6: Communicating With the Motion Control
The servo would then press the spacebar after each picture, while the Motion Control would move in small increments and adjusting focus at the same time. We will get into more detail about the Motion Control in a future post, but building a two-axes rig (tilt and focus) is not so difficult, in case you want to attempt the same experiment. The internet has loads of information about it and there are Arduino AccelStepper libraries that make the job much easier. The ingredients would be two stepper motors, two drivers, power supply and an Arduino. The only thing left would be to build a camera rig to your fancy.
Step 7: Arduino Programming
To test the theory we shot a number of pictures with the same delay and they were all very similar. We also realized that, by getting rid of the potentiometer and any communication with the laptop, the pictures were more and more similar- like two drops of water!
To test the theory we shot a number of pictures with the same delay and they were all very similar. We also realized that, by getting rid of the potentiometer and any communication with the laptop, the pictures were more and more similar- like two drops of water! We then cleaned the code and added some ideas to make the system more trustworthy, like adding a millisecond after each 1000 microseconds to help the Arduino manage such large amounts of figures.
CODE:
// "Entropy Machine" for IDN Magazine by Physalia. Coded by Jordi Planas & Pablo Barquin
#include <Servo.h>
int flash1 = 9; // Pin del Flash 1 pin 9
int flash2 = 12; // Pin del Flash 2 pin 11
int laser= 2; //Pin del fotodiodo
int camara = 3; //Pin del optoacoplador donde se conecta la camara
int boton1= 7; //Boton de disparo de foto
int boton2= 13; //Boton de repeticion de foto (no incrementar)
boolean clic1= false; //Buleano para el boton 1
boolean clic2= false; //Buleano para el boton 2
boolean laserState= false; //Buleano del laser
int i=1; //Variable que cuenta las gotas (primera o segunda)
Servo servo1; // Crea un Objeto servo
//int f=0; //Numero de fotos para DEBUG
////////////////////////// TIEMPOS //////////////////////////////////////////////////////////////////////////////
int delai= 0; //Espera en milisegundos para la primera foto
int delaim= 0; //Delay inicial al que se le suma el incremento
int incremento= 250; //Incremento en microsegundos
int guardarfoto= 4000; //Espera de la camara para guardar la foto
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){
//Serial.begin(9600); //Activar para hacer DEBUG
pinMode(flash1, OUTPUT);
pinMode(flash2, OUTPUT);
pinMode(laser, INPUT);
pinMode(camara, OUTPUT);
pinMode(boton1,INPUT);
pinMode(boton2,INPUT);
servo1.attach(6);
servo1.write(0); //Posicion inicial del servo
}
void loop(){
botones();
if (clic1 == true) { //Si el boton esta pulsado
lecturalaser(); //Ejecutamos la funcion lecturalaser
}
{ //Si el boton NO esta pulsado
} //No ocurre nada
}
void lecturalaser(){
laserState = digitalRead(laser);
if (laserState == HIGH) { //Si el laser no esta interrumpido
} //No ocurre nada
else { //Si el laser se interrumpe (LOW)
foto(); //Se ejecuta la funcion foto
}
}
void botones(){
int dclic1 = digitalRead(boton1);
int dclic2 = digitalRead(boton2);
if(dclic1==HIGH){
clic1=true;
}
if(dclic2==HIGH){
clic2=true;
}
}
void foto(){
if (i == 1){ //Si solo ha pasado una gota por el laser
delay(20); //Debounce del laser
digitalWrite(camara, HIGH); //Empezamos a obturar con la camara
i = i++; //Sumamos 1 a i para que dispare a la segunda gota
}
else { //Si i = 2
disparo(); //Ejecutamos la funcion disparo
i = 1; //i vuelver a valer 1
}
}
void disparo(){
if (clic2 == true){ //Si el boton 2 ha sido pulsado
delay(delai); //Esperamos "delai"
delayMicroseconds(delaim); //Esperamos el incremento en Microsegundos
flasheo(); //Ejecutamos flasheo
}
else { //Si el boton 2 NO ha sido pulsado
incrementar(); //Incrementamos la espera ejecutando la funcion incrementar
delay(delai); //Esperamos "delai"
delayMicroseconds(delaim); //Esperamos el incremento en Microsegundos
flasheo(); //Ejecutamos flasheo
motion(); //Movemos la motion
}
}
void flasheo(){
digitalWrite(flash1, HIGH); //Disparamos el flash 1
digitalWrite(flash2, HIGH); //Disparamos el flash 2
delay(10); //Le damos tiempo al flash mientras recibe un impulso
digitalWrite(camara, LOW);
digitalWrite(flash1, LOW); //Apagamos el flash 1
digitalWrite(flash2, LOW);
clic1=false; //Quitar si queremos las gotas automaticas
clic2=false;
/*f = f++;
Serial.println("Delay Inicial:"); //DEBUG
Serial.println(delai);
Serial.println("Delay Microsegundos:");
Serial.println(delaim);
Serial.println("Numero de fotos:");
Serial.println(f); */
}
void motion(){
delay(300);
servo1.write(90);
delay(100);
servo1.write(0);
/*
Serial.println("Motion"); //DEBUG
Serial.println("Esperando");
delay(guardarfoto); //Esperamos a que la camara guarde la foto
Serial.println("LISTO!!!!!!!"); */
}
void incrementar(){
delaim+=incremento;
if (delaim > 1000){
delaim = delaim -1000;
delai = delai++;
}
}
Step 8: The Electronic Schematic
Step 9: Animation Inside a Water Drop
The animation was rendered and the printed to be then replaced frame by frame in the piece. In this case, since we had to end in the IdN logo, each frame was placed behind the drop upside down so as to account for the inversion inside the water drop.
Step 10: First Tests
Step 11: Credits
Direction and Production: Physalia
Comissioned by IdN Magazine
Audio: CypherAudio
Programming: Jordi Planas & Physalia
Making Of Pictures: Albert Treblah
Please visit us at http://www.physaliastudio.com
And join us at https://www.facebook.com/pages/Physalia-Studio/312137322501?fref=ts
Physalia Love!