Introduction: LED Dress for Any Season

About: Lean something about everything and everything about something. Never stop creating.

No time to knit an ugly sweater for the holiday? - no problem. Add some LEDs to anything to make it satisfyingly ugly - or festive. Using addressable LEDS also allows you to tweak your code and instantly have festive attire for any holiday!

These LEDS are attached to a lightweight slip to be worn under a skirt or dress so it can be worn with more than one outfit.

The project is broken down into a few components.

1. LEDS - strips of indexable LEDS - like these 5050 NEOPIXEL LEDS

2. Battery Pack - a 5v battery supply - I used a phone charger that can output up to 3A

3. Controller - Arduino nano or similar ATmega328P

4. Code - I used the FastLED library.

In addition you will need to be able to solder wires on the LEDS and a sewing kit.

Step 1: LEDS

If you are not familiar with these LEDs, take the time to read Adafruit's guide to Neopixels.

1. Cut the LEDS into strips. Mine are 11 pixels long and 22 strips around. I set it up as two 11x11 "panels." So I could use it to project some basic images too. Most of the these LEDS I've used have a connector on one end. Use this as the first strip. It will make things easier later on.

Each strip has cut marks between the LEDS. Be carful to cut along the line. The copper pads are for soldering wires and you need to make sure that there is enough room to solder on each end.

Also, mind the direction of each strip. I've used these in a number of projects and still managed to solder one in backwards. Fortunately, they are easy to resolder.

2. Solder wires to the pads to connect the strips. Mine are wired in a boustrophedon pattern - a fancy way to say back and forth.

3. Use some heat shrink to secure the solder points.

4. Once all the LEDS are connected, pull off the paper backing and stick them to the fabric. This isn't enough to keep it all in place but it will help.

5. Finally, sew the ends on to the fabric. This will help keep things in place. I sewed around the end of the strip and on the wires.

Step 2: Controller and Power

The controller was made with an Arduino nano and soldered to a pcb I cut on a CNC. The PCB isn't strictly necessary but is a fun way to add a conspicuous button.

PCB - I used a CNC router to cut the PCB and traces. This is a double sided copper prototyping board like these from amazon. You can also get single sided boards - I used double sided so the face of the board would be copper as well.

The traces cut part way through the board. Leaving a isolated conductive path. I drilled all the way through where each of the pins are soldered through.

The three wires at the bottom are GND, VIN, and DATA. The button at the top is used to cycle throught the different patters that the dress will display.

Lastly, the controller and LEDS will need power. To connect the battery pack you will need to add a USB connection to your harness. The USB Cable isn't carrying data so all we care about are the RED and BLACK wires. These are power and ground. It is important that the Nano, battery and LEDS all share the same ground.

USB Red = 5v

USB Black = ground

Step 3: Code

The code relies heavily on the FastLED Library. FastLED has support for many different chips and LEDS. It also has a bunch of great color management, math and other function that help keep your sketch small and fast.

https://github.com/FastLED/FastLED

Another handy tool is this map generator, especially if you decide to have gaps in your strings.

https://macetech.github.io/FastLED-XY-Map-Generato...

My code does three patterns.

  1. Fades in and out reds and greens
  2. Fades in and out with in blues and whites
  3. Runs through the phases of the moon
  4. Turns off all the LEDS

I'm working on a Christmas tree too but I wasn't happy with the way it looked at the moment.

I took a make-it-work method over elegant coding - I copied parts from other programs I had and didn't spend much time cleaning thing up.

I expect anyone doing something similar would want to write their own code from scratch but it is included.

#include <FastLED.h>
#include <Button.h>

#define ROW 11
#define COLUMN 11
#define DATA_PIN 10
#define NUMBER_OF_PATTERNS 1
#define NUM_LEDS ROW*COLUMN //there are to 11x11 so NUM_LEDS is actually only half of the total
#define DATA_PIN 10

Button button = Button(2, BUTTON_PULLUP_INTERNAL);
CRGB MoonStrip[NUM_LEDS * 2];


/*---------- MOON PHASES  -----------*/
/*
255 = off
0 turns on first
1 second... 
counts using phaseCounter 
*/

uint8_t luna[11][11] = {  
  {255, 255, 255, 255, 2, 3, 10, 255, 255, 255, 255},
  {255, 255, 1, 2, 3, 5, 9, 10, 11, 255, 255},
  {255, 1, 2, 3, 4, 5, 8, 9, 10, 11, 255},
  {255, 1, 2, 4, 5, 6, 7, 8, 9, 11, 255},
  {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12},
  {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12},
  {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12},
  {255, 1, 2, 4, 5, 6, 7, 8, 9, 11, 255},
  {255, 1, 2, 3, 4, 5, 8, 9, 10, 11, 255},
  {255, 255, 1, 2, 3, 5, 9, 10, 11, 255, 255},
  {255, 255, 255, 255, 2, 3, 10, 255, 255, 255, 255}
};


int phaseCounter = 0; 
int waxWane = 1; //tells to turn on or off

/* ------------------ END MOON PHASE  ------------------*/

// Global variables
uint8_t val = 0;  //HSV
uint8_t sat = random8(); // HSV
uint8_t hue = 0;  // HSV
uint8_t selector = 0; // counts button presses
uint8_t tempPlace = 0; //used as index for pixels in array - sometimes
int flipper = 1; //used to alternate colors






/* ------ SETUP ------ */
void setup() {

  LEDS.addLeds<WS2812, DATA_PIN, GRB >(MoonStrip, NUM_LEDS * 2);
  LEDS.setBrightness(80);

  // make sure all leds are off at the start
  all_off();
  FastLED.show();

}
/* ------ END SETUP() ------ */


/*--------------- MAIN PROGRAM -----------------*/
void loop() {

  FastLED.setBrightness(255); // Set brightness - more POWER

  /* ----- START BUTTON SECTION ----- */

  if (button.uniquePress()) {
    //Serial.println(selector);
    selector++;
    phaseCounter = 1;
  }

  if (selector == 0) {
    EVERY_N_SECONDS (4) { // time to next phase
      if (phaseCounter > 13) {
        phaseCounter = -1;
        waxWane = waxWane * -1;
      }
      phaseCounter++;
    }
    moon_to_strip();
  }

  else if (selector == 1) {
    all_off();
  }

  else if (selector == 2) {
    all_off();
  }
  else if (selector == 3) {
    drops();
  }
  else if (selector == 4) {
    all_off();
  }
  else if (selector == 5) {
    sparkle_Christmas();
  }
  else if (selector == 6) {
    all_off();
  }
  else {
    selector = 0;
  }
  /*     -------------- END OF BUTTON SELECTION PART -------------------- */
  FastLED.show();  

}
/*---------------- END MAIN PROGRAM ----------------*/



/* ----- START DROPS() random points of light fade in and out ------*/
void drops() {

  EVERY_N_MILLISECONDS (random(500, 1000)) {
    tempPlace = random8(0, NUM_LEDS * 2);
    val = 0;
    sat = random8();
    MoonStrip[tempPlace] = CHSV(160, sat, val);
  }

  EVERY_N_MILLISECONDS(30) {
    if (val < 255) { // if it is not at full brightness add to V until new pixel is spaned
      val = val + 10;
      MoonStrip[tempPlace] = CHSV(160, sat, val);
    }
    for (uint8_t i = 0; i < NUM_LEDS * 2; i++) { //dim everything a bit
      MoonStrip[i].nscale8(252);
    }
  }
}

/* ------ END DROPS() -------*/




/* ----- TURN OFF ALL THE LEDS ----- */
void all_off() {
  for (int i = 0; i < NUM_LEDS; i++) {
    MoonStrip[i] = CRGB :: Black;
    MoonStrip[i + NUM_LEDS] = CRGB :: Black;
  }
}
/* ----- END ALL OFF() ------*/


/* ----- SPARKELS CHRISTMAS COLORS BLINK IN AND FADE OUT RANDOMLY ----- */
void sparkle_Christmas() {

  EVERY_N_MILLISECONDS (random(500, 1000)) { // spawn a new pixel, alternating red or green
    tempPlace = random8(0, NUM_LEDS * 2);
    val = 0;
    if (flipper == 1) {
      hue = 96;
      flipper = flipper * -1;
    }
    else if (flipper == -1) {
      hue = 0;
      flipper = flipper * -1;
    }
    else {
      flipper = 1;
    }
    MoonStrip[tempPlace] = CHSV(hue, 255, val);

  }

  EVERY_N_MILLISECONDS(30) {
    if (val < 255) {  //make it a brigter 
      val = val + 10;
      MoonStrip[tempPlace] = CHSV(hue, 255, val);  
    }
    for (uint8_t i = 0; i < NUM_LEDS * 2; i++) { // dim everthing a bit
      MoonStrip[i].nscale8(250);  
    }
  }
}
/* ---- END SPARKEL_CHRISTMAS() -----*/



/*------ TRANSLATE THE MOON PHASES TO THE LED ARRAY  ------*/
void moon_to_strip() {

  uint8_t i = 0;
  if (waxWane == 1) {
    for (uint8_t y = 0; y < ROW; y++) {  // turn on and increase brightnesslights in order in luna[][] - top/bottom of moon is symetrical so running columns backwards doesn't matter
      for (uint8_t x = 0; x < COLUMN; x++) {
        if (luna[x][y] == phaseCounter && luna[x][y] != 255) {
          MoonStrip[i] += CRGB(0, 0, 1);
          MoonStrip[i + NUM_LEDS] += CRGB(0, 0, 1);  //do the same to the second 11x11 matrix
        }
        i++;
      }
    }
  }

  if (waxWane == -1) {
    for (uint8_t y = 0; y < ROW; y++) {
      for (uint8_t x = 0; x < COLUMN; x++) {
        if (luna[x][y] == phaseCounter) {
          MoonStrip[i].fadeToBlackBy(2);
          MoonStrip[i + NUM_LEDS].fadeToBlackBy(2);
        }
        i++;
      }
    }
  }
}

/*----- END MOON_TO_STRIP()  -----*/


Step 4: Finishing Touches and Power It Up

Once everything is working. Find a suitable dress, skirt or whatever and let your LEDS shine!

They will shine brightest through white or light colored fabric. Tulle also does a good job of dispersing the light.

The dress we had available didn't have any pockets for the battery so we sewed an old sock to the inside of the back. The battery pack fit snugly in the sock and since it was positioned at about the small of the back, it wasn't visible.

Happy Holidays!

Ugly Sweater Speed Challenge

Participated in the
Ugly Sweater Speed Challenge