The EverWear garment is a digital representation of what future fashion might look like, addressing the fast fashion industry’s environmental impact. Fast fashion contributes significantly to pollution through mass production, textile waste, water contamination from dyes, and high carbon emissions from transportation.
EverWear offers a sustainable alternative by enabling digital customisation, reducing the need for multiple physical garments. The garment’s appearance changes based on user input, minimising waste linked to shifting fashion trends. To ensure inclusivity, I designed it with an oversized, boxy shape suitable for all body types. However, this limited arm movement, so I decide that users had to interact with it using their feet.
During user testing, I initially placed a sensor on the left shoulder, requiring users to cross their arms to tap it, which blocked the projection. Feedback also highlighted issues with mirror and projection alignment. In response, I developed a joystick bracelet for design adjustment and moved the sensor to the left hip, improving usability. However, the hip button’s placement caused users to exit design mode accidentally, as it was too close to the main button.
The production process involved three force sensors connected to Arduino, sending data to Processing. One sensor switched patterns, another animated the clothing, and the third adjusted pattern filters. While testing, I adapted class code to animate the garment but couldn’t resolve an issue requiring continuous pressing for animation playback. I also used a push button to end design mode.
My goal was to create an interactive, customisable garment that promotes sustainability while being engaging and fun. The audience found the project unique and interesting. With more time, I would reposition the touch sensor or use a different type, add more designs, and create a visual tutorial, as audio instructions were hard to hear during the presentation.
import processing.serial.*;
import processing.sound.*;
Serial serialPort;
SoundFile sound;
SoundFile sound1;
import processing.video.*;
Movie myMovie;
int NUM_OF_VALUES_FROM_ARDUINO = 6;
int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
PImage[] patternImages = new PImage[5];
PImage endImage;
int patternItem = -1;
int patternX = 100; // Initial X position
int patternY = 100; // Initial Y position
int moveStep = 10; // Step size for movement
float deadZone = 50;
int state = 1; // Initial state
int threshold2 = 1000; //threshold for the animation sensor
int threshold1 = 200;// threshold for the filter sensor
int currentFilter = -1; // -1 means no filter applied
int previousSensorValue = 0;
void setup() {
fullScreen(P2D);
background(0);
printArray(Serial.list());
serialPort = new Serial(this, "/dev/cu.usbmodem1101", 9600);
for (int i = 0; i < 5; i++) {
patternImages[i] = loadImage("pattern" + (i+1) + ".png"); // File names like "pattern1.png", "pattern2.png"
}
endImage = loadImage("last.png"); //loads image for the end screen
sound1 = new SoundFile(this, "long.aif");
if (patternImages[0] != null) {
patternX = (width - patternImages[0].width) / 2; // Center horizontally
patternY = (height - patternImages[0].height) / 2; // Center vertically
}
}
void draw() {
if (state == 1) {
drawStartScreen(); // beginning screen
} else if (state == 2) {
drawImageScreen(); // design mode
} else if (state == 3) {
drawThankYouScreen(); // end screen
}
getSerialData();
}
void getSerialData() { //reads from arduino
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil(10); // 10 = '\n'
if (in != null) {
print("From Arduino: " + in);
String[] serialInArray = split(trim(in), ",");
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i = 0; i < serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
}
}
}
}
void drawStartScreen() {
background(0);
if (!sound1.isPlaying()) { // Check if the sound is not already playing
sound1.play(); // Start looping the sound
}
if (arduino_values[0] >= 0 && arduino_values[0] < patternImages.length) { // Only transition to state 2 if interaction has happened
state = 2;
}
}
void drawImageScreen() {
background(0);
patternItem = arduino_values[0];
float joystickX = map(arduino_values[4], 0, 1023, -512, 512);
float joystickY = map(arduino_values[5], 0, 1023, -512, 512);
if (patternItem != -1) {
PImage pattern = patternImages[patternItem];
if (abs(joystickX) < deadZone) joystickX = 0; // Code for dead zone handling adapted from [Youtube] - [https://www.youtube.com/watch?v=vo7SbVhW3pE]
]
if (abs(joystickY) < deadZone) joystickY = 0;
// Adjust clothing position based on joystick input
patternX += joystickX / 512 * moveStep;
patternY += joystickY / 512 * moveStep;
// Constrain clothing position to remain within the window
patternX = constrain(patternX, 0, width - pattern.width/2); // Adjust for image width
patternY = constrain(patternY, 0, height - pattern.height/2);
float scaleFactor = min( //external code
(float) width / pattern.width,
(float) height / pattern.height
);
int scaledWidth = int(pattern.width * scaleFactor);
int scaledHeight = int(pattern.height * scaleFactor);
image(pattern, patternX, patternY); //shows the pattern , and its postions based on joystick
if (arduino_values[1] > threshold2) {
for (int i = 0; i < 100; i++) {
int x = int(random(pattern.width));
int y = int(random(pattern.height));
color c = pattern.get(x, y);
int screenX = patternX + int(x * scaleFactor);
int screenY = patternY + int(y * scaleFactor);
fill(c);
float size = random(1, 20);
ellipse(screenX, screenY, size, size);
}
}
if (arduino_values[2] > threshold1 && previousSensorValue <= threshold1) {
currentFilter = (currentFilter + 1) % 4; // Cycle through 4 filters
}
previousSensorValue = arduino_values[2];
if (currentFilter != -1) { // Apply filter only if currentFilter is valid
switch (currentFilter) {
case 0:
noTint();
break;
case 1:
filter(THRESHOLD);
break;
case 2:
filter(BLUR, 6);
noTint();
break;
case 3:
filter(POSTERIZE, 2);
noTint();
break;
case 4:
tint(255, 192, 203, 200);
break;
default:
noTint();
break;
}
}
}
if (arduino_values[3] == 1) { // Assuming button input is in arduino_values[3]
state = 3;
}
}
void drawThankYouScreen() { //shows the end screen,image pops up
float scaledWidth = endImage.width * 0.8;
float scaledHeight = endImage.height * 0.8;
float imageX = (width - scaledWidth) / 2;
float imageY = (height - scaledHeight) / 2 + 20;
image(endImage, width/2, height/1.5, 300, 300);
}
ARDUINO
const int changeClothingPin = A0;
const int sparklesPin = A2;
const int filterPin = A1;
const int threshold = 500; // Threshold to detect pressure
const int buttonPin = 2;
int buttonState = 0;
int clothingItem = -1; // Start with clothing item 1
const int joyStickXPin = A3;
const int joyStickYPin = A5;
int lastButtonState = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup() {
Serial.begin(9600);
pinMode(buttonPin,INPUT);
}
void loop() {
int reading = digitalRead(buttonPin);
if(reading != lastButtonState){
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
buttonState = reading;
}
lastButtonState = reading;
int changeClothingValue = analogRead(changeClothingPin);
int sparkleValue = analogRead(sparklesPin);
int filterValue = analogRead(filterPin);
int joyStickX = analogRead(joyStickXPin);
int joyStickY = analogRead(joyStickYPin);
Serial.print(clothingItem);
Serial.print(",");
Serial.print(sparkleValue);
Serial.print(",");
Serial.print(filterValue);
Serial.print(",");
Serial.print(buttonState);
Serial.print(",");
Serial.print(joyStickX);
Serial.print(",");
Serial.print(joyStickY);
Serial.println(" ");
// Check if the pressure sensor has been pressed
if (changeClothingValue > threshold) {
clothingItem = (clothingItem + 1) % 5; // Loop clothing items (0-6)
while (analogRead(changeClothingPin) > threshold) {
delay(10); // Wait until pressure is released
}
delay(200);
}
}
Cuttle.xyz. (2024). Cuttle: Generate Personalized SVG Cut Files in seconds. [online] Available at: https://cuttle.xyz/dashboard.
Hackster.io (2021). Arduino Thumb Joystick to Processing. [online] Hackster.io. Available at: https://www.hackster.io/MinukaThesathYapa/arduino-thumb-joystick-to-processing-92c182 [Accessed 16 Dec. 2024].
Hicks, J. (2019). Using a Projector in your Photoshoot - Remastered. [online] Jake Hicks Photography. Available at: https://jakehicksphotography.com/latest-techniques/2016/1/9/using-a-projector-in-your-photoshoot-remastered.
Nyu.edu. (2024). Interaction Lab – Interactive Media Arts – NYU Shanghai. [online] Available at: https://wp.nyu.edu/shanghai-ima-interaction-lab/ [Accessed 11 Nov. 2024].
www.youtube.com. (n.d.). How to Use a Joystick with Arduino (Lesson #13). [online] Available at: https://www.youtube.com/watch?v=vo7SbVhW3pE.
I did not disassemble my project because I applied for it to be displayed in the IMA gallery next semester