문지문화원
시간: <2011-04-28 수>
http://tinyurl.com/bytt-physicalcomp
$ tar xvfz pyserial-2.5.tar.gz $ cd pyserial-2.5 $ sudo python setup.py install
피지컬 컴퓨팅 (물질의 계산?)
전기 에너지는 여러 에너지를 상호 변환할 수 있는 에너지이다. 일종의 유니버설 에너지. 전기 에너지는 에너지계의 로제타석 이다.
그래서 전기를 컴퓨팅하는 마이크로 콘트롤러(예를 들어 아두이노)를 이용하면 물리적인 에너지도 컴퓨팅 할 수 있게 된다.
상호간에 듣고, 생각하고, 대답하는 과정. –크리스 크랙포드 (게임프로그래머)
모든 피지컬 컴퓨팅 프로젝트는 역시 '듣기, 생각하기, 대답하기'로 나눌 수 있다. 컴퓨터 용어로 입력, 프로세싱, 출력
LED와 전원(코인건전지 9V)을 연결해보자. LED는 전기 에너지를 빛에너지로 바꾸는 소자이다.
LED의 +를 헬로보드의 D13번에 연결 합시다! 전에 LED 터뜨리셨으면 어쩔 수 없습니다! 앞으로 머리속에서 불을 키는겁니다. ㅎㅎㅎㅎ (H 옆에 LED 보이시죠? 이 LED는 D13에 연결되어 있는 LED 입니다.)
그리고 아래의 코드를 헬로보드에 프로그래밍 하자.
int ledPin = 13; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); }
힌트: digitalWrite(ledPin, LOW);
우리는 프로그래밍을 통해 물리적 스위치 없이도 LED를 제어할 수 있습니다 (controlable). 프로그램의 무한루프는 장치가 살이 있는 것처럼 만들수 있지요 (liveness).
int buttonPin = 4; int ledPin = 13; boolean value; void setup() { pinMode(buttonPin, INPUT); pinMode(ledPin, OUTPUT); } void loop() { value = digitalRead(buttonPin); if (value == HIGH) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } }
LED대신 모터를 연결할 수 있습니다. 모터는 전기에너지를 운동에너지로 바꾸는 장치입니다. 멋지지 않습니까!! 19세기 전기공학자의 승리이지요! 아하하. 모터는 마이클 패러데이가 발명했군요. 네? 패럿이 좀 익숙하시다구요?
int buttonPin = 4; int ledPin = 13; int motorAPin = 3; int motorBPin = 5; boolean value; void setup() { pinMode(buttonPin, INPUT); pinMode(ledPin, INPUT); pinMode(motorAPin, OUTPUT); pinMode(motorBPin, OUTPUT); } void loop() { value = digitalRead(buttonPin); if (value == LOW) { digitalWrite(motorAPin, HIGH); digitalWrite(motorBPin, LOW); digitalWrite(ledPin,HIGH); } else { digitalWrite(motorAPin, LOW); digitalWrite(motorBPin, LOW); digitalWrite(ledPin,LOW); } }
버튼 대신 빛센서를 사용하여 LED를 제어 해보죠
빛센서와 마이크, 슬라이더는 아날로그 센서이다. 디지털 센서는 0(LOW) 와 1(HIGH)만 가져올 수 있지만, 아날로그 센서는 0부터 1023값까지 가져올 수 있다.
int cdsPin = 1; int ledPin = 13; int value; void setup() { pinMode(cdsPin, INPUT); pinMode(ledPin, OUTPUT); } void loop() { value = analogRead(cdsPin); if (value > 512) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } }
arduino는 컴퓨터의 USB를 통해 데이터를 주고 받을 수 있다. 이때 주고받는 통로를 시리얼 포트 라고 한다. 포트는 항구를 의미하여, 데이터를 내리고 받고 하는 곳이다. 주고 받는 데이터는 숫자다!
파이썬으로 프로그램을 버튼으로 사용하여 모터를 제어해보자
int ledPin = 13; int value; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { if (Serial.available() > 0) { value = Serial.read(); if (value == '1') { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } } }
시리얼포트의 이름: 코드의 '/dev/ttyUSB0' 는 시리얼포트의 이름으로 플래폼 마다 다르다. 윈도우는 'com1' 이런식이고,
맥은 '/dev/tty.usbserial-AXXXX' 이런식이다. 자신의 플랫폼에 맞추어 시리얼 포트의 이름을 바꾸자.
>>> import serial >>> s = serial.Serial('/dev/ttyUSB0') >>> s.write('1') 1 >>> s.write('0') 1 >>>
from Tkinter import * import sys import serial port = '/dev/ttyUSB0' # TODO: change port name speed = 9600 def send(char): ser = serial.Serial(port,speed) ser.setDTR() ser.flushInput() ser.write(char) ser.close() def toggle_switch(): if switch_button["text"] == "Turn On": send('1') switch_button["text"] = "Trun Off" else: send('0') switch_button["text"] = "Turn On" root = Tk() root.title('Switch') switch_button = Button(root, text="Turn On",command=toggle_switch) switch_button.pack() root.mainloop()
import processing.serial.*;
Serial myPort; boolean value;
void setup() { size(200, 200); String portName = Serial.list()1; myPort = new Serial(this, portName, 9600); }
void draw() { background(255); if (value == true) { // If mouse is over square, fill(204); // change color and myPort.write('1'); // send an H to indicate mouse is over square } else { // If mouse is not over square, fill(0); // change color and myPort.write('0'); // send an L otherwise } rect(50, 50, 100, 100); // Draw a square }
void mousePressed() { if (value == true) { value = false; } else { value = ture; } }
이번엔 반대로! 아두이노에서 입력을 받아서 컴퓨터에 출력을 해보자.
int switchPin = 4; void setup() { pinMode(switchPin, INPUT); Serial.begin(9600); } void loop() { if (digitalRead(switchPin) == HIGH) { Serial.print('1'); } else { Serial.print('0'); } delay(100); }
import processing.serial.*; Serial myPort; int value; void setup() { size(200, 200); String portName = Serial.list()[0]; myPort = new Serial(this, portName, 9600); } void draw() { if ( myPort.available() > 0) { // If data is available, value = myPort.read(); // read it and store it in val } if (value == '0') { // If the serial value is 0, background(0); } else { // If the serial value is not 0, backgroun(255); } } ** 해보기: - 아두이노의 버튼이 눌리면, 채워진 사각형을 그려보자.
하이퍼 텍스트 커피포트 조절 장치
http://en.wikipedia.org/wiki/Hyper_Text_Coffee_Pot_Control_Protocol
물이 다 끓면 사이커피 트위터에 트윗이 됩니다!
TODO: 연결 개념도 넣기.
int cdsPin = 3; int ledPin = 13; int value; void setup() { pinMode(cdsPin, INPUT); pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { value = analogRead(cdsPin); if (value > 700) { Serial.print('1'); digitalWrite(ledPin,HIGH); } else { Serial.print('0'); digitalWrite(ledPin,LOW); } }
버튼으로 트윗!
int ledPin = 13; int buttonPin = 4; int value; void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT); Serial.begin(9600); } void loop() { value = digitalRead(buttonPin); if (value == LOW) { Serial.print('1'); digitalWrite(ledPin,HIGH); } else { Serial.print('0'); digitalWrite(ledPin,LOW); } }
# -*- coding: utf-8 -*- import tweepy from tweepy.error import * import serial, os, random from time import localtime, strftime port = '/dev/ttyUSB0' speed = 9600 coffee = '1' def random_string(): word = '' for i in range(4): word += random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') return word def receive(): ser = serial.Serial(port,speed) ser.setDTR() ser.flushOutput() value = ser.read(1) ser.close() return value CONSUMER_KEY = 'OMzEiHX57WxDcgBmqg0vzQ' CONSUMER_SECRET = 'DdaRA8IfrVjDVr9OzxYh6vtAEHn66ECwzPWgr7Zafg' auth = tweepy.OAuthHandler(CONSUMER_KEY,CONSUMER_SECRET) print 'Authorization URL: ' + auth.get_authorization_url() token = raw_input('Token:') auth.get_access_token(token) api = tweepy.API(auth) while True: p_coffee = coffee coffee = receive() if p_coffee == '0' and coffee == '1': try: api.update_status(u'여러분, 커피가 다 되었습니다. 커피 마시러 오세요~ 장소는 문지문화원 2층 --커피봇' + random_string() + strftime(" %Y-%m-%d %H:%M:%S", localtime())) print 'update successed!' except TweepError: print 'update failed!'
트위터에서 #BYTTBOT 해쉬태그로 'On' 이라는 메시지가 포스팅하면 LED가 켜진다.
시리얼포트로 '1' 이 들어오면 LED를 깜박거립니다.
int ledPin = 13; int value; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { if (Serial.available() > 0) { value = Serial.read(); if (value == '1') { digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); digitalWrite(ledPin, HIGH); delay(500); digitalWrite(ledPin, LOW); delay(500); } } }
트위터에서 #BYTTBOT을 검색하여 그 결과 내용에 'On' 문자열이 있으면 시리얼 포트로 '1' 을 보냅니다.
import simplejson, urllib, sys, re, time import serial port = '/dev/ttyUSB0' # TODO: change port name speed = 9600 def send(char): ser = serial.Serial(port,speed) ser.setDTR() ser.flushInput() ser.write(char) ser.close() params = {'q':"#BYTTBOT"} query = urllib.urlencode(params) url = "http://search.twitter.com/search.json?%s" % query timeline = set() while True: time.sleep(0.5) results = simplejson.load(urllib.urlopen(url))['results'] for entry in results: r = re.compile(r'((www\.|(http|https|ftp|news|file)+\:\/\/)[_.a-z0-9-]+\.[a-z0-9\/_:@=.+?,##%&~-]*[^.|\'|\# |!|\(|?|,| |>|<|;|\)])',re.I|re.M) text = r.sub('<a href="\\1">\\1</a>',entry['text'].encode( "utf-8" )) r = re.compile(r'(@)+([_.a-z0-9-]+)', re.I|re.M) text = r.sub('<a href="http://twitter.com/\\2">\\1\\2</a>',text) from_user = entry['from_user'].encode( "utf-8" ) if text in timeline: continue if 'on' in text.lower(): send('1') print text else: send('0') timeline.add(text)
1 FOOTNOTE DEFINITION NOT FOUND: 0
Date: 2011-11-10 09:56:32 KST
HTML generated by org-mode 6.21b in emacs 23