Interactive Project – Skirt with Neopixels+Tilt Sensor

The neopixels and LEDs will turn on with the motion of the person because of the tilt sensor. The LEDs are red and there is no variation in color, they just turn on and off. The neopixels turn on and off and have colorful and patterns that change over time. My idea was that as someone walks or dances, the lights will move along with the person.

Materials:
-skirt
-Sewable neopixels
-3ply steel conductive thread
-sewing needle
-LEDs
-330K resistor
-small breadboard
-glue or nail polish to seal the knots of thread (I used clear nail polish)
-tilt sensor
-jumpers
-three heat shrinkers
-scissors
-pliers
-9V battery
-arduino

In my design, there are four neopixels and two LEDs. When connecting the paths of the neopixels with the LEDs, I connected the thread going through the power pin in the neopixel to the power leg of the LED, but connecting the ground thread to the LED did not work, so I had to connect the thread going through the data pin to the ground leg of the LED. All powers connect together. And instead of connecting the ground pin to the LED, I sewed directly from one ground pin on neopixel to the next ground pin on a neopixel. I used clear nail polish to sell the knots that I had to make throughout and on threads that were a little loose.

When sewing, you have to make sure the paths of the power, ground, and data don’t cross over. Each path should be separate, all around the design.

This is the path of the thread connected to the neopixels and the LEDs. The thread goes out from the first neopixel and into the pocket of the skirt. The threads of the power, ground, and data pin, were tied around jumpers and covered with heat shrinkers to make sure the threads or jumpers didn’t touch each other. These jumpers were connected to a small breadboard and to the arduino. (The power and ground into the breadboard and the data pin into data pin 1 in the arduino).

This is how I tied the thread around the legs of the LEDs. I used the nail polish to seal those threads and to make sure the threads didn’t fall off the legs. With a plier I curved the tips of the legs of the LEDs, this way it’s not poking the person wearing the skirt.

The one leg of the tilt sensor should be connected in the same row as the power, one leg of the resistor should also be connected to this row.
The other leg of the resistor should be connected in a different row. In this same row, the other leg of the tilt sensor should also be connected. In this row, the power pin of the neopixels should be connected.
Ground from the adruino should be connected in the same row as the ground of the neopixles.

Code:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 1 //

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(9, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 – 500 Ohm resistor on first pixel’s data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit…if you must, connect GND first.

int inPin = 2;         // the number of the input pin
int outPin = 13;       // the number of the output pin

int LEDstate = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

// the follow variables are long’s because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 50;   // the debounce time, increase if the output flickers

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code

  strip.begin();
  strip.show(); // Initialize all pixels to ‘off’

   pinMode(inPin, INPUT);
  digitalWrite(inPin, HIGH);   // turn on the built in pull-up resistor
  pinMode(outPin, OUTPUT);
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  colorWipe(strip.Color(255, 0, 0), 50); // Red
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
  // Send a theater pixel chase in…
  theaterChase(strip.Color(127, 127, 127), 50); // White
  theaterChase(strip.Color(127, 0, 0), 50); // Red
  theaterChase(strip.Color(0, 0, 127), 50); // Blue

  rainbow(20);
  rainbowCycle(20);
  theaterChaseRainbow(50);
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }

  int switchstate;

  reading = digitalRead(inPin);

  // If the switch changed, due to bounce or pressing…
  if (reading != previous) {
    // reset the debouncing timer
    time = millis();
  }

  if ((millis() – time) > debounce) {
     // whatever the switch is at, its been there for a long time
     // so lets settle on it!
     switchstate = reading;

     // Now invert the output on the pin13 LED
    if (switchstate == HIGH)
      LEDstate = LOW;
    else
      LEDstate = HIGH;
  }
  digitalWrite(outPin, LEDstate);

  // Save the last reading so we keep a running tally
  previous = reading;
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 – WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
}