I was inspired by the works of John Cage's improvisational music composition and dance performances, as well as the visual color theory experiments by Josef Albers. I wanted to give dancers a platform to create visual performances simultaneously to their physical performances. The garment is a standard black leotard with (4) flex sensors positioned at the hips and elbows. For future iterations i would like to explore new wearable sensor materials, more dynamic visual translation, and possibly creating the garment myself.
The flex sensors are connected to the ground and voltage. There is a 10k resistor between ground and the flex sensor. The sensors are then connected to the analog in pins.
The Harness
In order to get optimal flex output data, I chose to attach the sensors to thin plastic. This allows for me to have the most control in the direction of the bend and the placement and security of the sensors.
The Visuals
I have attached the Arduino data output to OpenFrameworks using the Firmata library. This allows for direct communication between the Arduino and my sketch, without any Arduino / Procession software running. For this first step I have connected the flex sensor to a basic circle graphic. The scale of the circle is determined by the flex data input. I have also mapped the data for smoother transition as well as added a xeno code to get rid of some of the glitches.
Dance is one of the most beautiful visual languages I know. I was inspired by a contemporary dance performance to John Cages music.
Look & Feel
I will be experimenting more with the material but I want there to be a stiffness for the sensors to be efficiently flexible. I am thinking I will first try using plastic, maybe strips of, with the flex sensors places strategically in areas of the body that the dancer may bend and curve.
The output of the individual sensors will trigger a particular sound/chime/beat that will continue to play for a brief amount of time then will mute until triggered again. The different pieces of sounds will create a composition of music that is especially unique to the wearer. I want there to be minimum exposure of the technical aspects of the dress. I have am also not sold on the design of the dress. With future prototype I will experiment with different patterns and materials.
I am really excited about this project because it came naturally to me.
We can all relate to the sense of fear and anxiety that is related to new experiences and surroundings of the unknown. The same is with new pets, whether dog or hamster. I wanted to remind everyone of this undeniable sense by allowing them to interact with this animated undefinable pet. I will achieve the feeling of anxiety and fear by performing some calm reactions. Such as the pet playing dead if touched and LEDs fading in and out with the speed determined by its proximity to an object.
We have been working on combining LED matrix with other sensors to create a game controller, where the matrix functions as display, sensor as data input and Arduino as internal game logics. The controller includes a battery (1.5V?), an LED matrix, an accelerometer, a 7-digit display, an Arduino board and an enclousure.
The LED matrix that we bought from Sparkfun is an 8x8 Red/Green display. The accelerometer from RadioShack is dual-axis, sensing tilt, collision, vibration, rotation, and gravity. The idea is to use accelerometer to sense tilting and shaking of the controller itself, using the data as input for the pong game that's embedded in the Arduino. The faster you shake the controler when the ball hit the "pong board", the faster the ball will fly away. The 7-digit display will show your score, and it'll be cleared every time you lose.
The making process:
(here I moved the 7-digit display to the top side so that there's space for battery.)
We have been working on the code, which is a hybrid between two sets of codes (matrix and acceleromter). The hybridization is quite complicated, as the matrix code came with lots of unfamiliar syntax... I am posting the two sets of code separately here:
LED Matrix code:
/ Simple program to test using the Arduino with the RGB Matrix
// & Backpack from Sparkfun. Code is a combination of Heather Dewey-Hagborg,
// Arduino Forum user: Little-Scale, and // Daniel Hirschmann. Enjoy!
//
// The Backpack requires 125Khz SPI, which is the slowest rate
// at which the Arduino's hardware SPI bus can communicate at.
//
// We need to send SPI to the backpack in the following steps:
// 1) Activate ChipSelect;
// 2) Wait 500microseconds;
// 3) Transfer 64bytes @ 125KHz (1 byte for each RGB LED in the matrix);
// 4) De-activate ChipSelect;
// 5) Wait 500microseconds
// Repeat however often you like!
#define CHIPSELECT 10//ss
#define SPICLOCK 13//sck
#define DATAOUT 11//MOSI / DI
#define DATAIN 12//MISO / DO
int data[] =
//{0,0,0,0,0,0,0,0,
//0,0,1,1,0,1,1,0,
//0,1,0,0,1,0,0,1,
//0,1,0,0,0,0,0,1,
//0,0,1,0,0,0,1,0,
//0,0,0,1,0,1,0,0,
//0,0,0,0,1,0,0,0,
//0,0,0,0,0,0,0,0
//};
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
{
};
}
void setup()
{
byte clr;
pinMode(DATAOUT,OUTPUT);
pinMode(SPICLOCK,OUTPUT);
pinMode(CHIPSELECT,OUTPUT);
digitalWrite(CHIPSELECT,HIGH); //disable device
SPCR = B01010001; //SPI Registers
SPSR = SPSR & B11111110; //make sure the speed is 125KHz
/*
SPCR bits:
7: SPIEE - enables SPI interrupt when high
6: SPE - enable SPI bus when high
5: DORD - LSB first when high, MSB first when low
4: MSTR - arduino is in master mode when high, slave when low
3: CPOL - data clock idle when high if 1, idle when low if 0
2: CPHA - data on falling edge of clock when high, rising edge when low
1: SPR1 - set speed of SPI bus
0: SPR0 - set speed of SPI bus (00 is fastest @ 4MHz, 11 is slowest @ 250KHz)
*/
clr=SPSR;
clr=SPDR;
delay(10);
}
void loop()
{
delay(100);
int index = 0;
digitalWrite(CHIPSELECT,LOW); // enable the ChipSelect on the backpack
delayMicroseconds(500);
for (int i=0;i<8;i++) for (int j=0;j<8;j++)
{
spi_transfer(data[index]);
index++;
}
digitalWrite(CHIPSELECT,HIGH); // disable the ChipSelect on the backpack
delayMicroseconds(500);
}
Accelerometer code:
int pinX = 3; int pinY = 2; unsigned long serialTimer = millis(); unsigned long xAcc = 0; unsigned long yAcc = 0; boolean flipflop;
#define CHIPSELECT 10//ss#define SPICLOCK 13//sck#define DATAOUT 11//MOSI / DI#define DATAIN 12//MISO / DO int data[] ={0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; char spi_transfer(volatile char data){SPDR = data; // Start the transmissionwhile (!(SPSR & (1<<SPIF))) // Wait the end of the transmission{};} void setup(){byte clr;pinMode(DATAOUT,OUTPUT);pinMode(SPICLOCK,OUTPUT);pinMode(CHIPSELECT,OUTPUT);digitalWrite(CHIPSELECT,HIGH); //disable device SPCR = B01010001; //SPI RegistersSPSR = SPSR & B11111110; //make sure the speed is 125KHz /*SPCR bits: 7: SPIEE - enables SPI interrupt when high 6: SPE - enable SPI bus when high 5: DORD - LSB first when high, MSB first when low 4: MSTR - arduino is in master mode when high, slave when low 3: CPOL - data clock idle when high if 1, idle when low if 0 2: CPHA - data on falling edge of clock when high, rising edge when low 1: SPR1 - set speed of SPI bus 0: SPR0 - set speed of SPI bus (00 is fastest @ 4MHz, 11 is slowest @ 250KHz) */ clr=SPSR;clr=SPDR;delay(10);} void loop() { delay(100); int index = 0; digitalWrite(CHIPSELECT,LOW); // enable the ChipSelect on the backpack delayMicroseconds(500); for (int i=0;i<8;i++) for (int j=0;j<8;j++) { spi_transfer(data[index]); index++; } digitalWrite(CHIPSELECT,HIGH); // disable the ChipSelect on the backpack delayMicroseconds(500);}
We used the method and code that we found on the website HERE.
After tinkering for a while, we successfully made the LED matrix lit up and displaying some messages, but it's not behaving the same way as on the website. Instead of showing only the message, the whole matrix lights up --- we are not sure if it's the problem with the code or wiring. We're posting the code here so if anyone's interested or has an idea please let us know. And the pictures will be coming in an hour or so.
The code we downloaded from www.oomlout.co.uk:
/* * Example Code for an 8 x 8 LED Matrix * For More Details Visit http://www.tinyurl.com/yhwxv6h * * Scrolls a message across an 8 x 8 LED Matrix * To adjust the speed change the variable speed. * The message is held in requestString[] */
int speed = 20; //number of times to repeat each frame int pauseDelay = 500; //microseconds to leave each row on before moving to the next
char requestString[] = " THIS IS A MESSAGE "; //The string to display //to change the message in code you right yourself simply //change this data and reset index and offset to 0 //Variables used for scrolling (both start at 0 int index = 0; //this is the current charachter in the string being displayed int offset = 0; //this is how many columns it is offset by
//Pin Definitions int rowA[] = {9,8,7,6,5,4,3,2}; //An Array defining which pin each row is attached to //(rows are common anode (drive HIGH)) int colA[] = {17,16,15,14,13,12,11,10}; //An Array defining which pin each column is attached to //(columns are common cathode (drive LOW))
//Constants defining each charachters position in an array of integer arrays //Letters const int A = 0; const int B = 1; const int C = 2; const int D = 3; const int E = 4; const int F = 5; const int G = 6; const int H = 7; const int I = 8; const int J = 9; const int K = 10; const int L =11; const int M = 12; const int N = 13; const int O = 14; const int P = 15; const int Q =16; const int R = 17; const int S = 18; const int T = 19; const int U = 20; const int V =21; const int W = 22; const int X = 23; const int Y = 24; const int Z = 25;
//Punctuation const int COL =26; const int DASH = 27; const int BRA2 = 28; const int _ = 29; const int LINE = 34; const int DOT =36;
//Extra Charchters
const int SMILE =35; const int COLDOT = 36;
//The array used to hold a bitmap of the display //(if you wish to do something other than scrolling marque change the data in this //variable then display) byte data[] = {0,0,0,0,0,0,0,0};
//The alphabet //Each Charachter is an 8 x 7 bitmap where 1 is on and 0 if off const int _A[] = {B0001000, B0010100, B0100010, B1000001, B1111111, B1000001, B1000001, B0000000};
//Load the bitmap charachters into an array (each charachters position corresponds to its previously defined index (ie _A (a's bitmap) //is at index 0 and A = 0 so letters[A] will return the 'A' bitmap) const int* letters[] = {_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P,_Q,_R,_S,_T,_U,_V,_W,_X,_Y,_Z,_COL,_DASH,_BRA2,__, _FULL, _CHECK, _A3, _TEMP, _LINE, _SMILE, _DOT, _COLDOT};
//Setup runs once when power is applied void setup() { for(int i = 0; i <8; i++){ //Set the 16 pins used to control the array as OUTPUTs pinMode(rowA[i], OUTPUT); pinMode(colA[i], OUTPUT); } }
//An array holding the powers of 2 these are used as bit masks when calculating what to display const int powers[] = {1,2,4,8,16,32,64,128};
//Loads the current scroll state frame into the data[] display array void loadSprite(){ int currentChar = getChar(requestString[index]); int nextChar = getChar(requestString[index+1]);
for(int row=0; row < 8; row++){ //iterate through each row data[row] = 0; //reset the row we're working on for(int column=0; column < 8; column++){ //iterate through each column data[row] = data[row] + ((powers[column] & (letters[currentChar][row] << offset))); //loads the current charachter offset by offset pixels data[row] = data[row] + (powers[column] & (letters[nextChar][row] >> (8-offset) )); //loads the next charachter offset by offset pixels } } offset++; //increment the offset by one row if(offset==8){offset = 0; index++; if(index==sizeof(requestString)-2){index=0;}} //if offset is 8 load the next charachter pair for the next time through }
void showSprite(int speed2){ for(int iii = 0; iii < speed2; iii++){ //show the current frame speed2 times for(int column = 0; column < 8; column++){ //iterate through each column for(int i = 0; i < 8; i++){ digitalWrite(rowA[i], LOW); //turn off all row pins } for(int i = 0; i < 8; i++){ //Set only the one pin if(i == column){ digitalWrite(colA[i], LOW);} //turns the current row on else{ digitalWrite(colA[i], HIGH); }//turns the rest of the rows off }
for(int row = 0; row < 8; row++){ //iterate through each pixel in the current column int bit = (data[column] >> row) & 1; if(bit == 1){ digitalWrite(rowA[row], HIGH); //if the bit in the data array is set turn the LED on }
} delayMicroseconds(pauseDelay); //leave the column on for pauseDelay microseconds (too high a delay causes flicker) } } }
//returns the index of a given charachter //for converting from a string to a lookup in our array of charachter bitmaps int getChar(char charachter){ int returnValue = Z; switch(charachter){ case 'A': returnValue = A; break; case 'a': returnValue = A; break; case 'B': returnValue = B; break; case 'b': returnValue = B; break; case 'C': returnValue = C; break; case 'c': returnValue = C; break; case 'D': returnValue = D; break; case 'd': returnValue = D; break; case 'E': returnValue = E; break; case 'e': returnValue = E; break; case 'F': returnValue = F; break; case 'f': returnValue = F; break; case 'G': returnValue = G; break; case 'g': returnValue = G; break; case 'H': returnValue = H; break; case 'h': returnValue = H; break; case 'I': returnValue = I; break; case 'i': returnValue = I; break; case 'J': returnValue = J; break; case 'j': returnValue = J; break; case 'K': returnValue = K; break; case 'k': returnValue = K; break; case 'L': returnValue = L; break; case 'l': returnValue = L; break; case 'M': returnValue = M; break; case 'm': returnValue = M; break; case 'N': returnValue = N; break; case 'n': returnValue = N; break; case 'O': returnValue = O; break; case 'o': returnValue = O; break; case 'P': returnValue = P; break; case 'p': returnValue = P; break; case 'Q': returnValue = Q; break; case 'q': returnValue = Q; break; case 'R': returnValue = R; break; case 'r': returnValue = R; break; case 'S': returnValue = S; break; case 's': returnValue = S; break; case 'T': returnValue = T; break; case 't': returnValue = T; break; case 'U': returnValue = U; break; case 'u': returnValue = U; break; case 'V': returnValue = V; break; case 'v': returnValue = V; break; case 'W': returnValue = W; break; case 'w': returnValue = W; break; case 'X': returnValue = X; break; case 'x': returnValue = X; break; case 'Y': returnValue = Y; break; case 'y': returnValue = Y; break; case 'Z': returnValue = Z; break; case 'z': returnValue = Z; break; case ' ': returnValue = _; break; case '3': returnValue = A3; break; // case '<': returnValue = TEMP; break; // case '*': returnValue = FULL; break; case '|': returnValue = LINE; break; case '_': returnValue = _; break; case ':': returnValue = COL; break; case '-': returnValue = DASH; break; case ')': returnValue = BRA2; break; case '%': returnValue = SMILE; break; case '.': returnValue = DOT; break; case '^': returnValue = COLDOT; break; } return returnValue; }
I thought of how I could create an LED Flute and make the sensors light the individual leds...
Second
I thought how cute would an LED ring be... and thought I could use our human connection to light the LED. I have also decided that I am going to work on this project for this week. I think it would be interesting to see how I can make this more interesting in its aesthetic design and if I can use different materials.
Recent Comments