BLE LED Pocket Square

2015 Sunday 8 Nov

Short

An illuminating pocket square, controlled via bluetooth: a gadget to steal the show.

Facts

built for Albert
owner Albert
state finished (since november 2015)

Description

Inspired by the Draper 2.0, Illuminated Pocket Square by ChrisSmolinski on Instructables.com, I built one that can be controlled via bluetooth, which makes it possible to control the lightning via my smartphone. Using a WS2812 LED-strip (Adefruit NeoPixels) - which enables every LED to be addressed individual - more advanced color-transitions and effects can be build. Furthermore, a beat-button was attached, for tapping the delay between beats.

Hardware

The Hardware consists of an Arduino Pro Mini (5v), combined with a HC-06 bluetooth module. For the communcation between the two modules, a voltage devider was required to prevent blowing the rx-line of the hc-06. Finally, I attached the WS2812 RGB LED-strip containing 6 LEDs is connected to the arduino, together with the beat-button and a 9v connector cable.

image

Software

App

I used the BlueTooth Serial Controller app, which makes it possible to bind buttons to a serial commando.

Arduino Sketch

/*   *   SCRIPT FOR BLUETOOTH CONTROLLED NEOPIXEL STRIP *   MADE BY ALBERT VAN DER MEER *   avdm.nl */

#include <SoftwareSerial.h>

#include <Adafruit_NeoPixel.h>
#define PIXEL_COUNT 6
#define PIXEL_PIN   9
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);


int ledPin = 13;  // use the built in LED on pin 13 of the Uno
volatile int state = 1;
int flag = 0;        // make sure that you return the state only once
volatile unsigned long timeA = 0;
volatile unsigned long timeStorage = 0;
volatile unsigned long beat = 1000;
volatile bool change = false;
SoftwareSerial bt(10, 11); //rx, tx; ==> 6 = de tx van bt ding

void setup() {
  // sets the pins as outputs:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  //Serial.begin(9600); // Default connection rate for my BT module
  bt.begin(9600);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  attachInterrupt(digitalPinToInterrupt(3), addBeat, RISING);

}
void loop() {
  //if some data is sent, read it and save it in the state variable

  if (bt.available() > 0) {
    state = bt.read() - '0';
  }
  startShow(state);

}


void startShow(int i) {
  //Serial.println("startshow");
  //Serial.println(i);

  switch (i) {
    case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
      break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red
      break;
    case 2: colorWipe(strip.Color(0, 255, 0), 50);  // Green
      break;
    case 3: colorWipe(strip.Color(50, 50, 255), 50);  // Blue
      break;
    case 6: colorWipe(strip.Color(255, 255, 0), 50);  // Yellow
      break;
    case 5: rainbowCycle(50);
      break;
    case 7: rainbow(20);
      break;
    case 4: heenEnWeer(strip.Color(105, 0, 0), strip.Color(0, 0, 0), 55);
      break;
    case 8: beatShow(beat, strip.Color(255, 100, 0));
      break;
      /* case 9: //tap time         addBeat();         state = 99; //disable looptime         break;      */


  }
}

void addBeat() {
  if (millis() - timeA > 240) { //debouncing
    if (timeA == 0) {
      timeA = millis();
      beat = 2999;
    }
    else {
      timeStorage = millis();
      if ((timeStorage - timeA) < 3000) {
        beat = timeStorage - timeA;
      }

      timeA = timeStorage;
      change = true;
      state = 8;
    }
    bt.println(beat);
    //Serial.println("trigger");

    //beatShow(beat, strip.Color(255, 100, 0));

    //bt.println("hallo!");
    //bt.println(state);
  }

}

void beatShow(unsigned long beat, uint32_t c) {
  //Serial.println("kip");
  uint32_t co = strip.Color(0, 0, 0);
  int loopTime = (beat - 240) / 40;
  //Serial.println(loopTime);

  for (int i = 0; i < (7 + loopTime - 1); i++) {
    if (i == 0) {
      strip.setPixelColor(2, c);
      strip.setPixelColor(3, c);
    }
    if (i == 1) {
      strip.setPixelColor(1, c);
      strip.setPixelColor(4, c);
    }
    if (i == 2) {
      strip.setPixelColor(0, c);
      strip.setPixelColor(5, c);
    }
    if (i == 3) {
      strip.setPixelColor(0, c);
      strip.setPixelColor(5, c);
    }
    if (i == 4) {
      strip.setPixelColor(0, co);
      strip.setPixelColor(5, co);
    }
    if (i == 5) {
      strip.setPixelColor(1, co);
      strip.setPixelColor(4, co);
    }
    if (i == 6) {
      strip.setPixelColor(2, co);
      strip.setPixelColor(3, co);
    }
    if (checkChange()) {
      break;
    }
    delay(40);
    strip.show();





  }
}


bool checkChange() {
  if (bt.available() > 0 || change) {
    change = false;
    return true;
  }
}

// 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);
  }
}

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));
    }
    if (checkChange()) {
      break;
    }
    strip.show();
    delay(wait);
  }
}

void romantic() {
  // timeLong = millis();
  state = 3;

}

void heenEnWeer(uint32_t c, uint32_t co, int wait) {

  for (uint16_t i = 0; i < strip.numPixels() - 1; i++) {
    strip.setPixelColor(i, co);
    strip.show();
  }


  for (uint16_t i = 0; i < strip.numPixels() - 1; i++) {
    strip.setPixelColor(i - 1, co);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }


  for (uint16_t i = strip.numPixels(); i > 0; i--) {
    strip.setPixelColor(i + 1, co);
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  int lengthStrip = 30;
  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < lengthStrip; i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / lengthStrip) + j) & 255));
    }
    strip.show();

    if (checkChange()) {
      break;
    }
    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 (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int 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 (int 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 (int 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);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}