Title
Landmark of Seoul (2017)
Description
Lotte World Tower, Dongdaemoon Design Plaza, 63 Building – Did we should make our city’s identity by constructing buildings?
Landmark of Seoul is an interactive artwork which is controlled by Arduino UNO. It gives the massage that because Seoul, Korea has a beautiful landmark of nature like Hangang(Han river), Bukhansan(Mt.Bukhan), and Inwangsan(Mt.Inwang), it is more important to take care those nature resources before build something. By swiping buildings themselves, users could experience this intention.
I connect arduino and processing making to communicate information of users interaction with controller. A real-time send&receive process is very important to use projection mapping technique. The core component, gears, is made by 3D printer and body consisted of foam board as a prototype.
Video
Background Story
Seoul has two important environments – river & mountain. Even though there are some cities which have their one nature resources in the worldwide, this is still very unique landscape of city surrounded by mountains with big river. So I think maybe we, Seoul doesn’t have to build ‘landscape’ artificially that already have.
After than, I found out that buildings of city cover up these nature so that people almost cannot appreciate it. The idea of ‘swiping a buildings’ started from this.
To express my idea, I planed physical computing artwork. Arduino, processing and even 3D printer was needed.
What is most urgent in this project is physical constitution. The controller should bear user’s hand pressure to protect sensor.
To make the gears, I used SketchUp 2017. After designed a teeth of gears to be matched each other exactly, I printed out them by using 3D printer.
I should adjust very detail of gear while printing it again and again :
https://vvansite.wordpress.com/2017/12/03/interactiveart_project-progress1/
Potentiometer is for adjusting resistance from 0 to 1023, but I used this principle as a ‘position value’. If users move cover, potentiometer will rotate and send value to arduino. Processing use this value as a position of cover to know how many move ‘building images’.
360 degree servo motor will move back the cover to first position. The reason why I made this process is for convenience of users. If there is no automatic return system, people would be hard to know what should they do after finishing move the cover.
I lost my arduino because of ignorance of motor driver & power : https://vvansite.wordpress.com/2017/12/10/interactiveart_project-progress2/
Ultrasonic sensor detects whether there are people or not. I want to give a little hint to users like ‘You can do something with this controller’ only just by coming near enough. So images will be changed according to user’s existence.
Code
Processing
/***Final Project for Interactive Arts***/ /***Wanho Kim***/ import processing.serial.*; Serial arduino; PImage[] backgroundImage = new PImage [3]; PImage[] buildings = new PImage[9]; PImage[] imageText = new PImage[3]; PImage title; int empty, titleTint, imageTrans, imageTint, backgroundImageNum, leftCover, rightCover, sensor, watingTime; float imageWidth, imageHeight, imageWidthVal, imageHeightVal; boolean people = false, openBuilding = false, endAnimation = false; void setup(){ size(1394, 415); println("Available serial ports:"); arduino = new Serial(this, Serial.list()[1], 9600); backgroundImageNum = 0; watingTime = 0; imageWidth = 2400; imageHeight = 1300; imageWidthVal = 72; imageHeightVal = 39; imageTint = 0; imageTrans = -30; titleTint = 255; empty = 0; for(int i = 0; i < 3; i++){ backgroundImage[i] = loadImage("backgroundImage" + i + ".jpg"); } for(int i = 0; i < 9; i++){ buildings[i] = loadImage("building" + i + ".png"); } for(int i = 0; i < 3; i++){ imageText[i] = loadImage("imageText" + i + ".png"); } title = loadImage("title.png"); } void draw(){ background(255); pushMatrix(); translate(width/2, height/2); imageMode(CENTER); image(backgroundImage[backgroundImageNum], 0, -140, imageWidth, imageHeight); imageMode(CORNER); popMatrix(); println(); if(openBuilding == false){ //leftImages pushMatrix(); translate(-leftCover/2+20, 0); scale(0.7); image(buildings[0], 825 - leftCover/2, 20); image(buildings[4], 233 + leftCover/5, -50); image(buildings[5], -60, -48); image(buildings[6], 400 - leftCover, 81); image(buildings[1], 55 + leftCover/3, -139); popMatrix(); //rightImages pushMatrix(); translate(rightCover/2-80, 20); scale(0.7); image(buildings[7], 1562 + rightCover/4, -106); image(buildings[8], 1166, 140); image(buildings[3], 1600 - rightCover/5, 143); image(buildings[2], 526 + rightCover/2, -132); popMatrix(); } if(leftCover >= 930 && rightCover >= 930){ openBuilding = true; }else if(openBuilding == true && leftCover < 900 && rightCover < 900){ watingTime = 0; imageWidth = 2400; imageHeight = 1300; imageTint = 0; imageTrans = -30; backgroundImageNum = int(random(0, 3)); openBuilding = false; endAnimation = false; titleTint = 0; } if(openBuilding){ watingTime += 1; if(watingTime >= 50){ if(imageWidth > 1590){ imageWidth -= imageWidthVal; imageHeight -= imageHeightVal; if(imageWidth <= 1590){ endAnimation = true; } } } } if(endAnimation == true){ tint(255, imageTint); if(backgroundImageNum == 0){ image(imageText[0], 0, imageTrans); }else if(backgroundImageNum == 1){ image(imageText[1], 0, imageTrans); }else if(backgroundImageNum == 2){ image(imageText[2], 0, imageTrans); } imageTint += 15; if(imageTrans < 0){ imageTrans += 2; } noTint(); } if( arduino.available() > 0 ){ while( arduino.available() > 0 ){ String str = arduino.readStringUntil('\n'); if( str != null ){ String[] vals = split( str, ' ' ); if( vals.length == 3 ){ leftCover = int(trim(vals[0])); rightCover = int(trim(vals[1])); sensor = int(trim(vals[2])); println( leftCover, rightCover, sensor); } } } } if(sensor <= 50){ people = true; empty = 0; }else if(sensor > 120){ if(empty < 60){empty += 1;} if(empty >= 60){ people = false; } } if(people && titleTint >= -100){ titleTint -= 30; }else if(!people && titleTint <= 255){titleTint += 30;} tint(255, titleTint); image(title, 0, -20); noTint(); }
Arduino
/***Final Project for Interactive Arts***/ /***Wanho Kim***/ #include <Servo.h> Servo servoMotor2, servoMotor1; int servoMotor2_num = 10, servoMotor1_num = 9; int potentio1 = 1, potentio2 = 2; int servoMotor2_count1, servoMotor2_count2, servoMotor2_count3, watingTime; boolean moveRightCover; const int trig = 2; const int echo = 3; long duration, distance; void setup() { Serial.begin(9600); servoMotor2.attach(servoMotor2_num); servoMotor1.attach(servoMotor1_num); servoMotor2_count1 = 0; servoMotor2_count2 = 0; servoMotor2_count3 = 0; watingTime = 0; moveRightCover = false; pinMode(trig, OUTPUT); pinMode(echo, INPUT); } void loop() { digitalWrite(trig, LOW); delayMicroseconds(5); digitalWrite(trig, HIGH); delayMicroseconds(5); digitalWrite(trig, LOW); duration = pulseIn(echo, HIGH); distance = duration/29/2; delay(35); int rightCover = analogRead(potentio1); int leftCover = analogRead(potentio2); int posRightCover = rightCover; int posLeftCover = leftCover; Serial.print(leftCover); Serial.print(" "); Serial.print(rightCover); Serial.print(" "); Serial.println(distance); if(posRightCover >= 930 && posLeftCover >= 930){ moveRightCover = true; } if(moveRightCover){ watingTime += 1; if(servoMotor2_count1 < 43 && watingTime >= 130){ servoMotor2.write(178); servoMotor1.write(15); servoMotor2_count1 += 1; delay(1); } else if(servoMotor2_count1 >= 43 && servoMotor2_count3 < 35){ servoMotor2.write(80); servoMotor1.write(128); servoMotor2_count3 += 1; watingTime = 0; delay(1); } else { servoMotor2.write(102); servoMotor1.write(98); moveRightCover = false; delay(1); } } else{ servoMotor2.write(102); servoMotor1.write(98); servoMotor2_count1 = 0; servoMotor2_count2 = 0; servoMotor2_count3 = 0; delay(1); } }