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.
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 * 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);
}
}