Slackline for KulturSydhavn

Interactive balance installation

I did a small interactive slackline project for KulturSYDHavn. A festival on the quay of Teglholmen and around the Illutron barge in conjunction with the annual KulturHavn festival on Islands Brygge on the 6, 7 and 8th of August. We created an interactive playground around the barge and together with Illutron I put up the slackline with RGB color feedback on the quay. I owe a great thanks to the Illutron crew who put a lot of energy into this festival, especially Troels Just Christoffersen who helped put the last pieces of the slackline installation up while I was gone in the week preceeding the festival. And I owe a thanks to the sponsors who made it possible, Slackline.dk and Rullegræsset.dk who sponsored a free feet slacklight15 kit and 1 metric ton of roll out grass respectively.

## Documentation The slackline is hooked up to a strain gauge that measures the weight on the slackline. An Op-Amp amplifies the signal for the arduino and two pieces of flexible high intensity RGB led strip are controlled with PWM via a ULN2003 Darlington transistor array.
Schematics
Code
// KulturSYDHavn Illutron Interactive slackline code by Johan Bichel Lindegaard float h; int h_int; int r=0, g=0, b=0, intensity=100; void h2rgb(float h, int &R, int &G, int &B); // Select which analog input the strain gauge is connected to. const int mPin = 0; int m = 0; int state = 0; // 0: inactive, 1: active, 3: pending inactive int deactivationThreshold = 8; int deactivationTime = 1000; unsigned long stateTimeStamp; unsigned long stateTime = 0; // Select which PWM-capable pins are to be used. const int redPin = 10; const int greenPin = 11; const int bluePin = 9; long brbgPreviousMillis = 0; long fadePreviousMillis = 0; boolean blinkState = 0; boolean fadeUp = 0; // range calibration variables. int lowPoint; int highPoint; void setup() { // start serial port at 9600 bps: // Serial.begin(9600); pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); // calibrate lowPoint = analogRead(mPin); highPoint = lowPoint + 124; if(highPoint > 1024) { highPoint = 1024; } // test pins rgb(255,0 ,0 ); delay(500); rgb(0 ,255,0 ); delay(500); rgb(0 ,0 ,255); delay(500); } void loop() { int m = analogRead(mPin); // Check calibration, and expand range if needed. if(m < lowPoint) { lowPoint = m; } else if(m > highPoint) { highPoint = m; } // Serial.println(m); // keep track of how long the line has been active and inactive if(m > lowPoint + deactivationThreshold) { if(state == 0) { state = 1; stateTimeStamp = millis(); } stateTime = millis() - stateTimeStamp; } else if(state == 1){ state = 3; stateTimeStamp = millis(); } else { stateTime = millis() - stateTimeStamp; if(stateTime > deactivationTime) { state = 0; } } if(state != 0){ // Convert input to RGB through hue then output. h = ((float)map(m, lowPoint, highPoint, 1024, 0))/1024; h_int = (int) 360*h; h2rgb(h,r,g,b); // if active for a short while enter fancy blink mode then return to normal if(stateTime > 15000 && stateTime < 60000) { int btime = map(stateTime,15000,60000,1000,50); brgb(r,g,b,btime); } else { rgb(r,g,b); } } else { unsigned long currentMillis = millis(); if(currentMillis - fadePreviousMillis > 100) { fadePreviousMillis = currentMillis; if(intensity > 99) { fadeUp = false; } else if (intensity < 1) { fadeUp = true; } if(fadeUp) { ++intensity; } else { --intensity; } rgb(255,0,0,intensity); } } } void rgb(int r, int g, int b) { analogWrite(redPin,r); analogWrite(greenPin,g); analogWrite(bluePin,b); } void rgb(int r, int g, int b, float intensity) { if(intensity > 100) { intensity = 100; } else if(intensity < 0){ intensity = 0; } rgb(r/100*intensity, g/100*intensity, b/100*intensity); } void brgb(int r, int g, int b, int interval) { unsigned long currentMillis = millis(); if(currentMillis - brbgPreviousMillis > interval) { brbgPreviousMillis = currentMillis; if (!blinkState) { blinkState = 1; rgb(r,g,b); } else { blinkState = 0; rgb(0,0,0); } } } void h2rgb(float H, int& R, int& G, int& B) { int var_i; float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b; if ( S == 0 ) //HSV values = 0 √∑ 1 { R = V * 255; G = V * 255; B = V * 255; } else { var_h = H * 6; if ( var_h == 6 ) var_h = 0; //H must be < 1 var_i = int( var_h ) ; //Or ... var_i = floor( var_h ) var_1 = V * ( 1 - S ); var_2 = V * ( 1 - S * ( var_h - var_i ) ); var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) ); if ( var_i == 0 ) { var_r = V ; var_g = var_3 ; var_b = var_1 ; } else if ( var_i == 1 ) { var_r = var_2 ; var_g = V ; var_b = var_1 ; } else if ( var_i == 2 ) { var_r = var_1 ; var_g = V ; var_b = var_3 ; } else if ( var_i == 3 ) { var_r = var_1 ; var_g = var_2 ; var_b = V ; } else if ( var_i == 4 ) { var_r = var_3 ; var_g = var_1 ; var_b = V ; } else { var_r = V ; var_g = var_1 ; var_b = var_2 ; } R = (1-var_r) * 255; //RGB results = 0 √∑ 255 G = (1-var_g) * 255; B = (1-var_b) * 255; } }