Skip to content

The (almost) Firefly

Introduction

Art imitates nature, and so can wearable electronics. I’ve designed an outfit inspired by my fascination towards firflies. The (almost) Firefly is a copying of what makes fireflies special, their light. Thus, the skirt is designed to respond to motion by sparkling light.

A Closer Look

So… how does it work? After all the trials and error I had, I can finally say, it’s fairly simple! The microcontroller is programmed to calculate the acceleration vector every 600 milliseconds, if the latest vector is larger than a set variable, motion is recognized and is responded with light.

An Even Closer Look

The Design

The top is plain and basic green tank that was laser-cut and then laser-engraved with a firefly to live up to the project’s name.

The skirt has two layers (disregarding the pouch that pockets the battery). The first layer holds the neopixels and is a dark blue to emphasize the light and resemble the ponds where fireflies live. The layer above is a sheer dark blue organza to add texture and hide the scars of the electronics sewn on the first layer.

The Electronics

The layout of the electronics is pretty simple. The battery is attached to a booster to acheive the optimum 5V, which is then connected to VCC and GND pins on seperate small boards I like to call “The Common”, which are soldered to the microcontroller’s (ATtiny85) VCC and GND pins, that is connected to the MPU-6050, and the neopixels use the MISO on the ATtiny and the VCC and GND from The Common.

The Code

The code is combination of Ashish Choudary’s “Build a Portable Step Counter using ATtiny85 and MPU6050” code, and the color wipe function from the AdaFruit Neopixel Library examples + some of my changes.

#include "TinyWireM.h"
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define LED_PIN    6
#define LED_COUNT 11

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);


int accelX, accelY, accelZ;
char mpu = 0x68;  
float vectorprevious;
float vector;
float totalvector;

void setup() {

  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)


  TinyWireM.begin();
  TinyWireM.beginTransmission(mpu); 
  TinyWireM.write(0x6B); //  Power setting address
  TinyWireM.write(0b00000000); // Disable sleep mode (just in case)
  TinyWireM.endTransmission();
  TinyWireM.beginTransmission(mpu); 
  TinyWireM.write(0x1B); // Config register for Gyro
  TinyWireM.write(0x00000000); // 250° per second range (default)
  TinyWireM.endTransmission();
  TinyWireM.beginTransmission(mpu); //I2C address of the MPU
  TinyWireM.write(0x1C); // Accelerometer config register
  TinyWireM.write(0b00000000); // 2g range +/- (default)
  TinyWireM.endTransmission();

}
void loop() {
 getAccel();
 vector = sqrt( (accelX * accelX) + (accelY * accelY) + (accelZ * accelZ) );
 totalvector = vector - vectorprevious;

if (totalvector > 6){
  colorWipe(strip.Color(255,   255,   51), 50); // yellow
  colorWipe(strip.Color(  255, 255,   255), 50); // white
  colorWipe(strip.Color(  153,   255, 255), 50); // Blue
}

  strip.show();            // Turn OFF all pixels ASAP

vectorprevious = vector;
delay(600);

}

void getAccel() {
  TinyWireM.beginTransmission(mpu); //I2C address of the MPU
  TinyWireM.write(0x3B); //  Acceleration data register
  TinyWireM.endTransmission();
  TinyWireM.requestFrom(mpu, 6); // Get 6 bytes, 2 for each DoF
  accelX = TinyWireM.read() << 8|TinyWireM.read(); 
  accelY = TinyWireM.read() << 8|TinyWireM.read();
  accelZ = TinyWireM.read() << 8|TinyWireM.read();

}

void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}