16.System integration

Material List

Product Quantity Mexican pesos Dollars Store
XIAO ESP32 C61128.006.64Unit Electronics
Thread6174.009.03Unit Electronics
Sensor LV-EZ0 MB10001613.0031.81Amazon
Rechargeable battery1390.0020.24Radio Shack
Velcro136.001.87Deportextil
Black zipper16.000.31Deportextil
Fabric "Pinguino"189.004.62Deportextil
Fabric "Kyoto"1.5114.005.92Deportextil
LEDs SMD10N/AN/AFab Lab
Resistors 1260 0Ω4N/AN/AFab Lab
Resistors 1260 270Ω10N/AN/AFab Lab
Resistors 1260 330Ω1N/AN/AFab Lab
Resistors 1260 10kΩ1N/AN/AFab Lab
MOSFET N 30V1N/AN/AFab Lab
Female pins1N/AN/AFab Lab
Phenolic plate1N/AN/AFab Lab
Wire cable3N/AN/AFab Lab
Total cost$1,550.00$80.44

This is a graphic showing how I arranged the cables and the conductive thread. Everything is placed on the inside of the vest so that nothing is visible from the outside. This makes it more comfortable and only the light from the LEDs is visible.

1

implemented methods of packaging

1

Integration with the LEDs

I used conductive thread to connect the LEDs. This method is more comfortable when someone wears the vest.

1

Integration with the PCB

The PCB is placed on the inside of the vest.

  • I soldered all the cables. I couldn't use conductive thread in this case because all of them would be in contact, which could cause short circuits. So, I used cable on the PCB and then soldered it with the conductive thread. To solder it, I covered one end of the thread with conductive tape.
  • I left some holes in case I want to add more LEDs later. They don’t affect the circuit and can work like antennas.
  • 1 1
1 1

Case in the vest

To protect the PCB, I made a silicone cover. I didn’t seal it completely so that air can circulate.

1 1

Integration of the Sensor

The way I connected the sensor is shown here. I left some holes in the back part of the vest to mount it.I used cables and placed them inside and at the back of the vest.

  • To keep the sensor in a stable position and avoid false readings, I secured it tightly with screws.
1

Battery Placement

I placed the battery in another pocket of the vest to keep the cables organized.

Electronics desing and production

Main Board

The schematic contains:

  • A MOSFET that controls all the LEDs. I added 10 terminals, but I only used 1 because the other 9 lines use conductive thread.
  • Pinout for the sensor; in this case, I’m using an analog input.
  • Extra pins for additional components like a vibration motor, Bluetooth module, and button.

In the PCB design, I used 0-ohm resistors as bridges.

electronics design electronics design electronics design
electronics design electronics design

Parameters and desing rules checker

Processes

The tools I used were:

  • Engraving: V-shaped tool
  • Hole cutting: 0.8 mm tool
  • Edge cutting: 2 mm tool
electronics design electronics design electronics design electronics design electronics design

Leds PCB

On the inside part, I decided to create a module where I added the LEDs, similar to Lilypad modules.

Example Image

I fabricated some modules and started placing them on the vest to achieve the desired lighting effect.

electronics design

Laser Cutting

The pattern design for the vest can be seen in week 2 laser cutting

I cut the fabric in parts using 100% polyester. The laser settings I used were:

  • Power: 70%
  • Speed: 30%
laser cutting

Usign the laser cutting

  1. I activated the power supply.
  2. I verified the air system was working.
  3. I turned on the laser machine.
  4. I deactivated the emergency stop button.
  5. I inserted the key and turned it to power the laser.
  6. I connected the USB drive to the machine.
  7. I chose my file from the USB.
  8. I pressed "Frame" to check the cutting area.
  9. I turned on the laser.
  10. I pressed "Start" to begin the cutting process.
laser cutting laser cutting laser cutting laser cutting laser cutting laser cutting

Molding and Casting

To make the vest comfortable at the pockets, I decided to use flexible silicone because it is soft.

You can see the detailed process in Molding and casting week

molding and casting molding and casting

Conductive Thread and Sewing

I sewed each module by hand because the conductive thread was too thick for the sewing machine.

Sewing Sewing Sewing

To make it washable, I added Velcro in some parts of the vest to attach and detach the LED modules.

Sewing

Sewing the Vest

  1. The shoulder seams of both the outer fabric and lining were sewn separately.
  2. The zipper was inserted between the outer fabric and lining (right sides facing) and sewn on both sides.
  3. The neckline, front edges, and lower front hem were sewn, joining the outer fabric and lining (right sides together).
  4. Two internal pockets were added with hidden openings to discreetly route electronic components.
  5. Velcro was sewn inside the vest, allowing for a removable fabric panel with conductive thread.
  6. The armholes were sewn, joining the outer and lining fabric (right sides together).
  7. The side seams were sewn, connecting outer and lining layers.
  8. The vest was turned right-side out.
  9. The final opening was closed using an invisible stitch.

Final result: A fully lined vest with no visible seams, a neatly finished zipper, and two hidden internal pockets for integrating electronics.

Sewing Sewing

Code


#define analogPin A2
#define ledPin D0
#define N 10
#define LED_ON_TIME 10000         // LED permanece encendido 10 s después de detectar
#define SENSOR_INTERVAL 50        // cada cuánto hacer una lectura (ms)
#define APAGADO_ESPERA 1000       // tiempo sin detección antes de apagar (ms)

unsigned long lastDetectionTime = 0;
unsigned long lastSensorReadTime = 0;
unsigned long lastInRangeTime = 0;

float lecturas[N];
int indice = 0;
bool ledEncendido = false;

float leerSensorCm() {
  int lectura = analogRead(analogPin);
  float voltaje = lectura * (3.3 / 4095.0);
  float pulgadas = voltaje / 0.00322;
  float cm = pulgadas * 2.54;
  return cm * 2.0;
}

float calcularPromedio() {
  float suma = 0;
  for (int i = 0; i < N; i++) suma += lecturas[i];
  return suma / N;
}

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

  // inicializa las lecturas
  float inicial = leerSensorCm();
  for (int i = 0; i < N; i++) lecturas[i] = inicial;
}

void loop() {
  unsigned long ahora = millis();

  // Leer sensor cada SENSOR_INTERVAL
  if (ahora - lastSensorReadTime >= SENSOR_INTERVAL) {
    lastSensorReadTime = ahora;
    lecturas[indice] = leerSensorCm();
    indice = (indice + 1) % N;

    float distancia = calcularPromedio();
    Serial.print("Distancia promedio: ");
    Serial.print(distancia, 1);
    Serial.println(" cm");

    if (distancia >= 150.0 && distancia <= 200.0) {
      lastDetectionTime = ahora;   // Se detectó algo válido
      lastInRangeTime = ahora;
      if (!ledEncendido) {
        digitalWrite(ledPin, HIGH);
        ledEncendido = true;
      }
    } else {
      // Si lleva más de APAGADO_ESPERA sin estar en rango, apaga
      if (ledEncendido && (ahora - lastInRangeTime > APAGADO_ESPERA) && (ahora - lastDetectionTime > LED_ON_TIME)) {
        digitalWrite(ledPin, LOW);
        ledEncendido = false;
      }
    }
  }
}


Summary

This code reads distance using an analog sensor. If an object is detected between 150–200 cm, it turns on an LED. The LED stays on for at least 10 seconds, and turns off only after 1 second without any valid detection.

1. Pin and constant definitions

#define analogPin A2
					#define ledPin D0
					#define N 10
					#define LED_ON_TIME 10000
					#define SENSOR_INTERVAL 50
					#define APAGADO_ESPERA 1000

These lines define constants:

  • analogPin: the analog input pin connected to the sensor.
  • ledPin: the digital output pin connected to the LED.
  • N: the number of readings used to calculate the average.
  • LED_ON_TIME: time the LED stays on after detection (10 seconds).
  • SENSOR_INTERVAL: how often the sensor is read (every 50 ms).
  • APAGADO_ESPERA: time without detection before turning off the LED (1 second).

2. Global variables

unsigned long lastDetectionTime = 0;
					unsigned long lastSensorReadTime = 0;
					unsigned long lastInRangeTime = 0;

					float readings[N];
					int index = 0;
					bool ledOn = false;

These variables track timing for detection, the current reading buffer index, and whether the LED is currently on.

3. Function to read distance

float readSensorCm() {
int reading = analogRead(analogPin);
float voltage = reading * (3.3 / 4095.0);
float inches = voltage / 0.00322;
float cm = inches * 2.54;
return cm * 2.0;
}

This function:

  • Reads the sensor using analogRead().
  • Converts the raw value to voltage, then to inches, then to centimeters.
  • Multiplies by 2 to apply a calibration factor.

4. Function to calculate average distance

float calculateAverage() {
					float sum = 0;
					for (int i = 0; i < N; i++) sum += readings[i];
					return sum / N;
					}

This function calculates the average of the last N sensor readings for stability.

5. setup() function

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

float initial = readSensorCm();
for (int i = 0; i < N; i++) readings[i] = initial;
}

In setup:

  • Starts the serial monitor.
  • Sets the LED pin as output and turns it off.
  • Fills the readings array with an initial distance value.

6. loop() function

void loop() {
unsigned long now = millis();

Gets the current time in milliseconds since the program started.

if (now - lastSensorReadTime >= SENSOR_INTERVAL) {
lastSensorReadTime = now;
readings[index] = readSensorCm();
index = (index + 1) % N;

Every 50 ms, a new distance is read and stored in the circular readings buffer.

float distance = calculateAverage();
Serial.print("Average distance: ");
Serial.print(distance, 1);
Serial.println(" cm");

Calculates the average distance and prints it to the serial monitor.

if (distance >= 150.0 && distance <= 200.0) {
lastDetectionTime = now;
lastInRangeTime = now;
if (!ledOn) {
	digitalWrite(ledPin, HIGH);
	ledOn = true;
}

If the distance is between 150 and 200 cm, an object is detected. The LED is turned on if it wasn't already.

} else {
if (ledOn &&
	(now - lastInRangeTime > APAGADO_ESPERA) &&
	(now - lastDetectionTime > LED_ON_TIME)) {
	digitalWrite(ledPin, LOW);
	ledOn = false;
}
}

If no object has been in range for more than 1 second, and it’s been 10 seconds since the last detection, the LED turns off.

Conclusion🛸🛸

Thinking about how to organize everything was a challenge because I didn’t know how to make it removable. I wanted the vest to be washable, so I needed to make the electronic parts removable to protect them. I also had to carefully consider the position of the sensor so it could read distance accurately. I’m happy with the result—no cables are visible, and it looks like a finished product. Everything is hidden inside the vest.

Get in touch

Follow