( presentation)
My motivation was a one-word-poem which I always wanted to materialize as an interactive installation.
The romantic idea is that when you approach a person who has recently been deprived of her commitment towards another person, she immediately demonstrates an introvertive gesture closing her veil in front of her face. This is the movement I would like to mimique.
~
The components of the installation are:
-a window and
-a curtain in front of it. I imagined them somehow like that:
The first challenge was to figure out how to register the distance of the viewer.
I needed to recycle or use low budget material. I wanted to come up with a simple solution to replace pre-made material on a DIY way.
*The original idea was to build a proximate sensor. I used five high-power infra Red emitter and one receiver diode with the following code:
int IRpin = A0; // IR photodiode on analog pin A0 int IRemitter = 2; // IR emitter LED on digital pin 2 int ambientIR; // variable to store the IR coming from the ambient int obstacleIR; // variable to store the IR coming from the object int value[10]; // variable to store the IR values int distance; // variable that will tell if there is an obstacle or not
void setup(){
Serial.begin(9600); // initializing Serial monitor pinMode(IRemitter,OUTPUT); // IR emitter LED on digital pin 2 digitalWrite(IRemitter,LOW);// setup IR LED as off pinMode(11,OUTPUT); // buzzer in digital pin 11 }
void loop(){ distance = readIR(5); // calling the function that will read the distance and passing the "accuracy" to it.originally 5. Serial.println(distance); // writing the read value on Serial monitor buzzer(); // uncomment to activate the buzzer function }
int readIR(int times){ for(int x=0;x<times;x++){ digitalWrite(IRemitter,LOW); // turning the IR LEDs off to read the IR coming from the ambient delay(1); // minimum delay necessary to read values ambientIR = analogRead(IRpin); // storing IR coming from the ambient digitalWrite(IRemitter,HIGH); // turning the IR LEDs on to read the IR coming from the obstacle delay(1); // minimum delay necessary to read values obstacleIR = analogRead(IRpin); // storing IR coming from the obstacle value[x] = ambientIR-obstacleIR; // calculating changes in IR values and storing it for future average }
for(int x=0;x<times;x++){ // calculating the average based on the "accuracy" distance+=value[x]; } return(distance/times); // return the final value }
The code seemed to work pretty well! It responded very fast – however, the detected area was not too broad…
It did not seem to sense any longer than 25cm.
DEAD END!
*I had to think about alternative solutions. There were several possibilites: motion sensor, photocell,
pressure sensor…
After some research, I found out that a motion sensor works pretty well in a narrow, high-distance range. To achieve such a result, one has to place a tube in front of the detective-area, in order to narrow down the horizon of the sensor. Since it detects only the changes, the distance of the tube placed in front of it does not activate it.
That discovery seemed to be very promising – until Mika gave me an even more promising hint: to simply build a pressure sensor, placed on the floor… so that when someone steps on it, it detects. After experimenting with different materials, it came out that the best is to have one layer of aluminium foil, another of velostat, and again,
aluminium foil. The two layers of aluminium are connected to ground and A0. The resistance between them – thanks for the antistatic foil – lowens when pressed. I put a layer of thin foam, in order to protect the fragile aluminium foil.
At first the sign was very noisy, but after smoothing, it turned out to be quite reliable.
NOW IT WORKS.
The second and third challenge was to move the curtain in front of the window.
mechanics
Let’s see how the gears are working (schematically).
1.closing
2. getting back to normal position
At first I tried to power a DC motor from Arduino through H-bridge. The plan was to connect the two ends of the curtain in a circle, and put the motor in the middle. It did not work. The elliptic form causes a varying tension between the two ends, which makes the circle loose, thus the gears immediately throw the thread off. When I connected the four ends of the threads, one motor was too week to spin it all.
Because of the elliptic form of the track – it has taken a very long while to figure out a system that could move the curtain. In fact, until
now, it functions only theoretically. Finally – in order to go around the varying tension, I installed two motors turning in two opposite directions, so they can keep the two ends tense, while spinning synchronized. I cut the connections between the four threads. The motors are already mounted, but the threads, after assembly have too much friction, so they
brake too easily. As the next and last step, I need to figure out how to wire those. SO…
Still UNDER CONSTRUCTION
THE FINAL CODE:
// A0 pin: sensor //ground: sensor, motor1, motor2 //5V: sensor // D3: motor 1 //D4: motor 2
const int buttonPin = A0; // switch input const int motor1Pin = 3; // H-bridge leg 1 (pin 2, 1A) const int motor2Pin = 4; // H-bridge leg 2 (pin 7, 2A)
int buttonState = 0; int LastButtonState = 0; int PressCount = 0; int sensorValue = 0;
const int numReadings = 10; int readings[numReadings]; // the readings from the analog input int index = 0; // the index of the current reading int total = 0; // the running total int average = 0; // the average
void setup() { // set the switch as an input: pinMode(buttonPin, INPUT);
// set all the other pins you're using as outputs: pinMode(motor1Pin, OUTPUT); pinMode(motor2Pin, OUTPUT);
//smoothing START for (int thisReading = 0; thisReading < numReadings; thisReading++) readings[thisReading] = 0; Serial.begin(9600);
}
void loop() { // subtract the last reading: total= total - readings[index]; // read from the sensor: readings[index] = analogRead(A0); // add the reading to the total: total= total + readings[index]; // advance to the next position in the array: index = index + 1;
// if we're at the end of the array... if (index >= numReadings) // ...wrap around to the beginning: index = 0;
// calculate the average: average = total / numReadings; // send it to the computer as ASCII digits
int sensorValue = average;
Serial.print("sensor Value: "); Serial.println(sensorValue ); Serial.print("Press Count: "); Serial.print(PressCount); delay(10);
//standard setup if (PressCount==0){ digitalWrite(motor1Pin, LOW); // set leg 1 of the H-bridge low digitalWrite(motor2Pin, LOW); }
//close curtain if (sensorValue > 90){ if (PressCount == 0){ digitalWrite(motor1Pin, LOW); // set first motor low digitalWrite(motor2Pin, HIGH); // set second motor high delay (1000); PressCount = 1; Serial.println("CURTAIN CLOSED! ");
} }
//stay closed while pressed if (sensorValue >90){ if (PressCount == 1){ digitalWrite(motor1Pin, LOW); digitalWrite(motor2Pin, LOW); } }
//open the curtains if (sensorValue < 90){ if (PressCount == 1){ digitalWrite(motor1Pin, HIGH); // set first motor high digitalWrite(motor2Pin, LOW); // set second motor low delay (500); PressCount = 0; Serial.println("CURTAIN OPENED! ");
} } delay (100);