Skip to content

9. Wearables

Portada

Wearables in the textile industry are revolutionizing the way we think about fashion and the functionality of garments. These devices integrate advanced technology directly into fabrics, creating smart clothing that can interact with its environment and the wearer. From garments that monitor health, such as t-shirts with heart rate sensors, to jackets that connect to mobile devices, wearables are merging the worlds of fashion and technology.

CREATIVE PEOPLE

Asher Levine

Asher Levine is a visionary fashion designer known for his innovative approach to fashion, combining high technology with avant-garde aesthetics. Renowned for his work with iconic figures like Lady Gaga, Taylor Swift, and Doja Cat, Asher has cemented his reputation in the industry by creating groundbreaking and designs that challenge conventional norms in fashion.



describe what you see in this image

Cameron Hughes

Cameron Hughes designs move as if they each have a mind of their own. On one dress, purple feathers rise and lower like a bird’s ruffled feathers. On another, a swarm of robotic butterflies flap their wings. Still another features spinning tubes of fabric that transform a skirt from pink to blue and back again. The 29-year-old New Yorker makes high-tech couture, and celebrities including Doja Cat, Charli XCX, and Gigi Hadid have all worn his pieces.


@cameronhughes Ok I got it to work. 😀 #fashionindustry #nyfw #arduino ♬ breathin - Ariana Grande
@cameronhughes Hey CVS #fashion101 #fashion #TeamofTomorrow #makingthecut ♬ in heat X brooklynbloodpop - embrr.wav


Casey Curran

describe what you see in this image

Casey Curran received his BFA in painting and sculpture from Cornish College in 2006. Since then he’s been involved in numerous gallery and museum exhibitions locally and nationally.
Focus primarily in sculpture, but not limited to any specific medium, he create kinetic environments with an internal logic and history often propelled by a simple hand crank. He invite the viewer to become a part of the work through participation, animating a tableau of flora and fauna that bloom or flutter to life when activated.


@debora.spencer Beautiful kinetic piece by Casey Curran. #kineticsculpture#kineticcouture #couture #caseycurran #kineticfashion #imminentmode #seattlekingstreetstation #kingstreetstation #seaofficeofarts #fashionphotographer ♬ Natural - eas Ratta
@asianweddingmag #AppreciationPost BTS on how GENIUS @casey_curran brings @hautemona vision of this incredible kinetic arm piece to life in under 30 days! 🤍 #asianweddingmagazine ♬ original sound - AsianWeddingMagazine



MOVEMENT TEST

The Schematic

There are different design programs to create the schematics but, Kicad is much easier and free.
To download Kicad click here!
NOTE: In this schematic I am adding a button, but, in my first test I did not include any button in the programming, because I just wanted to test that the servos worked.

Laser cut

Include Servo library
- The Servo library is included to control servomotors.

Define Servo objects
- Four Servo objects named Raul1, Raul2, Raul3, and Raul4 are created to control the servomotors.

Pin setup (setup function)
- In the setup() function, each Servo object is attached to a specific pin (D3, D4, D5, D6) on the microcontroller.

Servo movement (loop function)
- In the loop(), all servos move to the 0-degree position, then wait for 800 ms.
- After that, all servos move to the 180-degree position, then wait for 800 ms and this cycle repeats continuously.

Arduino code

#include <Servo.h>

Servo Raul1;
Servo Raul2;
Servo Raul3;
Servo Raul4;

void setup() {
Raul1.attach(D3);
Raul2.attach(D4);
Raul3.attach(D5);
Raul4.attach(D6);
}
void loop() {
Raul1.write(0);
Raul2.write(0);
Raul3.write(0);
Raul4.write(0);
delay(800);
Raul1.write(180);
Raul2.write(180);
Raul3.write(180);
Raul4.write(180);
delay(800);
}



SENSOR HC-SR04 & SERVOMOTOR

Distance measurement with HC-SR04: The HC-SR04 sensor is used to measure the distance between the sensor and an object. The Trig pin generates an ultrasonic signal, which bounces off a nearby object and returns to the Echo pin. The time it takes for the signal to return is proportional to the distance.

Servomotor control:
- Servo at 180 degrees: If the sensor detects an object within 30 cm (threshold value that you can adjust), the servo motor will move to 180 degrees.
- Servo at 0 degrees: If no object is detected (the distance is greater than 30 cm), the servo motor will return to its 0-degree position.

Servomotor behavior: The servomotor only moves once per detection. Using the servoMovido variable, it ensures that the servo does not repeatedly change its position while the object is still present. The servo will only move if it detects a new object or if the object moves away.

Serial communication: The code also prints the measured distance on the Serial Monitor, allowing you to verify the distance and the state of the servo motor in real time.

Arduino code

#include <Servo.h>

// Pin configuration
const int pinTrig = D7;   // Pin for the Trig of the HC-SR04
const int pinEcho = D8;   // Pin for the Echo of the HC-SR04
const int pinServo = D1;  // Pin for the servo motor

// Create servo object
Servo myServo;

long duration, distance;
bool servoMoved = false; // Variable to track if the servo has already moved

void setup() {
  // Initialize pins
  pinMode(pinTrig, OUTPUT);  // The Trig pin will be an output
  pinMode(pinEcho, INPUT);   // The Echo pin will be an input
  myServo.attach(pinServo);  // Connect the servo motor to pin D1

  Serial.begin(9600);  // Start serial communication for debugging
}

void loop() {
  // Send a 10-microsecond pulse to the Trig pin
  digitalWrite(pinTrig, LOW);
  delayMicroseconds(2);
  digitalWrite(pinTrig, HIGH);
  delayMicroseconds(10);
  digitalWrite(pinTrig, LOW);

  // Read the pulse time from the Echo pin
  duration = pulseIn(pinEcho, HIGH);

  // Calculate the distance in centimeters
  distance = duration * 0.034 / 2;

  // Print the distance to the serial port
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // If the distance is less than 10 cm and the servo has not moved yet, move the servo to 180 degrees
  if (distance < 30 && !servoMoved) {
    myServo.write(180);  // Move the servo motor to 180 degrees
    servoMoved = true;   // Mark that the servo has moved
    Serial.println("Movement detected. Servo moved to 180 degrees.");
  }

  // If there's no movement and the servo has already moved to 180 degrees, move it back to 0 degrees
  if (distance >= 30 && servoMoved) {
    myServo.write(0);    // Move the servo motor to 0 degrees
    servoMoved = false;  // Mark that the servo has returned to the initial position
    Serial.println("No movement. Servo moved to 0 degrees.");
  }

  delay(500);  // Wait half a second before the next measurement
}


VELOSTAT SENSOR TEST

Include Adafruit_NeoPixel library
- The Adafruit_NeoPixel library is included to control the Neopixels.

Define pins and parameters
- The pin connected to the Neopixel (PIN) and the pin connected to the Velostat pressure sensor (SENSOR_PIN) are defined.
- The number of Neopixels is defined (in this case, 1).

Declare colors
- Several RGB colors are defined that will be assigned to the Neopixel (red, green, blue, yellow, cyan, and magenta).

Setup function
- Initializes the Neopixel and sensor pin.
- Sets the Neopixel to the first color in the list.
- Starts serial communication at 9600 baud to monitor the sensor.

Sensor reading and color change (loop function)
- Reads the value from the Velostat pressure sensor.
- If the value is less than 500 (indicating the sensor is pressed), it changes the Neopixel color to the next one in the list and shows it.
- Ensures the color change doesn't happen too quickly (with a delay(200)).
- If the sensor value is greater than 500, it resets the sensor state.

Arduino code

#include <Adafruit_NeoPixel.h>

#define PIN D10  // Pin to Neopixel
#define SENSOR_PIN D0  // Pin to Velostat
#define NUM_PIXELS 1  // Number of Neopixels

Adafruit_NeoPixel pixels(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);

// Variables for color change control
int sensorValue = 0;
int lastSensorValue = 0;
bool isPressed = false;
int colorIndex = 0;

// Colors 
uint32_t colors[] = {
  pixels.Color(255, 0, 0),   // Red
  pixels.Color(0, 255, 0),   // Green
  pixels.Color(0, 0, 255),   // Blue
  pixels.Color(255, 255, 0), // Yellow
  pixels.Color(0, 255, 255), // Cian
  pixels.Color(255, 0, 255)  // Magenta
};

void setup() {
  pixels.begin();
  pinMode(SENSOR_PIN, INPUT);
  pixels.setPixelColor(0, colors[colorIndex]); // Initialize with the first color
  pixels.show();

  Serial.begin(9600);
}

void loop() {
  sensorValue = analogRead(SENSOR_PIN);  // Read Velostat sensor value

  // Detects pressure change
  if (sensorValue < 500 && !isPressed) {  // Presion Umbral
    isPressed = true;  // Indicates that the sensor has been pressed

    // To change the color of neopixel
    colorIndex = (colorIndex + 1) % (sizeof(colors) / sizeof(colors[0]));
    pixels.setPixelColor(0, colors[colorIndex]);
    pixels.show();
    delay(200); // Delay to avoid very fast changes
  }

  // If the sensor is not pressed, reset the state
  if (sensorValue > 500 && isPressed) {
    isPressed = false;
  }
}



VELOSTAT SENSOR SECOND TEST

This code uses two Velostat pressure sensors (one connected to each input pin) to control two independent Neopixels. Each time one of the sensors is pressed, the corresponding Neopixel changes color, cycling through a predefined list of colors. The colors change cyclically when the sensor is pressed, and each Neopixel responds independently to the sensor it's connected to.

NOTE: In this schematic I'm adding three sensors, but I only tested with 2 because I lost one of the Neopixels. Ops!

The Schematic

Laser cut

Explanation of Key Features

Control of Two Neopixels with Two Sensors:
- The code allows for independent control of two Neopixels (one for each sensor). When a sensor is pressed, the corresponding Neopixel changes color.

Pressure Sensors (Velostat)
- Each sensor is read to detect whether it has been pressed. If the value read is lower than a threshold (500), it indicates that the sensor is being pressed, which triggers the color change on the corresponding Neopixel.

Color Cycling
- Each time a sensor is pressed, the color of the corresponding Neopixel changes to the next one in the list of colors, and this change is shown on the Neopixel.
- The code ensures that color changes don’t occur too quickly by adding a delay(200).

Predefined Colors
- A set of colors (red, green, blue, yellow, cyan, magenta) is defined, and these colors are cycled through when the sensors are pressed.

Arduino code

#include <Adafruit_NeoPixel.h>

#define PIN1 D10  // Pin to the first Neopixel
#define PIN2 D9  // Pin to the second Neopixel
#define SENSOR_PIN1 A0  // Pin to the first velostat sensor
#define SENSOR_PIN2 A1  // Pin to the sencond velostat sensor
#define NUM_PIXELS 1    // Number of Neopixels for each pin

Adafruit_NeoPixel pixel1(NUM_PIXELS, PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixel2(NUM_PIXELS, PIN2, NEO_GRB + NEO_KHZ800);

// Variables for color change control
int sensorValue1 = 0;
int sensorValue2 = 0;
int lastSensorValue1 = 0;
int lastSensorValue2 = 0;
bool isPressed1 = false;
bool isPressed2 = false;
int colorIndex1 = 0;
int colorIndex2 = 0;

// Definición de colores
uint32_t colors[] = {
  pixel1.Color(255, 0, 0),   // Red
  pixel1.Color(0, 255, 0),   // Green
  pixel1.Color(0, 0, 255),   // Blue
  pixel1.Color(255, 255, 0), // Yellow
  pixel1.Color(0, 255, 255), // Cian
  pixel1.Color(255, 0, 255)  // Magenta
};

void setup() {
  pixel1.begin();
  pixel2.begin();
  pinMode(SENSOR_PIN1, INPUT);
  pinMode(SENSOR_PIN2, INPUT);
  pixel1.setPixelColor(0, colors[colorIndex1]); // Start with the first color Neopixel 1
  pixel2.setPixelColor(0, colors[colorIndex2]); // Start with the first color Neopixel 2
  pixel1.show();
  pixel2.show();
}

void loop() {
  sensorValue1 = analogRead(SENSOR_PIN1);  // read first sensor
  sensorValue2 = analogRead(SENSOR_PIN2);  // read second sensor

  // Para el primer sensor (Neopixel 1)
  if (sensorValue1 < 500 && !isPressed1) {  // If you push the sensor
    isPressed1 = true;
    colorIndex1 = (colorIndex1 + 1) % (sizeof(colors) / sizeof(colors[0]));  // Change the color
    pixel1.setPixelColor(0, colors[colorIndex1]);
    pixel1.show();
    delay(200); // To avoid very fast changes
  }
  if (sensorValue1 > 500 && isPressed1) {  // f the sensor is not pressed
    isPressed1 = false;
  }

  // For the second sensor (Neopixel 2)
  if (sensorValue2 < 500 && !isPressed2) {  // If you push the sensor
    isPressed2 = true;
    colorIndex2 = (colorIndex2 + 1) % (sizeof(colors) / sizeof(colors[0]));  // Change the color
    pixel2.setPixelColor(0, colors[colorIndex2]);
    pixel2.show();
    delay(200); // To avoid very fast changes
  }
  if (sensorValue2 > 500 && isPressed2) {  //If the sensor is not pressed
    isPressed2 = false;
  }
}



PULSE SENSOR TEST

The Schematic

Laser cut

This code uses a pulse sensor to measure the heart rate and makes a set of Neopixels blink according to the pulse rate. Each time a heartbeat is detected, the Neopixels turn red and blink at a speed corresponding to the heart rate (BPM).

Main Features

Define pins and parameters
- The pin where the Neopixels are connected (PIN_NEOPIXELS), the number of Neopixels (NUMPIXELS), and the pin where the pulse sensor is connected (PULSE_SENSOR_PIN) are defined.

Pulse sensor reading
- In the loop(), the pulse sensor value is constantly read to detect heartbeats.

Heartbeat detection
- If the sensor value exceeds a set threshold (threshold), a heartbeat is counted, and the heart rate (pulseRate) is incremented.

Blink interval calculation
- The heart rate (BPM) is mapped to a blink interval (from 1000 ms to 200 ms). This means that the higher the BPM, the faster the Neopixels will blink.

Control of the Neopixels
- When a heartbeat is detected, the Neopixels light up in red and blink at the speed determined by the BPM.
- It ensures that the blink interval stays within a reasonable range (between 200 ms and 1000 ms).
- After each blink, the Neopixels are turned off for the same duration.

State reset
- If the sensor value drops below the threshold, the pulse state is reset to detect the next heartbeat.

Arduino code

#include <Adafruit_NeoPixel.h>

// Define the pins and parameters
#define PIN_NEOPIXELS D10       // Pin where the Neopixels are connected
#define NUMPIXELS 4            // Number of Neopixels
#define PULSE_SENSOR_PIN D3    // Pin where the Pulse Sensor is connected

// Pulse sensor variables
int pulseValue = 0;         // Value of the pulse reading
int threshold = 550;        // Detection threshold for beats (adjustable)
bool lastPulseState = false; // Previous pulse state (detected/not detected)
int pulseRate = 0;          // Heart rate (BPM)

// Initialize the Neopixel strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, PIN_NEOPIXELS, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);  // To monitor the pulse via the serial port
  strip.begin();
  strip.show();  // Initially turn off the Neopixels
}

void loop() {
  pulseValue = analogRead(PULSE_SENSOR_PIN);  // Read the sensor value

  // If a heartbeat is detected (exceeds the threshold), turn on the Neopixels
  if (pulseValue > threshold && !lastPulseState) {
    pulseRate++;  // Count a heartbeat
    lastPulseState = true;  // Mark that a heartbeat has been detected
    Serial.print("Heartbeat detected! Pulse rate: ");
    Serial.println(pulseRate);

    // Map the heart rate (BPM) to a blink interval
    int blinkInterval = map(pulseRate, 60, 120, 1000, 200);  // Map the BPM to an interval from 1000ms to 200ms

    // Ensure the interval is within a reasonable range
    blinkInterval = constrain(blinkInterval, 200, 1000);  // Don't allow the interval to be less than 200ms or greater than 1000ms

    // Neopixel blink: Turn on the LEDs
    strip.fill(strip.Color(255, 0, 0));  // Turn the Neopixels red
    strip.show();
    delay(blinkInterval);  // Wait for the blink interval determined by the BPM

    // Turn off the Neopixels
    strip.clear();
    strip.show();
    delay(blinkInterval);  // Wait for the off interval determined by the BPM
  } 
  else if (pulseValue < threshold) {
    lastPulseState = false;  // Reset the state if the value falls below the threshold
  }

  // If there is no signal, keep the Neopixels off
  else {
    strip.clear();
    strip.show();  // Ensure the Neopixels are off
  }
}