dreamstack/docs/fabric-display-build-guide.md

317 lines
14 KiB
Markdown
Raw Permalink Normal View History

# 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) | ~1020mm (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 | $1540 |
| Substrate fabric | Rip-stop nylon (1.1oz, silicone-coated) | Ripstop by the Roll, Amazon | $515 |
| Controller | ESP32-S3 DevKit | Adafruit, SparkFun, Mouser | $815 |
| Touch sensing | MPR121 capacitive breakout (12 channels) | Adafruit (#1982), SparkFun | $8 |
| Touch electrodes | Conductive thread (stainless steel or silver-coated) | Adafruit (#641), SparkFun | $38 |
| Power | 5V 4A USB-C power bank or wall adapter | Amazon | $1020 |
| Logic level shifter | 74AHCT125 or SN74HCT245 (3.3V→5V) | Adafruit, Mouser | $2 |
| Diffusion layer | White ripstop nylon or organza | Fabric store | $35 |
| Protection | 1000µF capacitor, 330Ω resistor | Any electronics supplier | $1 |
**Total: ~$55115**
#### 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 510mm 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 100200V 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 (60200V, 4001000Hz)
> ⚠️ This requires screen printing equipment, a curing oven, and access to specialty inks (~$50200 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 1020cm 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** | 12 days | 1 week | 2+ weeks |
| **Cost** | $55115 | $80150 | $200500 |
| **Pixel count** | 256+ (16×16 or larger) | ~100400 | ~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 |