Skip to content

Making of LÜM

Garment 01 - Vera

  • Vera (The Matulastic)

    /vɛ-rah/
    A calm force of nature.
    Inspired by mutualism, Vera reflects the quiet harmony between fungi and tree roots — where both give, and both grow.
    Earthy veins, soft layers, and glowing connections.


Design Pattern

Parametric Design

Pattern 01



Slicing

Pattern 01

Cura Slicing Settings

Setting Value
Printer Ultimaker S5
Material nGen_FLEX (TPU-like)
Color Transparent Nude
Layer Height 1.0 mm
Wall Line Count 1
Wall Thickness 0.4 mm
Top Layers 2
Bottom Layers 2
Infill Density 0%
Infill Pattern None
Print Speed 20 mm/s
Travel Speed 60 mm/s
Nozzle Temperature 230°C
Build Plate Temp 85°C
Retraction Distance 4.5 mm
Cooling Fan On (60%)
Supports None
Adhesion Type Brim
Pause at Layer Layer 1
Special Effect None (Standard Print Mode)

Cura - Pattren 01 A Cura - Pattren 01 A Cura - Pattren 01 A


Pattern 02

Cura Slicing Settings

Setting Value
Printer Ultimaker S5
Material PLA Filament
Color White
Layer Height 0.15 mm
Wall Line Count 2
Wall Thickness 0.8 mm
Infill Density 20%
Infill Pattern Grid
Print Speed 50 mm/s
Travel Speed 120 mm/s
Nozzle Temperature 200°C
Build Plate Temp 60°C
Retraction Distance 6.5 mm (default Ultimaker)
Cooling Fan On (100%)
Supports None
Adhesion Type Brim
Pause at Layer Layer 4

Cura - Pattren 01 B

Cura - Pattren 01 B

Cura - Pattren 01 B



3D Print

Pattern 01

Swatches

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B


final Swatches

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


  • Dress 01 Pattern 01 - Branches

Pattern 02

3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


  • Dress 01 Pattern 02 - Branches

Pattren Layout

*Layer 01 - Base

This Process was duplilcated on both Dress 01 & Dress 02

01 Design Measurments

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

02 Prototype 3D PRINT - Pattren 01 B

03 Assembly 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


*Layer 02 - 3D Printing on Tull

  • Collect all prints together

3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


Garment 02 - Luma

  • Luma (The Endosymbiosis)

    /loo-mah/
    A light that lives within.
    Inspired by endosymbiosis, Luma channels the curious bond between lichens and trees — two lives intertwined as one.
    Nestled shapes, hidden lights, and a pulse that glows from the inside out


Design Pattern

Parametric Design 01

Pattern 01

Cura - Pattren 01 A Cura - Pattren 01 A Cura - Pattren 01 A Cura - Pattren 01 A

Cura - Pattren 01 A


Pattern 02

Cura - Pattren 01 A Cura - Pattren 01 A



Slicing

Pattern 01

Cura Slicing Settings

Setting Value
Printer Ultimaker S5
Material nGen_FLEX (TPU-like)
Color Transparent Nude
Layer Height 0.3 mm
Wall Line Count 1
Wall Thickness 0.4 mm
Top Layers 0
Bottom Layers 0
Infill Density 0%
Infill Pattern None
Print Speed 25 mm/s
Travel Speed 60 mm/s
Nozzle Temperature 230°C
Build Plate Temp 85°C
Retraction Distance 4.5 mm
Cooling Fan On (60%)
Supports None
Adhesion Type Brim
Pause at Layer Layer 7
Special Effect Spiralize Outer Contour (Vase Mode)

Cura - Pattren 02 A Cura - Pattren 02 A Cura - Pattren 02 A

Cura - Pattren 02 A


Pattern 02

Cura Slicing Settings

Setting Value
Printer Ultimaker S5
Material PLA Filament
Color White
Layer Height 0.15 mm
Wall Line Count 2
Wall Thickness 0.8 mm
Infill Density 20%
Infill Pattern Grid
Print Speed 50 mm/s
Travel Speed 120 mm/s
Nozzle Temperature 200°C
Build Plate Temp 60°C
Retraction Distance 6.5 mm (default Ultimaker)
Cooling Fan On (100%)
Supports None
Adhesion Type Brim
Pause at Layer Layer 4

Cura - Pattren 02 B



3D Print

Pattern 01

Swatches 01

Cura - Pattren 02 B Cura - Pattren 02 B

Cura - Pattren 02 B

Phinal Swatches Cura - Pattren 02 B Cura - Pattren 02 B


  • Dress 02 Pattern 01 - Lichens

Pattern 02

Swatches

Cura - Pattren 02 B Cura - Pattren 02 B Cura - Pattren 02 B Cura - Pattren 02 B


final Swatches

Cura - Pattren 02 B Cura - Pattren 02 B

Cura - Pattren 02 B


  • Dress 02 Pattern 02 - Lichens 02

Pattren Layout

*Layer 01 - Base

same as Layer Base Dress 01


*Layer 02 - 3D Printing on Tull

Cura - Pattren 02 B

Cura - Pattren 02 B

Cura - Pattren 02 B



3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


Electronics

What if garments could communicate? What if they could move beyond aesthetics and become an interactive language? This question is what led me to develop a garment that reacts to human connection—lighting up in response to movement and distance, creating a visual dialogue between the wearer and their surroundings.

I started by exploring electronic textiles and microcontrollers, testing how sensors and LEDs could respond dynamically. Through a series of experiments with XIAO ESP32 boards, I created a system where two garments communicate through proximity-based lighting—turning an outfit into an interactive performance. The journey involved material exploration, coding, and refining how light and movement could merge seamlessly into fabric.


🔌 First Spark

I dipped my toes into electronics with the good old breadboard—just me, some wires, and a sprinkle of chaos.


  • 💡 LED, Meet Xiao
    I started by hooking up an LED strip to the Seeed Studio XIAO ESP32C3. With the classic Blink code from Arduino, I got those lights to flash like a tiny rave. Success!

3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


  • 🔊 Then Came the Vibes
    Next, I swapped the LEDs for a vibration motor. Using the same Blink logic, I made it buzz to life. Instant feedback—literally.

3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B


// Define the pin where your LED or vibration motor is connected
int pin = 2; // D2 on Xiao ESP32C3

void setup() {
  pinMode(pin, OUTPUT); // Set the pin as output
}

void loop() {
  digitalWrite(pin, HIGH); // Turn on
  delay(500);              // Wait 0.5 second
  digitalWrite(pin, LOW);  // Turn off
  delay(500);              // Wait 0.5 second
}

  • 📶 Going Wireless
    The final challenge? Bluetooth. I connected everything wirelessly through the Xiao ESP32 and watched it all come together—vibes and lights responding without a single cable in sight. Felt like magic. 🔮

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLEService.h>
#include <BLECharacteristic.h>

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;

#define SERVICE_UUID        "12345678-1234-5678-1234-56789abcdef0"
#define CHARACTERISTIC_UUID "12345678-1234-5678-1234-56789abcdef1"

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

  BLEDevice::init("XIAO_BLE_Server"); // Name of the BLE device

  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);

  pCharacteristic = pService->createCharacteristic(
    CHARACTERISTIC_UUID,
    BLECharacteristic::PROPERTY_READ |
    BLECharacteristic::PROPERTY_WRITE
  );

  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();

  Serial.println("Waiting for a client to connect...");
}

void loop() {
  // Server does nothing in the loop, just waits for connections
  delay(1000);
}

class MyServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer *pServer) {
    deviceConnected = true;
    Serial.println("Device connected!");
  }

  void onDisconnect(BLEServer *pServer) {
    deviceConnected = false;
    Serial.println("Device disconnected!");
  }
}

E-Textile Circuit Layer

This layer is the functional tech core behind both interactive dresses. It holds all electronics: XIAO ESP32 board, RGB LEDs, vibrating motors, and their connections. It’s modular, washable, and connected to gloves via plug connectors. Two similar versions exist for Dress 1 (White) and Dress 2 (Pink).


🧰 Tools & Materials Used

Tool/Material Purpose
XIAO ESP32 board Microcontroller to control lights and haptics
RGB LED Neopixel Strips For visual feedback (3 per side = 6 per dress)
Vibrating motors – Flat Coin Used in Dress 2 (pink), flat design
Vibrating motors – Round Type Used in Dress 1 (white)
2-pin Plug Connectors (15cm) Modular glove-to-dress connection
E6000 Glue Fixing LED strips to fabric
Zip ties Stabilizing LED strips
Heat shrink tubing Reinforcing vibrator wire endings
Spray paint Aesthetic + insulation for wires
Soldering iron + solder wire Assembling all electrical joints
Fabric base (custom cut) Carries the circuit layer
Velcro strips Attaching/removing circuit from dress
Power bank (USB-C) Portable power source

🧵 1. Base E-Textile Layer

A detachable textile layer sitting under the visible dress, containing all primary components.

  • Starting with connecting everything together

now that eveything works by its own , the xiaos, the Ble , the vibrator , the LEDS lets connect them


3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


  • Built from a fabric sheet with 6 glued LED strips (3 on each side).

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

  • E6000 glue + zip ties used to fix strips securely.

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

  • Mounted inside dress using Velcro for easy detachment.

3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B

  • Concealed pocket holds power bank on back interior.
  • Spray-painted wires for insulation and aesthetic blend. 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

⚡ 2. Power & Microcontroller

🔋 Power Source - Powered by a USB-C portable power bank (placed in dress pocket).

🧠 XIAO ESP32 Pin Mapping

Board Label GPIO Role Dress 1 Dress 2
D10 20 LED Strip L Pin 10 Pin 9
D21 2 LED Strip R Pin 21 Pin 10
D7 7 Vibrators Shared for both dresses

  • Pins chosen to allow for duplicated logic between both dress versions.
  • Power routed from bank to ESP32 via USB-C.
  • Ground, 3.3V, and signal lines distributed from board to LEDs and vibrators.


🧤 3. Glove Integration

🦾 The Glove Prototype Adventure

I started crafting a prototype for my interactive glove project. At first, I thought I'd need a vibrator motor, resistor, and an LDR to get things working. The idea was simple: when the light level dropped (because both models held hands), the LDR would detect the darkness, triggering the vibrators. Easy, right?

  • 3D Printed Swatches as a prototype 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

  • adding vibrator, LDR, Resistor 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


What Prototyping helped me with ?

  1. 🔋 But Wait, There's More!
    After some testing, I realized the Xiao ESP32 could handle the whole thing without a resistor or LDR! It could handle the vibrators directly and manage everything I needed. No extra parts needed! 🙌 The Xiao was ready to rock and roll, just like a superhero in disguise.

  1. 📶 Bluetooth to the Rescue
    I then decided to add Bluetooth—not just to sync the gloves, but to use it as a distance sensor instead the LDR. Now, the distance between the two gloves could control the LED lights and vibrators. When the models were too far apart, the LEDs wouldn’t light up, and no vibration would happen. But as they got closer? Magic. ✨ Vibration and lights. No LDR required. Xiao’s got it all covered.

  1. 💡 In the End...
    The Xiao was my hero, turning a complicated mess into a simple, sleek setup. No extra parts, no struggle—just pure creative bliss. Just the way I like it. 😎

Each glove includes 2 sewn-in vibrating motors that connect to the circuit via modular plugs.

Construction: - Made with 2 textile layers: base + 3D printed tulle overlay.

3D PRINT - Pattren 01 B


  • Vibrating motors placed in sensational contact zones.

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


  • Wires reinforced with heat shrink tubing.

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


Modular Connection: - Uses 15cm male-female 2-pin plug connectors: - Female end on the dress base layer. - Male end on the gloves. - Allowing quick snap-in and disconnect during wear.

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


Vibrator Types by Dress

Dress Motor Type Specs & Link
Dress 01 (White) Round Vibrator Aexit DC 3V Electric Motors 10000RPM 4mm x 12mm Cylindrical
Dress 02 (Pink) Flat Coin BestTong 10000RPM Wired Vibration Motors 10mm x 2mm

  • Detachable gloves allow for independent wear or interaction.
  • Plug system makes the glove modular and easy to repair.
  • Vibrators are aesthetically hidden within glove seams.

3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B 3D PRINT - Pattren 01 B


📊 Schematic Diagram

      +-----------------------------+
      |         XIAO ESP32          |
      |   [USB]         [RESET]     |
      |                             |
      |  D10 / GPIO 20 → LED Strip L1 (Signal)  
      |  D21 / GPIO 2  → LED Strip L2 (Signal)  
      |  D9  / GPIO 21 → LED Strip L3 (Signal)  
      |  D7  / GPIO 7  → Vibrators (Signal)    
      |   GND -------- GND (LEDs + Vibrators)
      |  3.3V ------- Power (LEDs only)        
      +-----------------------------+
                |         |
          ______|__     __|_____
         |         |   |        |
     Vibrator 1   Vibrator 2   (→ gloves)

 ← LED Strip L1     LED Strip R1 →
 ← LED Strip L2     LED Strip R2 →
 ← LED Strip L3     LED Strip R3 →

[Each LED strip has 3 wires: GND (black), 3.3V (red), Signal (green)] [Each vibrator has 2 wires: Signal (red), GND (black) via GPIO7]


🧩 Design Highlights by Section

  1. Base Layer:
  2. Fabric base holds all electronics without impacting comfort.
  3. Double-securing with glue + zip ties for LED stability.

  4. Connectivity:

  5. Uses modular plug-ins to keep electronics detachable.
  6. Wires painted and arranged aesthetically for visual blend-in.

  7. Maintenance:

  8. Velcro system allows layer to be fully removed and washed.
  9. All connections reinforced with shrink tubing or zip ties.

  10. Aesthetics:

  11. Spray-painted wires blend into the fabric.
  12. Circuit design follows the contours of the body for minimal visibility.


Feature Function
Modular Gloves + circuit detach easily
Interactive LEDs + vibration respond to logic
Wearable Comfortable textile base, washable
Duplicated Designed identically for both dresses with slight pin changes

Code

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <Adafruit_NeoPixel.h>

// Bluetooth Settings
const char* deviceName = "ESP32-Device";
const int proximityThreshold = -32;
const int farThreshold = -45;
BLEScan* pBLEScan;

// Hardware Pins
#define PIN_1 10
#define PIN_2 21
#define NUM_LEDS 20
#define VIBRATOR_PIN 7

// LED Strips Setup
Adafruit_NeoPixel strip1(NUM_LEDS, PIN_1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2(NUM_LEDS, PIN_2, NEO_GRB + NEO_KHZ800);

// State Variables
bool isClose = false;
bool isFar = false;
bool vibratorsOn = false;
int rssiValue = -100;

// Bluetooth Scanning Class
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
        if (advertisedDevice.getName() == deviceName) {
            rssiValue = advertisedDevice.getRSSI();
            Serial.print("RSSI: ");
            Serial.println(rssiValue);  // Print the RSSI value to the Serial Monitor

            if (rssiValue >= proximityThreshold) {
                isClose = true;
                isFar = false;
                Serial.println("Status: Close");
            } else if (rssiValue <= farThreshold) {
                isFar = true;
                isClose = false;
                Serial.println("Status: Far");
            } else {
                isClose = false;
                isFar = false;
                Serial.println("Status: Medium");
            }
        }
    }
};

void setup() {
    Serial.begin(115200);
    pinMode(VIBRATOR_PIN, OUTPUT);
    digitalWrite(VIBRATOR_PIN, LOW);

    strip1.begin();
    strip2.begin();
    strip1.show();
    strip2.show();

    BLEDevice::init(deviceName);
    BLEServer *pServer = BLEDevice::createServer();
    BLEAdvertising *pAdvertising = pServer->getAdvertising();
    pAdvertising->start();

    pBLEScan = BLEDevice::getScan();
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true);
}

void fadeLines(int delayTime) {
    for (int i = 0; i < NUM_LEDS; i++) {
        strip1.setPixelColor(i, strip1.Color(255, 255, 255));
        strip2.setPixelColor(NUM_LEDS - i - 1, strip2.Color(255, 255, 255));
        strip1.show();
        strip2.show();
        delay(delayTime);
    }
    for (int i = 0; i < NUM_LEDS; i++) {
        strip1.setPixelColor(i, strip1.Color(0, 0, 0));
        strip2.setPixelColor(NUM_LEDS - i - 1, strip2.Color(0, 0, 0));
        strip1.show();
        strip2.show();
        delay(delayTime);
    }
}

void movingLines(int delayTime) {
    for (int i = 0; i < NUM_LEDS - 1; i++) {
        strip1.clear();
        strip2.clear();
        uint32_t color = strip1.Color(255, 255, 255);

        strip1.setPixelColor(i, color);
        strip1.setPixelColor(i + 1, color);
        strip2.setPixelColor(i, color);
        strip2.setPixelColor(i + 1, color);
        strip1.show();
        strip2.show();
        delay(delayTime / 2);
    }
}

void blinkingEffect(int delayTime) {
    for (int i = 0; i < NUM_LEDS; i++) {
        strip1.setPixelColor(i, strip1.Color(255, 255, 255));
        strip2.setPixelColor(i, strip2.Color(255, 255, 255));
    }
    strip1.show();
    strip2.show();
    delay(delayTime);
    strip1.clear();
    strip2.clear();
    strip1.show();
    strip2.show();
    delay(delayTime);
}

void loop() {
    pBLEScan->start(1, false);
    delay(100);

    if (isClose) {
        if (!vibratorsOn) {
            digitalWrite(VIBRATOR_PIN, HIGH);
            delay(5000);
            digitalWrite(VIBRATOR_PIN, LOW);
            vibratorsOn = true;
        }
        fadeLines(50);  // Fades LED strips between each other
    } 
    else if (isFar) {
        blinkingEffect(300);  // Independent blinking effect on each strip
    } 
    else {
        movingLines(100);  // Independent moving lines effect on each strip
    }
}

ESP32 BLE Proximity-Based LED & Vibration System

📄 Brief Summary

This code uses an ESP32 to detect a specific Bluetooth Low Energy (BLE) device by name. Depending on how close that BLE device is (based on its signal strength or RSSI), the ESP32 will trigger different lighting effects on two LED strips and activate a vibration motor.


Behaviors: - Close range → Activates the vibrator once + fade animation on LEDs. - Medium range → Moving light line animation. - Far range → Blinking light animation.

This setup can be used in wearables, interactive installations, or proximity feedback systems.


🧩 Code Breakdown

  1. Library Imports
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <Adafruit_NeoPixel.h>

  • BLEDevice, BLEScan, etc. → Used for scanning nearby Bluetooth devices.

  • Adafruit_NeoPixel → Controls addressable LED strips.

  • BLE Settings and Thresholds

const char* deviceName = "ESP32-Device";
const int proximityThreshold = -32;
const int farThreshold = -45;
BLEScan* pBLEScan;
  • deviceName: The BLE device the ESP32 is scanning for.

  • proximityThreshold: RSSI level for "close" distance.

  • farThreshold: RSSI level for "far" distance.

  • pBLEScan: BLE scanner object used in the loop.

  • Hardware Pins & LED Setup

    #define PIN_1 10
    #define PIN_2 21
    #define NUM_LEDS 20
    #define VIBRATOR_PIN 7
    

  • PIN_1, PIN_2: Control two LED strips.

  • NUM_LEDS: Number of LEDs per strip.

  • VIBRATOR_PIN: Digital pin connected to a vibration motor.

Adafruit_NeoPixel strip1(NUM_LEDS, PIN_1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2(NUM_LEDS, PIN_2, NEO_GRB + NEO_KHZ800);
Define two NeoPixel LED strips with 20 LEDs each.
  1. State Variables

    bool isClose = false;
    bool isFar = false;
    bool vibratorsOn = false;
    int rssiValue = -100;
    

  2. These flags control what state the device is in based on RSSI proximity:

  3. isClose, isFar: To determine proximity zone.

  4. vibratorsOn: Used to only vibrate once when close.

  5. rssiValue: Stores signal strength from BLE device.

  6. BLE Scanner Callback Class

    class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
        void onResult(BLEAdvertisedDevice advertisedDevice) {
            if (advertisedDevice.getName() == deviceName) {
                rssiValue = advertisedDevice.getRSSI();
    

  7. When a BLE device is found, the callback checks if the name matches deviceName.
  8. Then it stores the RSSI signal strength.
if (rssiValue >= proximityThreshold) {
    isClose = true;
    isFar = false;
} else if (rssiValue <= farThreshold) {
    isFar = true;
    isClose = false;
} else {
    isClose = false;
    isFar = false;
}
Decides the state based on signal strength:

>= -32: Close

<= -45: Far

Between: Medium
  1. Setup Function

    void setup() {
        Serial.begin(115200);
        pinMode(VIBRATOR_PIN, OUTPUT);
        digitalWrite(VIBRATOR_PIN, LOW);
    

  2. Initialize serial monitor for debugging.

  3. Set vibrator pin as output and turn it off initially.


strip1.begin();
strip2.begin();
strip1.show();
strip2.show();
- Initialize both LED strips and clear them.


BLEDevice::init(deviceName);
BLEServer *pServer = BLEDevice::createServer();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
  • Start BLE service and begin advertising (this is optional and not crucial here).

pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
- Set up active BLE scanning and register the callback.

  1. LED Animation Functions fadeLines(int delayTime)
    for (int i = 0; i < NUM_LEDS; i++) {
        strip1.setPixelColor(i, white);
        strip2.setPixelColor(NUM_LEDS - i - 1, white);
    }
    
  2. Lights up the LEDs from outer edges to center (mirrored), then fades them back to black.

movingLines(int delayTime)

for (int i = 0; i < NUM_LEDS - 1; i++) {
    strip1.clear();
    strip2.clear();
    strip1.setPixelColor(i, white);
    strip1.setPixelColor(i + 1, white);

  • Creates a "snake-like" white light moving across the strip.

blinkingEffect(int delayTime)

for (int i = 0; i < NUM_LEDS; i++) {
    strip1.setPixelColor(i, white);
    strip2.setPixelColor(i, white);
}
- All LEDs flash white and then turn off, like a heartbeat blink.

  1. Main Loop Function
    pBLEScan->start(1, false);
    delay(100);
    
  2. Scans for BLE devices for 1 second every loop iteration.

Logic Based on Proximity:

if (isClose) {
    if (!vibratorsOn) {
        digitalWrite(VIBRATOR_PIN, HIGH);
        delay(5000);
        digitalWrite(VIBRATOR_PIN, LOW);
        vibratorsOn = true;
    }
    fadeLines(50);
}
- If the BLE device is close, vibrate once and do fade animation.


else if (isFar) {
    blinkingEffect(300);
}
If far, trigger blinking lights.

else {
    movingLines(100);
}
- If medium range, show the moving light effect.


fabrication files

-All fabrication files drive


🎬 Credits

This project was brought to life by a passionate team of creatives and technical talents. Deep gratitude to everyone involved:

  • Models: Maria Abu Liel & Leen farraj
  • Makeup Artist: Batoul
  • Hairstylist: Hamzeh
  • Director & Photographer: Alaa Makhlouf
  • Soldering & Technical Support: Omar Baalbaki
  • Tailors: Abo Omar & Waleed
  • Lighting: Ahmad Kashkah
  • Setup & Location Assistance: Hamid
  • Sponsor: Bank Al Etihad
  • Shooting Space: The MakerSpace CPf
  • Instructor:
    - Claudia Simonelli - Anastasia Pistofidou - Cecilia Raspanti - Oscar Tomico

  • Content Creation Support: Aya Al Mufti

  • Event Location: The Spark by Bank Al Etihad
  • Project Coordinator: Diala
  • Endless Love & Support: My family & my friends – thank you for standing by me through every stitch and solder.

This wearable vision wouldn’t have existed without each and every one of you.