Midterm project

I was paired with Nicola Carpegginai and we decided to work on an infinity mirror that will have neo pixels strips that will be controlled by the movement of the side mirrors that will be attached to it as a triptych.
il_570xN.757243302_pqy5

The inspiration for this project came after I saw this Kaleidoscopic visuals made with the neo pixels and thought about incorporating it with an infinity mirror.

Growing up, we had a triptych right at the entrance to our house and I used to stare at it for hours, looking at the reflections made by the angles of the mirrors.  It occurred to me that it could be interesting to control the neo pixels with the movement of theses side doors and see what kind of visual effects could appear. Then I thought about  Yayoi Kusama‘s Infinity room that I saw a couple of years ago at the Tate Modern in London.

Yayoi-Kusama

I started searching for infinity mirrors made with Arduino and found this beautiful Warmhole Actualization Machine made by Alan Watts
WAManim

and looked up for more references on google images
1400609954LB_LM19190_Via_Negativa_II_LMG_2014_Inst_det04_hr

kusama139b

and also found this amazing Infinity Room made with code..

We started by playing around with the neo pixel library and accelerometer.  Originally we bought the ADXL345 accelerometer, but soon switch to ADXL335 which does not need it’s own library when using with the Arduino Uno.

At the beginning we planned to map the values of the ADXL335 to the lights and so place the ADXL335 on the side doors and every time the doors will move the light will reflect the movement. Soon after we realized that it will be better to use the ADXL335 as a kind of toggle switch, and every time it will sense movement it will switch to another light pattern design.

Now that we had the concept more or less in place, we went on to make the infinity mirror box, and prepare the light strip inside it, originally a long 60 neo pixel strip that we cut to make 14 strips of 4 neo pixel on each, then we soldered the strips to wires and wrapped it around a frame .

Here is the process of making the box:

We cut foam board to make the support for the mirrors

IMG_3822

 

 

 

 

 

 

and added the light strips to check out what it looks like. We decided to place them on an angle to create this chevron of lights

IMG_3823

IMG_3828

 

 

 

 

 

 

 

 

We checked what it looked like while holding the side mirrors to finalize the placement of the lights

IMG_3825IMG_3831

 

 

 

 

 

 

 

 

Then we started to solder all the lights to wires, to create the pattern

IMG_3833IMG_3852IMG_3849 (1)
IMG_3845


IMG_3837

When check for continuity and plugged it in the Arduino and made sure all the lights worked

IMG_3855 photo 2 (1)

Then we made another box to fit it all in

IMG_3861

Then we fit the top mirror to create the infinity effect and played with the plexiglass to see what happens

After finishing assembling the structure we went back to the code.

This is the result:

P1950005

P1950015

P1950012

P1950010

 

 

 

 

 

 

Eventually the neo pixel react whenever there is a change in the accelerometer

This is the code:

#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

const int PIXEL_PIN = 2; // Digital IO pin connected to the NeoPixels.
const int PIXEL_COUNT = 56;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
int count = 0;
int ledPattern = 0;
float prevSensorValue = 0;

int accX = 0;
int accX_StartValue;
boolean isRunning = false;
boolean change = false;

const int x1 = A5;
// for the second acc // const int x2 = A4;

void setup()
{
Serial.begin(9600);

strip.begin();
strip.show(); // Initialize all pixels to ‘off’
pinMode(PIXEL_PIN, OUTPUT);

//Calibrate
calibrateAcc();
}

void loop()
{
if (!isRunning) {
// print the sensor values:
for (int i = 0; i <= 50; i++) {
accX = accX + analogRead(x1);
}
accX = accX / 50;
}

Serial.print(“Before: “);
Serial.println(accX – accX_StartValue);
checkSensor();
// randomColor();
delay(100);

}
void checkSensor() {
if ( abs(accX) – abs(accX_StartValue) >= 12 && isRunning == false) {
isRunning = true;
Serial.println(“Light-up”);
Serial.println(accX – accX_StartValue);
accX = 0;

int rColor = random(0, 255);
int gColor = random(0, 255);
int bColor = random(0, 255);

switch (count) {
case 0:
colorWipe(strip.Color(rColor, gColor, bColor), 50); // random color
reset();
break;
case 1:
colorWave(300);
reset();
break;
case 2:
randomColor(); // random colors
reset();
break;
case 3:
colorPulse(200);
reset();
break;
case 4:
colorPulse1(400);
reset();
break;

default:
colorWipe(strip.Color(255, 255, 255), 50); // white
reset();
break;
}
delay(30);
}
}

///////////////////////////////// NEOPIXEL /////////////////////////////////

void colorWipe(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
// creating all pixel random whipe
void randomColor() {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, random(0, 255), random(0, 255), random(0, 255));
strip.show();
delay(1);
}
}

void colorPulse(int wait) {
for (int t = 0; t < wait; t++) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
int r = abs(sin(t * 0.02)) * 255;
int g = abs(sin(t * 0.02)) * 255;
int b = abs(sin(t * 0.02)) * 255;
if (i % 2) {
strip.setPixelColor(i, strip.Color(r, 0, b / 2));
} else {
strip.setPixelColor(i, strip.Color(255 – r, 0, 255 / 2 – b / 2));
}
}
strip.show();
delay(1);
}
}

void colorPulse1(int wait) {
for (int t = 0; t < wait; t++) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
int r = abs(sin(t * 0.01)) * random(0, 255);
int g = abs(sin(t * 0.01)) * random(0, 255);
int b = abs(sin(t * 0.01)) * random(0, 255);
if (i % 2) {
strip.setPixelColor(i, strip.Color(0, g, b / 2));
} else {
strip.setPixelColor(i, strip.Color(0, 255 – g, 255 / 2 – b / 2));
}
}
strip.show();
delay(1);
}
}

void colorWave(int wait) {
for (int t = 0; t < wait; t++) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
int r = abs(sin((t + i) * 0.05)) * 255;
int g = abs(sin((t + i) * 0.05)) * 255;
int b = abs(sin((t + i) * 0.05)) * 255;
strip.setPixelColor(i, strip.Color(random(20, 100), g / 2, b));
}
strip.show();
delay(1);
}
}

void reset() {
delay(300);
calibrateAcc();
isRunning = false;

// for (uint16_t i = 0; i < strip.numPixels(); i++) {
// strip.setPixelColor(i, strip.Color(0, 0, 0));
// }
// strip.show();

count = random(0,5);
}

//void theaterChase(uint32_t c, uint8_t wait) {
// for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
// for (int q = 0; q < 3; q++) {
// for (int i = 0; i < strip.numPixels(); i = i + 3) {
// strip.setPixelColor(i + q, c); //turn every third pixel on
// }
// strip.show();
//
// delay(wait);
//
// for (int i = 0; i < strip.numPixels(); i = i + 3) {
// strip.setPixelColor(i + q, 0); //turn every third pixel off
// }
// }
// }
//}

uint32_t Wheel(byte WheelPos) {
WheelPos = 255 – WheelPos;
if (WheelPos < 85) {
return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
}

///////////////////////////////// CALIBRATE /////////////////////////////////
void calibrateAcc() {

for (int i = 0; i <= 50; i++) {
accX = accX + analogRead(x1);
}
accX = accX / 50;
accX_StartValue = accX;

Serial.println(“Done!”);
Serial.println(accX_StartValue);

}
/////////////////////////////////////////////////////////////////////////////

In the next version, we will use potentiometers as the hinges to map the analog values to the neo pixel colors. Also we want to add sound to the visuals and recreate the mirror in a full body size, and also add more neo pixels and develop the patterns further.