Skip to content

Experience 1

submerged in a river

graph



look1

  • fitted knit dress w felt details

Designed to hug the body, with no armholes to evoke the underwater isolating sensation. The dress pattern is simplified and zero-waste, reusing fabric cuts to create ornaments for the garment and accessories. With felted details, to represent river moss, adding texture and depth.

  • 3D-printed wearable sculpture

For sound ouptut circuit management, speaker and electronics housing, and a representation of the spikes piercing the skin from the cold river water, described by the participant.

  • striped bio-plastic scarf

With a holographic finish on one side to mimic the shine of water. Also exploring traditional textile prints on bio-materials.

  • crystallization

Crystallization process is still to be explored, either through the felted details on the dress or a faux sleeve extending from the dress pockets, symbolizing the crystal-clear water and spikes.

skecthes


dress w felt details

This dress is designed to ensure that the stretchy knit fabric hugs the body closely while maintaining flexibility for movement and comfort. It draws inspiration from 1920s dropped-waist dresses with a modern interpretation.

The dress is adorned with needle-felted abstract flower shapes in shades of green wool, reminiscent of river moss.


For the prototype, I began by draping the fabric on a mannequin to directly develop the foundational ideas for the pattern–no armholes, a draped neckline, two front pockets with darts, a dropped waistline, a short skirt, and a strap for fastening the dress.

prototype1


pattern

After completing the first prototype, I revised the pattern to explore how it could be simplified into a single-piece cutting. This involved merging all the individual pattern pieces and identifying key points for stitching to create a functional, wearable dress while minimizing seams and enhancing efficiency.


dress



NEEDLE FELTING


felt



electronics

  • Initial idea was to incorporate conductivity into the felted details of the dress and add an interior conductive garment. This garment, when rubbed against the felted details, would trigger sounds. It could work through friction, act like a type of Velcro material, or even respond to pressure or stretch.

  • Given the timelines and the scope of work I want to achieve with this look, I decided to focus on a more streamlined approach. The idea is to use a conductive rubber cord stretch sensor, placed along the shoulder line at the back of the dress or in between the elbows. This sensor would be activated when the wearer moves, stretching the cord and triggering sounds.

The sounds will be samples created by the artist unpsii, designed to evoke underwater movement or vocals or noise. For sound output, I plan to use a DFPlayer Mini, a small, low-cost MP3 module with a simplified output directly to a active speaker, JBL go 2.

Additionally, the system will use wireless communication—a sender and receiver setup—between the stretch sensor input and the sound output. This would allow the speaker and receiver circuit to be discreetly hidden within the wearable sculpture and the sender circuit hidden below the dress.


wireless


stretch sensor input


input

Building this Circuit on a Breadboard:

  • Connect one end of the stretch sensor to 3.3V and the other to A0.

  • Attach a 10kΩ pull-down resistor between A0 and GND.


INPUT (SENDER):

#include <esp_now.h>
#include <WiFi.h>

// Define stretch sensor pin
const int stretchSensorPin = A0;  // Change this if needed

// Define the MAC address of the receiver ESP32
uint8_t receiverMAC[] = { 0x64, 0xe8, 0x33, 0x00, 0x90, 0x1c };  // Replace with actual MAC

// Structure to send stretch level
typedef struct struct_message {
int stretchLevel;  // 1 = low stretch, 2 = medium, 3 = high stretch
} struct_message;

// Create struct instance
struct_message myData;

esp_now_peer_info_t peerInfo;

// Callback to check if data was sent successfully
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("Send Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
}

void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);  // Set ESP32 as Wi-Fi station

// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW initialization failed!");
return;
}

// Register send callback
esp_now_register_send_cb(OnDataSent);

// Add receiver as a peer
memcpy(peerInfo.peer_addr, receiverMAC, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;

if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
}

void loop() {
int stretchValue = analogRead(stretchSensorPin);  // Read sensor value

// Map stretch value to 3 levels (adjust thresholds based on testing)
if (stretchValue < 1500) {
myData.stretchLevel = 1;  // Low stretch
} else if (stretchValue < 3000) {
myData.stretchLevel = 2;  // Medium stretch
} else {
myData.stretchLevel = 3;  // High stretch
}

Serial.print("Stretch Level: ");
Serial.println(myData.stretchLevel);

// Send data via ESP-NOW
esp_err_t result = esp_now_send(receiverMAC, (uint8_t *)&myData, sizeof(myData));

if (result == ESP_OK) {
Serial.println("Data sent successfully");
} else {
Serial.println("Error sending data");
}

delay(100);  // Short delay before next reading
}


wireless communication - sender

Step Code Purpose
Enable Wireless Communication WiFi.mode(WIFI_STA); Sets ESP32 to Wi-Fi Station mode (required for ESP-NOW).
Initialize ESP-NOW esp_now_init(); Starts the ESP-NOW protocol.
Add a Receiver (Peer Device) esp_now_add_peer(); Registers the receiver ESP32’s MAC address.
Send Data Wirelessly esp_now_send(); Sends data from the sender ESP32 to the receiver ESP32.
Confirm Successful Transmission OnDataSent(); Checks if the data was successfully sent.



STRETCH SENSOR TEST w LED



CODE:

#define STRETCH_SENSOR_PIN A0  // Use GPIO1 (A0)
#define LED_PIN 5  // Change this to any PWM-capable GPIO pin

void setup() {
Serial.begin(115200);  // Start serial monitor
pinMode(LED_PIN, OUTPUT);  // Set LED pin as output
analogWrite(LED_PIN, 0);  // Ensure LED starts off
}

void loop() {
int sensorValue = analogRead(STRETCH_SENSOR_PIN);  // Read stretch sensor value

// Map the sensor value from 2600-3400 to 0-100 range
int mappedValue = map(sensorValue, 2600, 3400, 0, 100);

// Map the same value to LED brightness (0-255 for PWM control)
int ledBrightness = map(mappedValue, 0, 100, 0, 255);

// Print the mapped value
Serial.print("Mapped Value: ");
Serial.println(mappedValue);

// Print the LED brightness range
Serial.print("LED Brightness: ");
Serial.println(ledBrightness);

// Determine stretch levels and LED brightness
if (mappedValue < 25) {  
Serial.println("Stretch Level 1: High Stretch - LED Max Brightness");  
ledBrightness = 255;  // Max brightness
} 
else if (mappedValue >= 25 && mappedValue < 45) {  
Serial.println("Stretch Level 2: Medium Stretch - LED Medium Brightness");  
ledBrightness = 128;  // Medium brightness
} 
else if (mappedValue >= 45 && mappedValue < 80) {  
Serial.println("Stretch Level 3: Light Stretch - LED Low Brightness");  
ledBrightness = 50;  // Low brightness
} 
else {  
Serial.println("No Stretch - LED Off");  
ledBrightness = 0;  // Turn off LED when no stretch is detected
}

// Apply brightness to LED using PWM
analogWrite(LED_PIN, ledBrightness);

delay(500);  // Wait before next reading
}


sound output


output

Building this Circuit on a Breadboard:

  • Connect ESP32's TX to DFPlayer Mini's RX through a 1kΩ resistor.

  • Connect ESP32's RX directly to DFPlayer Mini's TX.

  • Connect DFPlayer Mini’s VCC to 5V and GND to GND.

  • Insert a microSD card with the sound files into the DFPlayer Mini.

  • Connect a passive speaker to the DFPlayer Mini’s SPK1 and SPK2 pins (); active speaker to DAC_R or DAC_I and GND.


OUTPUT (RECEIVER) CODE:

#include <esp_now.h>
#include <WiFi.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

// Define DFPlayer Mini RX/TX pins (change if needed)
SoftwareSerial mySoftwareSerial(16, 17);  // RX, TX
DFRobotDFPlayerMini myDFPlayer;

// Structure to receive stretch level
typedef struct struct_message {
int stretchLevel;  // 1, 2, or 3
} struct_message;

// Create struct instance
struct_message myData;

// Callback function to receive ESP-NOW data
void OnDataRecv(const esp_now_recv_info_t *recvInfo, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));

Serial.print("Received Stretch Level: ");
Serial.println(myData.stretchLevel);

// Play corresponding sound file
if (myData.stretchLevel == 1) {
Serial.println("Playing sound_1.mp3");
myDFPlayer.play(1);  // Play file "0001.mp3"
} else if (myData.stretchLevel == 2) {
Serial.println("Playing sound_2.mp3");
myDFPlayer.play(2);  // Play file "0002.mp3"
} else if (myData.stretchLevel == 3) {
Serial.println("Playing sound_3.mp3");
myDFPlayer.play(3);  // Play file "0003.mp3"
}
}

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

// Set ESP32 as Wi-Fi station
WiFi.mode(WIFI_STA);

// Initialize ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOW initialization failed!");
return;
}

// Register the receive callback
esp_now_register_recv_cb(OnDataRecv);

// Initialize DFPlayer Mini
mySoftwareSerial.begin(9600);
if (!myDFPlayer.begin(mySoftwareSerial)) {
Serial.println("DFPlayer Mini not detected!");
return;
}
Serial.println("DFPlayer Mini ready.");

myDFPlayer.volume(20);  // Set volume (0 to 30)
}

void loop() {
// Nothing to do here, everything happens in OnDataRecv()
}


wireless communication - receiver

Step Code Purpose
Enable Wireless Communication WiFi.mode(WIFI_STA); Sets ESP32 to Wi-Fi Station mode (required for ESP-NOW).
Initialize ESP-NOW esp_now_init(); Starts the ESP-NOW protocol.
Register Callback for Receiving Data esp_now_register_recv_cb(OnDataRecv) Registers the callback function to process incoming data.
Process Incoming Data OnDataRecv(); Receives and processes the incoming data, triggering actions.
Play Sound Based on Received Data myDFPlayer.play(); Plays a corresponding sound file based on the received stretchLevel.


VOLUME CONTROL

int volume = 20;  // Default volume

if (myData.stretchLevel == 1) {
Serial.println("Light Stretch - Low Volume");
volume = 5;  // Low volume
} else if (myData.stretchLevel == 2) {
Serial.println("Medium Stretch - Medium Volume");
volume = 15;  // Medium volume
} else if (myData.stretchLevel == 3) {
Serial.println("High Stretch - High Volume");
volume = 25;  // High volume
}

myDFPlayer.volume(volume);  // Apply volume level


PITCH CONTROL

To achieve pitch control, I will need an external audio processor or use pre-recorded audio files at different pitches, because the function playBackSpeed(speed) does not exist in the DFPlayer Mini library.

int speed = 150;  // Default speed (medium pitch)

if (myData.stretchLevel == 1) {
Serial.println("Light Stretch - Low Pitch");
speed = 100;  // Slow speed (lower pitch)
} else if (myData.stretchLevel == 2) {
Serial.println("Medium Stretch - Medium Pitch");
speed = 150;  // Default medium speed (medium pitch)
} else if (myData.stretchLevel == 3) {
Serial.println("High Stretch - High Pitch");
speed = 200;  // Fast speed (higher pitch)
}

myDFPlayer.playBackSpeed(speed);  // Apply speed to change pitch


wearable sculpture

The wearable sculpture is designed for two distinct purposes:

  • It embodies a key aspect of the sensory experience described in the graph and questionnaire. The participant noted: “The moment you enter the water, you feel the sharpness of crystal spikes piercing your skin. It hurts, but it also makes you feel alive.” The accessory captures this sensation, symbolizing the icy spikes felt when submerged in cold water.

  • It also serves a functional purpose. It is engineered to manage the receiver circuit and host the speaker, which will communicate wirelessly with the sender circuit.


I started by creating the 3D model shape for the wearable sculpture using Nomad Sculpt. This initial prototype was intended to help me understand several aspects:

  • The scale of both the ergonomic handle and the overall size of the piece.
  • The final aesthetic.
  • How to implement a system with an opening in the back that would be versatile, manageable, and spacious. This opening would also need integrated holes to allow sound from the speaker inside the bag to project outward.
  • Additionally, I needed a way to design the bag in separate parts to join later, since our lab's 3D printers cannot operate overnight. Because the bag would take more than two days to print, I planned to divide the final design into smaller sections that could be connected later.


prusa

printtest1

For my first print test, I used a white PLA filament and cut the design to print only the handle. This allowed me to evaluate whether the handle needed resizing or further ergonomic adjustments. You can find the 3D model for my first print test here1 and the Prusa Slicer file here2!

However, I applied too much support using the Prusa Slicer software, which made removing the supports after printing very time-consuming. Despite this, the handle turned out fine overall. Here are some alterations I need to make:

  • Consider adjusting the pinky finger hole to make it smaller, as it currently feels a bit uncomfortable.

  • Adjust the overall width of the sculpture to provide more space for the speaker.


sketch


striped bio-plastic scarf

The striped bio-plastic scarf is designed to resemble the texture and appearance of water, by casting it on a holographic sheet.

The scarf is intended to be biodegradable, reflecting the transient nature of water—it comes and goes. This accessory serves as an experiment, aiming to introduce basic patterns, like stripes, into a bio-material. By hand-crafting it, I aim to explore its durability and potential applications.


For the first sample, I used tape to create walls on the mini tray I was using to cast the bio-plastic. I prepared gelatine bio-plastic. I created two different batches, adding green food coloring to one of them.

I began by pouring the uncolored bio-plastic into the side stripes, leaving the middle stripe empty. I let it dry for 15–20 minutes, and once it had partially hardened, I removed the tape walls and poured the green bio-plastic into the middle stripe. The green bio-plastic blended seamlessly with the other two, resulting in a striped sample.

striped


half-fabrication files