Metropollutan

Metropollutan

Metropollutan is a wordplay on two words “Metropolitan” and “pollutant”, signifying the idea of a citizen in a city surrounded by pollution.

In the distant future, global warming have desertified Earth. Temperatures are always high and dust storms frequently hit urban cities, forcing its population to adapt. The garment is an imaginative reflection of the clothings that people in this dystopian future wear, referencing elements from desert wear and the clothings from Cyberpunk genre in Science Fiction.

The jumpsuit is the innermost layer of the garment, and is made of a comfortable and breathable fabric which helps the wearer feel cool. The sleeves are made broader to make it more cooling, which can also be buttoned off when a dust storm hits.

The poncho is the next layer, covering half the wearer’s body. This is inspired by the garments worn by desert dwellers. The poncho can be further extended to cover the wearer more if needed.

The outermost layer is the armour, which is used to protect the wearer and to perform functions such as detecting environmental changes, and responding using lights and motion. The armour pieces are also inspired by beetles in the way they are designed and the way they are segmented. For example, the arm pieces look like beetle legs while the shoulder pieces look like antennas. The armour also has an iridescent shine like beetles, which also coincides with cyberpunk aesthetics.

The garment is thus able to allow wearers, the Metropollutans, to adapt to the dusty yet urban environment.

The different parts and their functions:

The hood and the mask helps the wearer to protect their face against dust. When high pollution is detected, the motor moves and the mask comes up to cover the face.

The shoulder pieces are called the “Illumunators” which lights up into bright green light when there is high pollution so as to increase visibility.

The chest and neck piece houses the electronics and helps keep every other armour piece together.

The arm pieces help the wearer to visualise the environmental information in the form of light. The left arm piece responds to pollution changes, where in low pollution, it glows in blue and green, while in high pollution, it glows in pink and purple. The right arm piece responds to temperature changes, where in average temperature, it glows in blue and green, while in higher temperature, it glows in orange and red. These changes notify the wearer of the changes in environment, while also preparing them for the change in the garment pieces’ movements.

Finally, the belt allows the wearer to hold more things as it acts like a utility belt.

How it works

The garment uses Internet of Things (IoT) services to collect, send, and receive data to alter the state of the garment. Data is collected from Air Visuals, a weather data API. The data is sent to Adafruit.io, which stores all the data. The stored data is then sent to microcontrollers, NodeMCU Amica, inside different parts of the garment, controlling different LED strips and servo motors.

As IoT data do not reflect the imagined world’s environment very well, the garment is also controlled by a switch on Adafruit.io which changes the state of the garment. There are two states that works on my garment currently: high pollution and low pollution. On high pollution, the mask will move up to cover the wearer’s mouth, the Illuminator will switch on, and the arm piece colour will turn from blue/green to red/orange; vice versa for low pollution.

Photos of final state:

As I didn’t have the tools (and drive 🙁 ) to continue working on the garment, this is the final state of my work.

Current state: With a piece of armour

Additionally, I’ve worked on the mask and the electronics at home.

Mockups, Sketches:

To make up for the lack of finalised project, I used sketching and mockups to imagine the way the armour pieces look.

Video of Electronics / Interaction:

 

Role and Future Aspiration in Fashion Show

I would remain in the role I was assigned, doing the stage. I wish to do projection for the show, and had discussed with Shah before about it and we think it’s a good idea. I think we can project the quirks of the different garments, like for example, mine could be a desert world, while Fizah’s can be snakes.

The stage design will also include logistics like smoke machine placement, decorations, etc. This should tie in with the theme, but that’s undecided yet.

Programming Final – Strang

Our Research:

So we wanted to work on something like a clock. After Yue Ling and I looking at some online examples and ideas, we decided to settle on an infinity mirror with LED lights that changes as the user interacts with the clock.

As clock measures time, we wanted to play with the idea of a clock not measuring what it’s supposed to measure. So by changing the speed and colour of the clock through interaction, it will create an inaccurate idea of time, and as such, becomes an interesting observation of our relationship with interaction and time.

Our Proposal:

Our Project

Yue Ling and I went to Sim Lim and Art Friend to purchase the items, and after getting some help from Charissa, Jia Yi, Nok Wan, Mark, and Vienna, we managed to get the items we need!

Assembly

Fixing up the main structure of the clock

Applying of black one-way mirror film

After assembly, we put in the LED

The Prototype Code:

Yue Ling found an example online:

Guide for WS2812B Addressable RGB LED Strip with Arduino

With this example, we were able to use a timer to change the LED states, and as we are unable to find an elegant way of coding the colours to change smoothly, we have to create different set of colours and code different timings to different set of colours:

#include <FastLED.h>

#define LED_PIN 13
#define NUM_LEDS 51
#define BRIGHTNESS 200
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100

CRGBPalette16 currentPalette;
TBlendType currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedW4hiteBluePalette_p PROGMEM;

int x = 1000;
int xspeed = 100;
int p1, p2, p3;
int o1, o2, o3;

void setup() {
delay( 3000 ); // power-up safety delay
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );

// currentPalette = RainbowColors_p;
currentBlending = LINEARBLEND;
}

void loop()
{

ChangePalettePeriodically();

static uint8_t startIndex = 0;
startIndex = startIndex + 1;

FillLEDsFromPaletteColors( startIndex);

FastLED.show();
FastLED.delay(x / UPDATES_PER_SECOND);
}

void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
uint8_t brightness = 255;

for ( int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 3;
}
}

void ChangePalettePeriodically()
{
uint8_t secondHand = (millis() / 1000) % 21;
static uint8_t lastSecond = 99;

if ( lastSecond != secondHand) {
lastSecond = secondHand;
if ( secondHand == 0) {
SetupPurpleAndGreenPalette();
currentBlending = LINEARBLEND;
}
if ( secondHand == 1) {
SetupPurpleAndGreenPalette();
currentBlending = LINEARBLEND;
}
if ( secondHand == 2) {
SetupPurpleAndGreenPalette2();
currentBlending = LINEARBLEND;
}
if ( secondHand == 3) {
SetupPurpleAndGreenPalette3();
currentBlending = LINEARBLEND;
}
if ( secondHand == 4) {
SetupPurpleAndGreenPalette4();
currentBlending = LINEARBLEND;
}
if ( secondHand == 5) {
SetupPurpleAndGreenPalette5();
currentBlending = LINEARBLEND;
}
if ( secondHand == 6) {
SetupPurpleAndGreenPalette6();
currentBlending = LINEARBLEND;
}
if ( secondHand == 7) {
SetupPurpleAndGreenPalette7();
currentBlending = LINEARBLEND;
}
if ( secondHand == 8) {
SetupPurpleAndGreenPalette8();
currentBlending = LINEARBLEND;
}
if ( secondHand == 9) {
SetupPurpleAndGreenPalette9();
currentBlending = LINEARBLEND;
}
if ( secondHand == 10) {
SetupPurpleAndGreenPalette10();
currentBlending = LINEARBLEND;
}
if ( secondHand == 11) {
SetupPurpleAndGreenPalette11();
currentBlending = LINEARBLEND;
}
if ( secondHand == 12) {
SetupPurpleAndGreenPalette10();
currentBlending = LINEARBLEND;
}
if ( secondHand == 13) {
SetupPurpleAndGreenPalette9();
currentBlending = LINEARBLEND;
}
if ( secondHand == 14) {
SetupPurpleAndGreenPalette8();
currentBlending = LINEARBLEND;
}
if ( secondHand == 15) {
SetupPurpleAndGreenPalette7();
currentBlending = LINEARBLEND;
}
if ( secondHand == 16) {
SetupPurpleAndGreenPalette6();
currentBlending = LINEARBLEND;
}
if ( secondHand == 17) {
SetupPurpleAndGreenPalette5();
currentBlending = LINEARBLEND;
}
if ( secondHand == 18) {
SetupPurpleAndGreenPalette4();
currentBlending = LINEARBLEND;
}
if ( secondHand == 19) {
SetupPurpleAndGreenPalette3();
currentBlending = LINEARBLEND;
}
if ( secondHand == 20) {
SetupPurpleAndGreenPalette2();
currentBlending = LINEARBLEND;
}
if ( secondHand == 21) {
SetupPurpleAndGreenPalette();
currentBlending = LINEARBLEND;
}
}
}

void SetupPurpleAndGreenPalette()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
pink, pink, orange, orange,
orange, orange, pink, pink,
pink, pink, orange, orange,
orange, orange, pink, pink );
}

void SetupPurpleAndGreenPalette2()
{

CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
pink2, pink2, orange2, orange2,
orange2, orange2, pink2, pink2,
pink2, pink2, orange2, orange2,
orange2, orange2, pink2, pink2 );
}

void SetupPurpleAndGreenPalette3()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
pink3, pink3, orange3, orange3,
orange3, orange3, pink3, pink3,
pink3, pink3, orange3, orange3,
orange3, orange3, pink3, pink3 );
}
void SetupPurpleAndGreenPalette4()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
pink4, pink4, orange4, orange4,
orange4, orange4, pink4, pink4,
pink4, pink4, orange4, orange4,
orange4, orange4, pink4, pink4 );
}

void SetupPurpleAndGreenPalette5()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
purple1, purple1, orange5, orange5,
orange5, orange5, purple1, purple1,
purple1, purple1, orange5, orange5,
orange5, orange5, purple1, purple1 );

}

void SetupPurpleAndGreenPalette6()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
purple2, purple2, orange6, orange6,
orange6, orange6, purple2, purple2,
purple2, purple2, orange6, orange6,
orange6, orange6, purple2, purple2 );

}

void SetupPurpleAndGreenPalette7()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
purple3, purple3, orange7, orange7,
orange7, orange7, purple3, purple3,
purple3, purple3, orange7, orange7,
orange7, orange7, purple3, purple3 );

}

void SetupPurpleAndGreenPalette8()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
purple4, purple4, orange8, orange8,
orange8, orange8, purple4, purple4,
purple4, purple4, orange8, orange8,
orange8, orange8, purple4, purple4 );

}

void SetupPurpleAndGreenPalette9()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
purple5, purple5, orange9, orange9,
orange9, orange9, purple5, purple5,
purple5, purple5, orange9, orange9,
orange9, orange9, purple5, purple5);
}

void SetupPurpleAndGreenPalette10()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
purple6, purple6, orange10, orange10,
orange10, orange10, purple6, purple6,
purple6, purple6, orange10, orange10,
orange10, orange10, purple6, purple6);
}

void SetupPurpleAndGreenPalette11()
{
CRGB pink = CRGB( 250, 0, 100);
CRGB pink2 = CRGB( 225, 0, 100);
CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
purple7, purple7, orange11, orange11,
orange11, orange11, purple7, purple7,
purple7, purple7, orange11, orange11,
orange11, orange11, purple7, purple7);
}

As you can see, we created combinations of different colours manually, which is not practical. We hope to improve on this.

Prototype outcome:

So I tried to fix everything up and here is the result:

Ultrasound

So Brendan worked on the ultrasonic sensors after looking through some codes online:

https://create.arduino.cc/projecthub/unexpectedmaker/ultrasoniceyes-b9fd38?ref=tag&ref_id=ultrasonic&offset=2

https://www.hackster.io/gowrisomanath/the-positronic-brain-my-techno-heart-9084be

He made a code that detects distance based on how far an object is in CM

const int trigPin = 9;
const int echoPin = 10;
const int ledPin = 13;

// defines variables
long duration;//travel time
int distance;//travel distance
int safetyDistance;

void setup() {
pinMode(trigPin, OUTPUT); // sets the trigPin as an Output
pinMode(echoPin, INPUT); // sets the echoPin as an Input
pinMode(ledPin, OUTPUT);
Serial.begin(9600); // Starts the serial communication for serial monitor
}
void loop() {
// Check trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
//generate ltrasound wave at high state
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// reads the echoPin, read the sound wave travel time
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
//blinker
safetyDistance = distance;
if (safetyDistance <= 20) {
digitalWrite(ledPin, HIGH);
}
else{
digitalWrite(ledPin, LOW);
}
Serial.print("Distance: ");
Serial.println(distance);

}

With this code, we merged the lights code with the ultrasonic sensor code and simplified it to be slightly more elegant:

const int trigPin = 9;
const int echoPin = 10;
const int ledPin = 13;
const int flexPin = A0; //pin A0 to read analog input

// defines variables
long duration;//travel time
int distance;//travel distance
int safetyDistance;
int value; //save analog value

#include <FastLED.h>

#define LED_PIN 13
#define NUM_LEDS 51
#define BRIGHTNESS 200
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100

CRGBPalette16 currentPalette;
TBlendType currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

int x;
int a, b, c;
int d, e, f;
int col1, col2;

void setup() {
pinMode(trigPin, OUTPUT); // sets the trigPin as an Output
pinMode(echoPin, INPUT); // sets the echoPin as an Input
pinMode(ledPin, OUTPUT);
Serial.begin(9600); // Starts the serial communication for serial monitor

FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );

// currentPalette = RainbowColors_p;
currentBlending = LINEARBLEND;

}

void loop() {

value = analogRead(flexPin); //Read and save analog value from potentiometer
Serial.println(value); //Print value
value = map(value, 700, 900, 0, 255);//Map value 0-1023 to 0-255 (PWM)

// Check trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
//generate ltrasound wave at high state
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// reads the echoPin, read the sound wave travel time
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
//blinker
safetyDistance = distance;

Serial.print("Distance: ");
Serial.println(distance);

ChangePalettePeriodically();
static uint8_t startIndex = 0;
startIndex = startIndex + 1;

FillLEDsFromPaletteColors( startIndex);

FastLED.show();
FastLED.delay(x / UPDATES_PER_SECOND);
}

void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
uint8_t brightness = 255;

for ( int i = 0; i < NUM_LEDS; i++) {
leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 3;
}
}

void ChangePalettePeriodically()
{
// uint8_t secondHand = (millis() / 1000) % 21;
// static uint8_t lastSecond = 99;

// if ( lastSecond != secondHand) {
// lastSecond = secondHand;
SetupPurpleAndGreenPalette();
currentBlending = LINEARBLEND;
if (safetyDistance >= 30) {
x=500;
a = 250;
b = 0;
c = 100;
d = 250;
e = 100;
f = 50;
}
if (safetyDistance <=29) {
x=800;
a = 225;
b = 0;
c = 100;
d = 200;
e = 100;
f = 50;
}
if (safetyDistance <=26) {
x=1200;
a = 200;
b = 0;
c = 100;
d = 150;
e = 100;
f = 50;
}
if (safetyDistance <=23) {
x=1500;
a = 175;
b = 0;
c = 100;
d = 100;
e = 100;
f = 50;
}
if (safetyDistance <=20) {
x=1800;
a = 150;
b = 0;
c = 100;
d = 50;
e = 100;
f = 50;
}
if (safetyDistance <=17) {
x=2200;
a = 125;
b = 0;
c = 100;
d = 0;
e = 100;
f = 50;
}
if (safetyDistance <=14) {
x=2500;
a = 75;
b = 0;
c = 100;
d = 0;
e = 100;
f = 50;
}
if (safetyDistance <=11) {
x=2800;
a = 75;
b = 0;
c = 125;
d = 0;
e = 100;
f = 100;
}
if (safetyDistance <=8) {
x=3200;
a = 75;
b = 0;
c = 150;
d = 0;
e = 100;
f = 150;
}
if (safetyDistance <=5) {
x=3500;
a = 75;
b = 25;
c = 150;
d = 0;
e = 100;
f = 200;
}
if (safetyDistance <=2) {
x=3800;
a = 75;
b = 50;
c = 150;
d = 0;
e = 100;
f = 250;
}
}

void SetupPurpleAndGreenPalette()
{
CRGB col1 = CRGB( a, b, c);
CRGB col2 = CRGB( d, e, f);

CRGB pink3 = CRGB( 200, 0, 100);
CRGB pink4 = CRGB( 175, 0, 100);
CRGB purple1 = CRGB( 150, 0, 100);
CRGB purple2 = CRGB( 125, 0, 100);
CRGB purple3 = CRGB( 75, 0, 100);
CRGB purple4 = CRGB( 75, 0, 125);
CRGB purple5 = CRGB( 75, 0, 150);
CRGB purple6 = CRGB( 75, 25, 150);
CRGB purple7 = CRGB( 75, 50, 150);
CRGB orange = CRGB( 250, 100, 50);
CRGB orange2 = CRGB(200, 100, 50);
CRGB orange3 = CRGB(150, 100, 50);
CRGB orange4 = CRGB(100, 100, 50);
CRGB orange5 = CRGB(50, 100, 50);
CRGB orange6 = CRGB(0, 100, 50);
CRGB orange7 = CRGB(0, 100, 100);
CRGB orange8 = CRGB(0, 100, 150);
CRGB orange9 = CRGB(0, 100, 175);
CRGB orange10 = CRGB(0, 100, 200);
CRGB orange11 = CRGB(0, 100, 250);
CRGB yellow = CRGB(255, 255, 0);
CRGB green = CRGB(100, 255, 0);
CRGB turquoise = CRGB(0, 255, 100);
CRGB grue = CRGB( 0, 100, 255);
CRGB purple = CRGB( 255, 100, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
col1, col1, col2, col2,
col2, col2, col1, col1,
col1, col1, col2, col2,
col1, col1, col2, col2);
}

Motors + Flex

Brendan went back to fix the motors up with the second part of our project which is to make the screen move. We also went to the film store to borrow some flex sensors.

It was really difficult to connect everything as we have so many wires that are too loose. Eventually, we managed to put everything up and taped the wires down.

Yue Ling found a code for the motors and we merged it with a flex sensor code such that the motor will move directly proportionate to the flex’s bend.

/* Sweep
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.

modified 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

const int flexPin = A0; //pin A0 to read analog input
int value; //save analog value

Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0; // variable to store the servo position

void setup() {
Serial.begin(9600); //Begin serial communication
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {

value = analogRead(flexPin); //Read and save analog value from potentiometer
Serial.println(value); //Print value
value = map(value, 400, 500, 0, 180);//Map value 0-1023 to 0-255 (PWM)

//if(value < 399){

myservo.write(value);
// pos = 0;
// pos--;
// delay(1);
}

//if(value> 400){bb
// value = map(value, 700, 900, 0, 255);//Map value 0-1023 to 0-255 (PWM)

//pos+=3;
// myservo.write(pos); // tell servo to go to position in variable 'pos'
// delay(1); // waits 15ms for the servo to reach the position
// }
//}

So with both parts complete, we fixed up the box. The wiring was a major headache for us as we do not have the correct kit and enough wires. We managed to fix everything after much troubles. Yue Ling also borrowed female-to-male wires from Vienna which is a great help! Without that, we would not be able to connect our flex sensors and our ultrasonic sensors.

Unfortunately we don’t have an image of our final wirings.

Final Model

Before placing hand inside (lights)
Before placing hand inside (motor)
After placing hand inside (lights)
After placing hand inside (motor)

Video demonstration:

 

Concept is that by putting your hand through the hole, we bend space and time. Bending time is through slowing down of the rotation of the ‘clock’ as well as turning the colours from pink/orange to purple/blue, which began from the idea of ‘blue shifting’ like how light will look like if time slows down.

By pushing the fabric at the end of the installation, the motors move, emulating fingers that seems like as if the user’s hands have traversed through a wormhole into another location.

The overall feeling we aimed to get is the sense of amazement from the shifting in colours and also being able to teleport their hands through space.

Presentation Slides:

https://docs.google.com/presentation/d/1QqwL3OJHkvuKO2NJf1szHjSbgNvObOalTWKNzutuSV4/edit?usp=sharing


Problems Encountered

  1. LED lights code settings could be better, as we don’t know how to make it smoothly transit between colours. We could possibly make the value from the distance detected by the ultrasonic sensors directly control the colour range, but we don’t know how to do that so that can be an area of improvement.
  2. Circuit is a very big mess for us and we don’t have the right kits provided so we have to keep sourcing from our friends. We could have bought a long roll of wire so we can have all the wire we need and not use tiny short wires which breaks the circuit easily.
  3. We bought some wrong items along the way too, like the acrylic piece that is in front of the clock, we accidentally bought a matt acrylic. We had some difficulty finding the correct LED too and it was thanks to Vienna who helped us with where we can get it.
  4. Ultrasonic Sensor is buggy and there is no solution to fixing it. We speculate that it was because of bad wiring that it kept reading weird readings once in a while.
  5. The ‘fingers’ stuck on the motor wasn’t really sticking well and if we had more time, we would have improved it by securing it better.

What I learnt:

I learnt to control the motor using the flex sensor values, as well as how to work around a problem (the LED one) by manually writing individual code for individual colours. I’ve also learnt to use 4 different components and making them work together.

Tasks Deligation

Brendan:

  • Ultrasonic Sensors code + circuit
  • Motors setup
  • Fabric board assembly

Bryan:

  • LED code + circuit
  • motor circuit
  • general assembly and troubleshooting

Yue Ling:

  • Item sourcing
  • LED code + testing
  • Motors code + circuit