Hive 240 by Yin Liu, Michael Uzzi, Chris Egervary, and Alex Olivier

Constructing the Hive

We talked about several construction methods/materials including wood, acrylic, etc..  In the end, we settled on using light-weight materials that would be easy to mount on the wall in the lobby of 240 Central Park South.  To maximize reconfigurability, we decided to create “mini-hives” of three honeycombs, which we could then attach together on the wall.  Chris CNCed blue foam bases that could accommodate a hexagonal piece of acrylic while still providing some room for electronics in back.  He also CNCed some nice wooded frames to fit over the front of the honeycombs.

 Yin and I lasercut acrylic pieces of various colors (white, frosted) to give the hive a bit more organic, less uniform look.  We also cut pieces of orange acetate to fit over the acrylic.

Image

 

Yin and I also lasercut foam core backs to fit over each of the units, with a small hole to fit an LED.  We assembled all of the pieces using wood glue!

Lastly, we wirewrapped white LEDs to header pins so that we could plug them into our breadboard later.  Things got a little messy…

Image

Coding the Hive

To program the behavior of our hive, we had to do a few different things.  First, we had to somehow get data from our iDigi data stream (which comes in XML format) and extract out the relevant bits.  I modified another XML parser to allow our Arduino to extract important data points.  

We also needed to control the animation of our LEDs.  We used TLC 5940 LED drivers (wired according to the datasheet), which have PWM control.  Below is the code for the entire installation:

//////////////////////////////////////////////
// Get XML formatted data from the XIG. Use it to control LED Driver.
// Original Code from Bob S.
// Modified by Alex Olivier, 12/12/2012.
//////////////////////////////////////////////

// Include description files for other libraries used (if any)
#include <string.h>
#include “Tlc5940.h”
#include “tlc_fades.h”

TLC_CHANNEL_TYPE channel;

// Define Constants
// Max string length may have to be adjusted depending on data to be extracted
#define MAX_STRING_LEN 40

// Setup vars
char tagStr[MAX_STRING_LEN] = “”;
char dataStr[MAX_STRING_LEN] = “”;
char tmpStr[MAX_STRING_LEN] = “”;
char endTag[3] = {‘<‘, ‘/’, ”};
int len;
boolean getData = false;

// Flags to differentiate XML tags from document elements (ie. data)
boolean tagFlag = false;
boolean dataFlag = false;
unsigned long time;

//for leds
uint16_t duration =2000; //default LED speed

void setup()
{
Tlc.init(); //initialize LED Driver code
time = 0;
Serial.begin(115200);

}

void loop() {

if ((millis() – time > 30000)|| time == 0){ // sample every 30 s
Serial.println(“http://itpatnyu:Interact4u!@my.idigi.com/ws/DataPoint/dia/channel/00000000-00000000-00409DFF-FF521E03/XBee_4079C120/average_amplitude_front?rollupInterval=hour&rollupMethod=average&#8221;);
time = millis();
}

// code for controlling LEDs
if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH – 2) {
if (!tlc_isFading(channel)) {
int maxValue = 4095;
uint32_t startMillis = millis() + 50;
uint32_t endMillis = startMillis + duration;
tlc_addFade(channel, 0, maxValue, startMillis, endMillis);
tlc_addFade(channel, maxValue, 0, endMillis, endMillis + duration);
}
if (channel++ == NUM_TLCS * 16) {
channel = 0;
}
}
tlc_updateFades();
}

// Process each char from web
void serialEvent() {
while (Serial.available()) {

// Read a char
char inChar = Serial.read();

if (inChar == ‘<‘) { // a tag is starting
//Serial.println(“tag!”);

if (getData == true){ // if we’re done getting the data chars
getData = false;
double dataNum = atof(dataStr); // convert chars to a double

// map sound data to LED animation speed
int clippedData = constrain(dataNum, 400, 800);
int lightDelay = map(clippedData, 400,800, 1000, 7000);
duration = lightDelay;;
clearStr(dataStr); // flush out data string

}else{

addChar2(inChar, tmpStr); // if it’s not data, start adding the chars to the other string
tagFlag = true;
}

}else if (inChar == ‘>’) { // we’re done with this tag

addChar2(inChar, tmpStr);
tagFlag = false;

if (strcmp(tmpStr, “<data>”)==0){ // is it a data tag
getData = true; // get data until the next < tag.
}
clearStr(tmpStr);

}else if (tagFlag == true){
addChar2(inChar, tmpStr);

}else if (getData == true){
addChar2(inChar, dataStr);
}
}
}

/////////////////////
// Other Functions //
/////////////////////

// Function to clear a string
void clearStr (char* str) {
int len = strlen(str);
for (int c = 0; c < len; c++) {
str[c] = 0;
}
}

//Function to add a char to a string and check its length (Alex version)
void addChar2 (char ch, char* str){

str[strlen(str)] = ch;
}

// Function to check the current tag for a specific string
boolean matchTag (char* searchTag) {
if ( strcmp(tagStr, searchTag) == 0 ) {
return true;
} else {
return false;
}
}

Installing the Hive

Luckily, we were able to install brackets on the walls of the lobby hallway.  Our piece was very light, so it wasn’t terribly tricky to hang out.

Image

Here’s the final piece, notice the laser-engraved label (which also hides our electronics!).

Image

Here’s the hive on the wall:

Image

 

Video coming soon!

 

Advertisements