# Fabric Display Build Guide

> **Goal:** Build an interactive, networked display on fabric — combining the electroluminescent textile concepts from [Shi et al. (Nature, 2021)](https://www.nature.com/articles/s41586-021-03295-8) and the LED-on-fabric approach from [Carpetlight / LED Professional](https://www.led-professional.com/resources-1/articles/lighting-fabrics-a-new-approach-for-flexible-light-sources).

---

## 1. Technology Landscape

The two source articles represent opposite ends of the same spectrum:

| | Nature Paper (EL Textile) | Carpetlight (LED Fabric) |
|---|---|---|
| **Light source** | ZnS:Cu phosphor EL units at warp-weft contacts | Discrete SMD LEDs on miniature PCBs |
| **Pixel pitch** | ~800µm (research-grade) | ~10–20mm (commercial) |
| **Addressing** | AC field at fiber intersections | Standard LED driver (DMX/PWM) |
| **Flexibility** | Fully woven, machine-washable | Rip-stop polyamide, rollable |
| **DIY feasibility** | Lab-only (ionic gel electrodes, custom fibers) | **Highly practical** |
| **Interactivity** | Demonstrated textile keyboard (capacitive) | External control only |

**Bottom line:** The Nature paper's exact process (ionic gel transparent electrodes, ZnS:Cu phosphor-coated fibers, industrial weaving) is not reproducible outside a materials science lab. But its *architecture* — a woven grid where intersections are pixels, with integrated capacitive touch — can be replicated using commercially available components.

---

## 2. Three Practical Build Approaches

### Approach A: Addressable LED Matrix on Fabric (Recommended Start)

The most accessible path. Uses off-the-shelf components to create a flexible, interactive pixel grid on textile.

#### Bill of Materials

| Component | Specific Product | Source | Est. Cost |
|---|---|---|---|
| LED panel | WS2812B 16×16 flexible matrix (256px) | AliExpress, Adafruit, SuperLightingLED | $15–40 |
| Substrate fabric | Rip-stop nylon (1.1oz, silicone-coated) | Ripstop by the Roll, Amazon | $5–15 |
| Controller | ESP32-S3 DevKit | Adafruit, SparkFun, Mouser | $8–15 |
| Touch sensing | MPR121 capacitive breakout (12 channels) | Adafruit (#1982), SparkFun | $8 |
| Touch electrodes | Conductive thread (stainless steel or silver-coated) | Adafruit (#641), SparkFun | $3–8 |
| Power | 5V 4A USB-C power bank or wall adapter | Amazon | $10–20 |
| Logic level shifter | 74AHCT125 or SN74HCT245 (3.3V→5V) | Adafruit, Mouser | $2 |
| Diffusion layer | White ripstop nylon or organza | Fabric store | $3–5 |
| Protection | 1000µF capacitor, 330Ω resistor | Any electronics supplier | $1 |

**Total: ~$55–115**

#### Construction Steps

**Step 1 — Prepare the fabric substrate**
- Cut rip-stop nylon to desired panel size + 2cm margin on all sides
- Mark a grid for the LED panel position and touch zones
- If using multiple LED panels (e.g., 4× 8×8 to make 16×16), plan the daisy-chain data path in a serpentine pattern

**Step 2 — Mount LEDs to fabric**
- **Option A (simplest):** Use flexible WS2812B matrix panels. Bond to fabric with E6000 flexible adhesive or fabric glue. The flexible PCB substrate bends with the fabric.
- **Option B (like Carpetlight):** Create fabric pockets/sleeves for LED strips. Sew channels from rip-stop, slide strips in. Allows removal for washing.
- **Option C (closest to Nature paper):** Use individual WS2812B modules. Sew each LED to fabric using conductive thread for power/ground rails, with thin silicone wire for the data line.

**Step 3 — Wire the LED matrix**
```
Power Supply (5V, 4A+)
    │
    ├──► 1000µF capacitor across V+ and GND
    │
    ├──► LED Matrix V+ (inject power every 64 LEDs)
    │
    └──► ESP32 Vin
         │
         GPIO pin ──► 330Ω resistor ──► 74AHCT125 ──► LED Data In
```

- Use silicone-jacketed wire (30 AWG) for flexibility
- For matrices >128 LEDs, inject power at multiple points to prevent voltage drop
- Common ground between ESP32 and LED power supply is **critical**

**Step 4 — Add capacitive touch**
- Embroider touch zones onto the fabric using conductive thread
- Create isolated zones (e.g., 4×3 grid = 12 touch areas matching MPR121's 12 inputs)
- Route conductive thread traces to an edge connector area
- Keep positive and negative traces at least 3mm apart to avoid shorts
- Connect to MPR121 breakout via I²C (SDA/SCL to ESP32)

```
Conductive Thread Layout (back of fabric):
┌─────────────────────────────┐
│  [Zone1] [Zone2] [Zone3]    │
│  [Zone4] [Zone5] [Zone6]    │  ← Embroidered conductive pads
│  [Zone7] [Zone8] [Zone9]    │
│             ...              │
│  ════════════════════════    │  ← Thread traces to edge
│  → MPR121 breakout board    │
└─────────────────────────────┘
```

**Step 5 — Diffusion layer**
- Layer white organza or thin white rip-stop over the LED matrix
- A 5–10mm spacer (foam or spacer fabric mesh) between LEDs and diffusion layer softens the hotspots into smooth pixel blobs
- Sew or Velcro the diffusion layer for removability

**Step 6 — ESP32 firmware**
```cpp
// Core libraries
#include <FastLED.h>
#include <Wire.h>
#include <Adafruit_MPR121.h>

#define NUM_LEDS    256
#define DATA_PIN    16
#define MATRIX_W    16
#define MATRIX_H    16

CRGB leds[NUM_LEDS];
Adafruit_MPR121 cap = Adafruit_MPR121();

void setup() {
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setMaxPowerInVoltsAndMilliamps(5, 4000);  // limit current
  FastLED.setBrightness(80);
  cap.begin(0x5A);  // MPR121 default I2C address
}

void loop() {
  uint16_t touched = cap.touched();
  for (int i = 0; i < 12; i++) {
    if (touched & (1 << i)) {
      // Map touch zone i to pixel region and update
      setTouchZoneColor(i, CRGB::White);
    }
  }
  FastLED.show();
  delay(16);  // ~60fps
}

// Map 12 touch zones to 16x16 pixel regions
void setTouchZoneColor(int zone, CRGB color) {
  int zx = zone % 3;  // 3 columns of touch zones
  int zy = zone / 3;  // 4 rows of touch zones
  int px = zx * 5;    // each zone covers ~5 pixels wide
  int py = zy * 4;    // each zone covers ~4 pixels tall
  for (int y = py; y < py + 4 && y < MATRIX_H; y++) {
    for (int x = px; x < px + 5 && x < MATRIX_W; x++) {
      int idx = (y % 2 == 0) ? (y * MATRIX_W + x) : (y * MATRIX_W + (MATRIX_W - 1 - x));  // serpentine
      leds[idx] = color;
    }
  }
}
```

---

### Approach B: EL Wire/Panel Woven Grid

Closer to the Nature paper's warp-weft concept, using commercial EL materials.

#### Key Components

| Component | Product | Source | Notes |
|---|---|---|---|
| EL wire (warp) | 2.3mm EL wire, multiple colors | Adafruit, SparkFun, Ellumiglow | Each color = separate AC channel |
| Conductive fiber (weft) | Silver-coated nylon thread (235Ω/ft) | Adafruit (#641) | Woven perpendicular to EL wire |
| AC inverter | 3V or 12V EL inverter | SparkFun, Adafruit | Converts DC→AC (100-200V, 1kHz) |
| AC switching | Opto-triacs (MOC3021) + triacs (BT136) | Mouser, DigiKey | One per EL channel |
| Controller | Arduino Nano or ESP32 | Standard | Drives opto-triacs via GPIO |
| Frame | Embroidery hoop or lightweight aluminum | Craft store | Keeps the weave taut |

#### Architecture

```
EL Wire Segments (warp, vertical)
    ║   ║   ║   ║   ║
════╬═══╬═══╬═══╬═══╬════  ← Conductive thread (weft, horizontal)
    ║   ║   ║   ║   ║
════╬═══╬═══╬═══╬═══╬════
    ║   ║   ║   ║   ║

Each ╬ = potential EL pixel (glows where AC passes through intersection)
```

**How it works:**
- EL wire segments run vertically (warp)
- Conductive threads run horizontally (weft)
- Applying AC between a specific warp wire and weft thread illuminates only their intersection
- **Row-column scanning** (multiplexing) addresses individual pixels, just like the Nature paper

> ⚠️ **Caution:** EL wire operates at 100–200V AC. Proper insulation, isolated opto-triac drivers, and careful handling are essential. This approach requires intermediate electronics experience.

#### Practical pixel resolution
- EL wire: 2.3mm diameter → minimum pitch ~5mm with spacing
- Achievable grid: ~20×20 pixels per 10cm² panel
- Color: limited to EL wire color choices (blue, green, orange, white, pink)

---

### Approach C: Screen-Printed EL Ink on Fabric

Closest to the Nature paper's pixel density, but requires screen printing equipment.

#### Materials

| Layer | Material | Supplier |
|---|---|---|
| **Base electrode** | Silver conductive ink (screen-printable) | Sun Chemical (SunTronic), Creative Materials |
| **Dielectric** | Barium titanate dielectric paste | Saralon, SPLinx |
| **Phosphor** | ZnS:Cu EL phosphor paste (SaralEL Display Ink) | Saralon (Blue/Green/Orange/White) |
| **Top electrode** | PEDOT:PSS transparent conductive ink | Heraeus (Clevios), Sigma-Aldrich |
| **Substrate** | Tightly-woven polyester or cotton fabric | Any fabric supplier |

#### Process (per panel)

1. Screen-print silver conductive traces on fabric (bottom electrode grid pattern)
2. Cure at 130°C for 10 min
3. Screen-print dielectric layer over the electrode pattern
4. Cure at 130°C for 10 min
5. Screen-print ZnS:Cu phosphor layer over dielectric
6. Cure at 130°C for 10 min
7. Screen-print transparent PEDOT:PSS top electrode
8. Cure, then seal with flexible polyurethane coating
9. Connect bus bars to AC inverter (60–200V, 400–1000Hz)

> ⚠️ This requires screen printing equipment, a curing oven, and access to specialty inks (~$50–200 per ink system from Saralon). Best suited for maker spaces with printing facilities.

---

## 3. Adding Interactivity

All approaches support the same input methods:

### Capacitive Touch (recommended)
- **Behind the display:** Embroider conductive thread pads on the back of the fabric, behind pixel zones
- **Controller:** MPR121 (12-channel) or FDC2214 (4-channel, higher sensitivity) connected to ESP32
- **Principle:** Human finger changes capacitance through the fabric layers; controller detects the change
- **Thread choices:**
  - Stainless steel thread (Adafruit #641) — durable, moderate conductivity
  - Silver-coated nylon (Adafruit #640) — higher conductivity, less durable after washing

### Pressure/Force Sensing
- **Velostat/Eeonyx:** Sandwich conductive fabric + piezoresistive sheet + conductive fabric
- **Use case:** Detect where and how hard someone presses
- **Resolution:** One analog reading per zone

### Gesture (proximity)
- **APDS-9960:** Detects hand swipes 10–20cm from the fabric surface
- **Use case:** Touchless control layer

---

## 4. Networking with DreamStack

The fabric display becomes a **DreamStack streaming endpoint**:

```
┌──────────────────────────────────┐
│  ESP32 on Fabric                 │
│                                  │
│  signal pixels = [256 × RGB]     │──► DreamStack bitstream
│  signal touch_zones = [12 × bool]│    via WiFi → relay
│                                  │
│  on touch_zone[i] changed:       │
│    mutate pixels[zone_region]    │
└──────────────────────────────────┘
         ▲                │
         │                ▼
   Remote Input      Remote Viewer
   (phone/laptop)    (any browser)
```

**Key integration points:**
- Pixel state is a flat signal array — efficient for bitstream delta encoding
- Touch events generate mutations that propagate upstream through the relay
- Remote clients can push pixel data downstream (animations, text, images)
- Conflict resolution (version counters) arbitrates simultaneous fabric-touch + remote-touch

---

## 5. Supplier Quick Reference

| Category | Supplier | URL | Key Products |
|---|---|---|---|
| Addressable LEDs | Adafruit | adafruit.com | NeoPixel matrices, strips |
| Addressable LEDs | SuperLightingLED | superlightingled.com | Flexible WS2812B panels |
| EL wire/thread | Ellumiglow | ellumiglow.com | SewGlo EL thread, EL wire |
| EL wire | SparkFun | sparkfun.com | EL wire, inverters, sequencers |
| EL inks | Saralon | saralon.com | SaralEL Display Inks (screen-print) |
| EL inks | SPLinx | splinx.eu | EL coatings and varnishes |
| Conductive thread | Adafruit | adafruit.com | Stainless (#641), silver (#640) |
| Conductive fabric | LessEMF | lessemf.com | Shielding fabric, conductive textiles |
| Touch IC | Adafruit | adafruit.com | MPR121 breakout (#1982) |
| Fiber optic fabric | Light Up Wear | lightupwear.com | Pre-woven fiber optic fabric |
| LED-on-fabric (commercial) | Forster Rohner | ffrosti.com | e-broidery LED textiles |
| Microcontrollers | Adafruit/SparkFun | — | ESP32-S3, Pico W |

---

## 6. Comparison: Which Approach For What?

```mermaid
graph LR
    A["Want to build<br/>this weekend?"] -->|Yes| B["Approach A<br/>LED Matrix on Fabric"]
    A -->|"Want EL glow<br/>aesthetic"| C["Approach B<br/>EL Wire Grid"]
    A -->|"Want highest<br/>pixel density"| D["Approach C<br/>Screen-Print EL Ink"]
    B --> E["+ Touch + ESP32<br/>= Interactive Display"]
    C --> E
    D --> E
    E --> F["+ DreamStack<br/>= Networked Display"]
```

| | Approach A | Approach B | Approach C |
|---|---|---|---|
| **Time to build** | 1–2 days | 1 week | 2+ weeks |
| **Cost** | $55–115 | $80–150 | $200–500 |
| **Pixel count** | 256+ (16×16 or larger) | ~100–400 | ~1000+ |
| **Color** | Full RGB | Limited (EL colors) | Limited (phosphor colors) |
| **Flexibility** | Good (flexible PCB) | Excellent (wire) | Good (printed) |
| **Brightness** | High | Low-medium | Low |
| **Interactivity** | Easy (capacitive touch) | Moderate | Moderate |
| **Washable** | With removable pockets | Fragile | With PU sealing |
| **Skills needed** | Basic soldering, sewing | Electronics + HV safety | Screen printing + chemistry |
