Arduino Prototyping
...
시간: <2011-10-17 월>
(defun org-xor (a b) "Exclusive or." (if a (not b) b))
준비물
- 아두이노 : http://arduino.cc
- LED 1개
- 코인 건전지
- 모터 1개
- Python 2.7.2 http://www.python.org/download/
- Pyserial-2.5.win32.exe http://pypi.python.org/pypi/pyserial
맥사용자는 pyserial-2.5.tar.gz 을 다운로드 받아 압축을 풀고 압축 푼 폴더에서 들어갑니다. 그 폴더의 터미널에서 python setup.py install 을 실행하여 설치해 주세요.
$ tar xvfz pyserial-2.5.tar.gz $ cd pyserial-2.5 $ sudo python setup.py install
피지컬 컴퓨팅?
피지컬 컴퓨팅 (물질의 계산?)
물질이 가지는 에너지도 미디어다!
전기 에너지는 여러 에너지를 상호 변환할 수 있는 에너지이다. 일종의 유니버설 에너지. 전기 에너지는 에너지계의 로제타석 이다.
그래서 전기를 컴퓨팅하는 마이크로 콘트롤러(예를 들어 아두이노)를 이용하면 물리적인 에너지도 컴퓨팅 할 수 있게 된다.
인터렉티션 정의
상호간에 듣고, 생각하고, 대답하는 과정. –크리스 크랙포드 (게임프로그래머)
모든 피지컬 컴퓨팅 프로젝트는 역시 '듣기, 생각하기, 대답하기'로 나눌 수 있다. 컴퓨터 용어로 입력, 프로세싱, 출력
해보기
- 미디어 아트 프로젝트를 선택하여 입력, 프로세싱, 출력으로 구분해서 분석해보자!
1. LED와 전원
LED와 전원(코인건전지 3V)을 연결해보자. LED는 전기 에너지를 빛에너지로 바꾸는 소자이다.
해보기:
- 질문: LED와 건전지를 연결하여 불이 켜질때, 입력은 무엇이고, 출력은 무엇이고, 프로세싱은 무엇일까?
2. LED와 USB전원
- 아두이노의 전원으로 사용해보자.
- 질문: LED를 5V(+), GND(-) 에 연결하면 잘 동작할까요? (가정-결과관찰-비교-학습)
3. 아두이노에서 LED켜기 (입력)
LED의 +를 아두이노의 D13번에 연결 합시다! 전에 LED 터뜨리셨으면 어쩔 수 없습니다! 앞으로 머리속에서 불을 키는겁니다. ㅎㅎㅎㅎ (H 옆에 LED 보이시죠? 이 LED는 D13에 연결되어 있는 LED 입니다.)
그리고 아래의 코드를 아두이노에 프로그래밍 하자.
준비물
- Arduino IDE 다운로드: http://arduino.cc/en/Main/Software
LED 켜기
int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
digitalWrite(ledPin, HIGH);
delay(1000);
}
해보기:
- LED를 1초에 한번씩 깜빡이도록 만드세요!
힌트: 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를 켜보기에서 '프로세싱' 에 해당하는 것은 무엇일까요?
4. 모터 (출력)
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);
}
}
해보기
- 모터를 연결하여 동작이 잘되다 멈추지 않나요? 왜 잘 동작 안될까요? 그 이유를 생각해보세요. 힌트: 에너지 보존 법칙!
5. 빛센서로 LED 제어
버튼 대신 빛센서를 사용하여 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);
}
}
해보기:
- 마이크와 연결해보자. 마이크의 핀번호는 0번이다. analogRead(0);
- 슬라이더의 핀번호는 2번 이다. 슬라이더를 사용하여 LED를 제어 해보자.
6. 컴퓨터와 아두이노 사이의 통신
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);
}
}
}
해보기:
- 아두이노의 시리얼 모니터에서 1 또는 0의 숫자를 입력한다. 어떻게 될지 예상해보자.
- pyserial을 설치하고, 파이썬 인터프리터에서 다음과 같이 입력해보자. 어떻게 될지 예상해보자.
\\ 시리얼포트의 이름: 코드의 '/dev/ttyUSB0' 는 시리얼포트의 이름으로 플래폼 마다 다르다. 윈도우는 'com1' 이런식이고, 맥은 '/dev/tty.usbserial-AXXXX' 이런식이다. 자신의 플랫폼에 맞추어 시리얼 포트의 이름을 바꾸자.
>>> import serial
>>> s = serial.Serial('/dev/ttyUSB0')
>>> s.write('1')
1
>>> s.write('0')
1
>>>
GUI 스위치 만들기
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()
일상에서 유용한 장치 만들기
트위터와 연결
- Tweepy 설치: https://github.com/joshthecoder/tweepy
- Tweepy 사용법: http://packages.python.org/tweepy/html/index.html
- OAuth 클라이언트 등록: http://twitter.com/oauth_clients
7. 물이 다 끓면 트윗!
사이커피 트위터: http://twitter.com/#!/BYTT2
물이 다 끓면 사이커피 트위터에 트윗이 됩니다!
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!'
해보기
- 이 예제를 응용하여, 일상을 풍요롭게 할 수 장치에 대한 아이디어를 내보자! 짝과 이야기 나눠 보세요.
8. 트위터 메시지로 LED 켜기.
트위터에서 #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)