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

316 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 |