LED skirt
Jump to navigation
Jump to search
Project LED skirt | |
---|---|
Status | In progress |
Contact | Noor |
Last Update | 2020-10-19 |
To do
- Reinforce wire connections with hot glue and/or zip ties.
- Punch and grommet holes where velcro used to be.
- Buy or make a carrying case (width ~80 cm, height ~110 cm), maybe pop-up tent bag.
- Make LEDs addressable by position.
- More programming designs.
- Get aurora borealis palette working properly on circles and panel, and shooting stars display on strips.
- Replace (or add to) strip in bottom tube with side-emitting LEDs?
LED count
- 240 - circles (all used except one)
- 64 - 8x8 panel.
- 23 - strip 1.
- 23 - strip 2.
- 17 - strip 3.
- 84 (?) - strip along bottom tube.
Total: 451 LEDs.
Timeline
Construction
2019-11-06 - 2019-11-11
Bought:
- 8x8 cm WS2812 LED panel
- 5m, 30 LEDs/m, IP67, black LED pixel strip
- 241 LEDs, rings of varying sizes from 3 to 17 cm
- [x2] 2-hoop crinolines to attach LEDs to
- 88 cm black skirt
Old sketches:
2019-11-12 - 2019-11-24
- Played with layout of LEDs, waiting for items to arrive.
- Tested out LEDs under layers and on crinoline.
2019-11-25
- Took apart seams of inner layers of black skirt to add extra panels to fit over crinoline.
2019-11-26
- Measured skirt on top of crinoline. Extra panel with bottom arc length of 100+cm.
- Decided to go with 6 strips of 23 LEDs each. Cut one strip.
2019-12-03 - 2019-12-05
- Tested out LED rings. One wire was detached so had to be soldered on.
2019-12-06
- Punched holes in crinoline, used zip ties to attach first LED strip.
- Took apart LED circles and tested FastLED programs.
- Set up LED circles, one strip, and panel together on crinoline and used zip ties to place everything but the panel on crinoline.
- Ran FastLED programs on everything together.
- Pictures posted by others to Facebook, RevSpace kiekjes, Twitter.
2019-12-20
- Rearranged LED circles, mounted some back on with velcro. Mounted panel with velcro.
- Cut two more strips. Attached wires to one and mounted it horizontally at an angle.
2019-12-22
- Folded up bottom hem and put velcro strips all across to partially make a tube along bottom.
2019-12-24
- Bought LED connectors (20 pairs, 3-pin).
2019-12-25
- Measured and cut panel for black layer of skirt.
2020-01-10
- Used fabric glue along bottom hem tube, in between velcro strips.
- Soldered wires to more LED strips.
2020-01-11
- Soldered wires to remaining LED strips.
- Connected everything together, hooked up to an Arduino.
2020-01-17
- Added more velcro bits to fix placement of LEDs.
- Experimented with modifying FastLED programs. BPM on circles?
2020-01-18 - 2020-02-13
- Experimented more with FastLED programs.
- For custom color palettes, used PaletteKnife bookmarklet to generate codes for palettes. Add to sketch directly, or add to Arduino/libraries/FastLED/colorpalettes.cpp and palette name to colorpalettes.h.
- Cut up plastic bag for panel over skirt, attached with velcro.
- Finished up everything on black outer skirt.
- Bought 2x SilverCrest power banks.
HackerHotel 2020
2020-02-14 -2020-02-16
- Debut as Princess of Lights went excellent, with paparazzi taking pictures and video all weekend.
- About a dozen wires broke off throughout the weekend and had to be soldered back on, some with reinforcements of zip ties to hold them in place.
- LEDs kept weighing down crinoline, and since the string in the waist came out a long time ago, the velcro was not enough to hold it up. Used an opened paperclip to hold it together, and then a safety pin. Need to add a hook fastener, or use a large safety pin (through grommeted holes) or some other kind of fastener.
Modified fastLED sketches that I used at HH2020:
Arduino 1 (for circles and panel):
#include <FastLED.h> FASTLED_USING_NAMESPACE #if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) #warning "Requires FastLED 3.1 or later; check github for latest code." #endif #define DATA_PIN 6 //#define CLK_PIN 4 #define LED_TYPE WS2811 #define COLOR_ORDER GRB #define NUM_LEDS 304 CRGB leds[NUM_LEDS]; #define BRIGHTNESS 15 #define FRAMES_PER_SECOND 120 #define SHIFT_PER_SECOND 15 void setup() { delay(3000); // 3 second delay for recovery // tell FastLED about the LED strip configuration FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // set master brightness control FastLED.setBrightness(BRIGHTNESS); } // List of patterns to cycle through. Each is defined as a separate function below. typedef void (*SimplePatternList[])(); SimplePatternList gPatterns = { rainbowWithGlitter, bpm, confetti, flowingwater }; uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current uint8_t gHue = 0; // rotating "base color" used by many of the patterns DEFINE_GRADIENT_PALETTE( Aleutian_Clouds_gp ) { 0, 37,184,133, 12, 37,184,133, 25, 46,168, 98, 37, 55,152, 67, 51, 22,104, 77, 63, 5, 66, 88, 76, 1, 31, 49, 88, 1, 19, 32, 100, 1, 2, 11, 112, 1, 3, 9, 125, 1, 6, 20, 137, 1, 10, 20, 149, 1, 2, 11, 161, 1, 19, 32, 173, 1, 31, 49, 185, 5, 66, 88, 200, 22,104, 77, 212, 55,152, 67, 225, 46,168, 98, 237, 37,184,133, 255, 37,184,133, }; void loop() { // Call the current pattern function once, updating the 'leds' array gPatterns[gCurrentPatternNumber](); // send the 'leds' array out to the actual LED strip FastLED.show(); // insert a delay to keep the framerate modest FastLED.delay(1000/FRAMES_PER_SECOND); // do some periodic updates EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically } #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) void nextPattern() { // add one to the current pattern number, and wrap around at the end gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); } void rainbow() { // FastLED's built-in rainbow generator fill_rainbow( leds, NUM_LEDS, gHue, 35); } void rainbowWithGlitter() { // built-in FastLED rainbow, plus some random sparkly glitter rainbow(); addGlitter(80); } void addGlitter( fract8 chanceOfGlitter) { if( random8() < chanceOfGlitter) { leds[ random16(NUM_LEDS) ] += CRGB::White; } } void confetti() { // random colored speckles that blink in and fade smoothly fadeToBlackBy( leds, NUM_LEDS, 10); int pos = random16(NUM_LEDS); leds[pos] += CHSV( gHue + random8(64), 200, 255); } void bpm() { // colored stripes pulsing at a defined Beats-Per-Minute (BPM) uint8_t BeatsPerMinute = 62; CRGBPalette16 palette = PartyColors_p; uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); for( int i = 0; i < NUM_LEDS; i++) { //9948 leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); } } int offset = 0; int framecounter = 0; void flowingwater() { CRGBPalette16 palette = Aleutian_Clouds_gp; for( int i = 0; i < NUM_LEDS; i++) { leds[i] = ColorFromPalette(palette, ((i+offset)%256), 128); addGlitter(1); } framecounter++; if (framecounter > FRAMES_PER_SECOND / SHIFT_PER_SECOND) { offset++; //offset = offset + random8(4); if (offset >= 256) { offset = 0; } framecounter = 0; } }
Arduino 2 (for strips), from fastLED's demo reel:
#include <FastLED.h> FASTLED_USING_NAMESPACE #if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) #warning "Requires FastLED 3.1 or later; check github for latest code." #endif #define DATA_PIN 6 //#define CLK_PIN 4 #define LED_TYPE WS2811 #define COLOR_ORDER GRB #define NUM_LEDS 147 CRGB leds[NUM_LEDS]; #define BRIGHTNESS 75 #define FRAMES_PER_SECOND 40 void setup() { delay(3000); // 3 second delay for recovery // tell FastLED about the LED strip configuration FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); // set master brightness control FastLED.setBrightness(BRIGHTNESS); } // List of patterns to cycle through. Each is defined as a separate function below. typedef void (*SimplePatternList[])(); SimplePatternList gPatterns = { confetti, sinelon, juggle, bpm }; uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current uint8_t gHue = 0; // rotating "base color" used by many of the patterns void loop() { // Call the current pattern function once, updating the 'leds' array gPatterns[gCurrentPatternNumber](); // send the 'leds' array out to the actual LED strip FastLED.show(); // insert a delay to keep the framerate modest FastLED.delay(1000/FRAMES_PER_SECOND); // do some periodic updates EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically } #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) void nextPattern() { // add one to the current pattern number, and wrap around at the end gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); } void confetti() { // random colored speckles that blink in and fade smoothly fadeToBlackBy( leds, NUM_LEDS, 10); int pos = random16(NUM_LEDS); leds[pos] += CHSV( gHue + random8(64), 200, 255); } void sinelon() { // a colored dot sweeping back and forth, with fading trails fadeToBlackBy( leds, NUM_LEDS, 20); int pos = beatsin16( 13, 0, NUM_LEDS-1 ); leds[pos] += CHSV( gHue, 255, 192); } void bpm() { // colored stripes pulsing at a defined Beats-Per-Minute (BPM) uint8_t BeatsPerMinute = 62; CRGBPalette16 palette = PartyColors_p; uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); for( int i = 0; i < NUM_LEDS; i++) { //9948 leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); } } void juggle() { // eight colored dots, weaving in and out of sync with each other fadeToBlackBy( leds, NUM_LEDS, 20); byte dothue = 0; for( int i = 0; i < 8; i++) { leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255); dothue += 32; } }
LED skirt corona-tion edition
Thought experiment: Corona-tion edition
- Skirt needs to keep other people 1.5 m away, so bottom hoop with 3 m radius (~9.4245 m diameter).
- Waist circumference (cut-off top of cone) is 65 cm, height is 1 m, bottom radius is 1.5 m.
- First back-of-the-envelope calculation: surface area of 70,000 sq cm for LEDs (that many if assuming 1 LED per sq cm).
- Requires a portable nuclear power station (can build them in openRA).
- Weight of LEDs can be dealt with by using a proper wooden/metal hoop skirt, with roller wheels at bottom.
- Plenty of space under skirt for batteries. Roller wheels can be powered wheels to move around.
- Power consumption can be reduced massively by adding in motion detectors that light up only some LEDs at a time if someone gets near [noopwafel].
- Addressable RGB leds will come at 5cts in bulk, so 3500 euro in LEDs excluding PCBs and other stuff [Sebastius].
- A proper calculation resulted in 87,656.25 sq cm surface area. Assuming 1 LED per sq cm, and approx 7 LEDs per euro, the cost of the LEDs would be 12,522 euro.
- Power consumption for 87,656 neopixel LEDs at 60 mA, 5 V each: 26+ kW, more than a 3x 35A mains set up to power [Peetz0r].
- LEDs are more likely to be 20 mA each, resulting in 8.77 kW [Juerd].
- With circle packing and lower density LEDs it might become affordable, if LEDs are placed inside circles with r = 2.5, ~4100 leds for triangular packing [supakeen].
Further work
2020-02-21 and 2020-02-25
- Removed velcro pads from skirt as they were coming apart and were useless at Hacker Hotel.
- Applied Mod Podge where velcro pads used to be, sealing loose threads.
2020-03-07
- Took apart a couple of cracked LCD screens. Diffusion and reflective films had some trippy effects (that don't show so well in pictures). Plan is to use them as panels for some parts.
2020-10
- Several Velcro patches need re-gluing back on.