놀라운 점은 한사람 뿐 아니라, 수십명이 손을 잡아서 장거리 회로를 구성해도 작동됩니다. 가장 기초적인 트랜지스터 활용예이면서 제법 재밌는 응용을 할수있는 회로입니다. 아래 회로1 상의 콜렉터(C) 점과 R1사이에 LED를 넣어주면 아두이노 없이도 LED를 On/Off 시켜볼수 있습니다. (단, R1은 330옴으로 변경요함) 아두이노에서 활용하려면 아래와 같이 연결하시면 됩니다.
회로1.이 기본회로입니다.
A와 B점을 양손으로 잡으면 트랜지스터 Base에 전류가 가해져서 C점의 전압이 강하(Low)하게됩니다. A와 B간에 결합이 없어서 트랜지스터의 Base와 Emitter간의 전류가 흐르지 않게되면 C점의 전압은 거의 5V(High)로 유지됩니다.
아날로그입력핀으로 감지하면 이값(전압)의 변화를 확인 가능하며, 디지탈입력으로 감지하면 HIGH / LOW를 구분할 수 있게 됩니다. 회로1에서 R1은 꼭 필요하지만 R2는 A와 B가 쇼트될 가능성이 있어서 보호차원에서 넣은 저항입니다. 쇼트 시킬 일이 없다면 생략해도 됩니다.
트랜지스터는 유사품(범용 NPN형)으로 대체가능합니다.
위 경우엔 2sc1815를 사용한 예입니다.
회로1의 경우 예제소스는 아두이노 스케치에서 기본제공하는 File > Examples > Analog > AnalogInOutSerial 예제를 업로딩 후, 시리얼모니터 창을 열어놓고 A,B점을 양손으로 꽉 잡아보시면 됩니다. 접촉 상태에따라 A0핀으로 입력받는 전압 값의 변화 출력됩니다.
우측의 회로2. 는 저항을 모두 생략한 상태이며 R1을 생략하고 대신 아두이노 내부 풀업저항을 활성화 시킨 상태입니다. 즉, R1 역활을 하는 내부 저항을 활용하는 방법입니다.대부분의 마이크로콘트롤러칩들은 외부저항없이도 프로그램 세팅만으로 내부 풀업저항을 설정할 수 있는 기능이 있습니다.풀업저항 활성화를 위해선 핀모드를 입력모드로 전환 후, 해당핀을 HIGH로 세팅해주면 됩니다. 내부 풀업을 활성화 시키는 코드가 포함된 예제소스는 아래와 같습니다.
// A와 B점을 손으로 잡으면 아두이노 내장 LED가 켜지고 , 놓으면 꺼집니다. void loop() { if( digitalRead(2)){ digitalWrite(ledPin, LOW); }else{ digitalWrite(ledPin, HIGH); } delay(100); }
참고로, 5V 전원을 사용하므로 손으로 잡아도 감전 될 걱정은 안하셔도 됩니다.
활용예. 잘만 활용하면 터치센서 대체용으로 활용 가능합니다. 터치센서는 한극으로 작동 되지만, 러브스위치는 두접점을 동시에 눌러야 작동되는점이 차이점입니다. TR한개만 있으면 되므로 매우 저렴한 방법입니다. 특히 사람의 몸을 통하여 회로가 구성된다는 점이 알쏭 달쏭 요상한 재미를 더해주므로 여러명이서 재밌는 이벤트를 구성할때 활용하면 좋은 소재가 될 수 있습니다.
알림. 위 회로와 소스로 테스트 결과 잘 작동됨을 확인하였습니다. 시간이 늦은 관계로 실제 이미지와 작동영상은 추후에 올리겠습니다.
본 글을 통해 최근 동영상을 통해 알려드렸던 DIY 전자악기 만드는 법을 안내해 드리고자 합니다.
하드웨어 제작은 반제품의 쉴드를 아두이노에 결합하고 스위치를 몇개 장착하는게 전부이므로 매우 쉽습니다. 하지만 프로그래밍을 통해 제어를 하려면 MIDI 프로토콜을 이해해야 하는데 인터넷에 공개된 관련 글을 봐도 곧바로 이해하고 활용하기 쉽지 않았습니다. 결국, 정확한 신호 파악을위해 직접 마스터 키보드를 구입하여;; 건반을 누를때, 뗄때, 악기가 변경될때, 기타 콘트롤시 어떤 MIDI 신호가 출력되는지 분석을 한 후에야 대충 이해가 가더군요,, 하지만 많은 분들이 그럴 여유가 없으시죠;;;
우선은 이미 제조사에서 일련의 내장된 악기음을 순서대로 반복해주는 정도의 예제가 있으므로 참고가 되실 겁니다. 하지만, 위 소스만으로는 응용이 어려우신 분들도 많으시므로 실제 스위치(건반대응)로 연결하여 기초적인 악기를 구현한 예제(연결방법 + 소스코드)를 소개드리오니 참고하시기 바랍니다. 여러분의 좀더 멋진 DIY 악기 개발에 작으나마 도움이 되었으면 합니다
추가사항. 현재 화면상의 소스코드는 Sketch 0022 버전에서 테스트된 소스입니다. 최신 아두이노 개발환경(Arduino 1.0)용 소스코드도 첨부파일에 링크되어있으니 참고하시기 바랍니다. 첨부된 파일2개는 동일한 기능 두가지 버전입니다.)
. -로보밥-
준비물
아두이노 UNO 1개 아두이노 용 USB케이블 MIDI 악기 쉴드 1개 재적측 가능한 헤더셋(아두이노용) 1세트 결합형 브레드보드 중형 4개 스위치 12개 (마이크로 스위치 , 5색칼라버튼) 점퍼케이블 1세트
하드웨어 준비
1. 재적층 가능 해더셋을 MIDI 악기쉴드에 납땜합니다. 여분의 헤더핀들을 아두이노에 결합 후 재적층 가능 헤더셋을 뒤집어 꽂은 상태로 납땜을 하면 수직(90도)상태로 납땜하기 용이해 집니다.
2. 아래의 이미지를 참고하셔서 MIDI 악기 쉴드에 아래와 같은 방식으로 스위치를 장착합니다. 버튼 3개만 보이지만 나머지 버튼들도 동일한 방법으로 연결하면 됩니다. 어떤 핀에 연결해야하는지는 소스코드에 나오는 버튼별 핀번호 정의부분을 보시면 됩니다. 싱겁게도 회로 연결 작업은 이것으로 끝입니다. ( 아직 MIDI쉴드를 아두이노에 장착하지 마세요!)
아두이노 프로그래밍 준비작업
1. 아두이노에 내장된 기존 프로그램이 장착된 하드웨어와 맞지 않는 경우에 대비하기위해 첫프로그래밍시엔 쉴드를 제거한 상태에서 프로그래밍(업로딩) 하실 것을 권장드립니다.
2. 컴파일전에 NewSoftSerial 라이브러리를 설치 하셔야합니다. 아두이노 프로그래밍 방법 및 라이브러리 설치방법등을 모르시는 분들은 아두이노 해당 기초 학습을 완료 후 시도하시기 바랍니다.
3. 소스코드를 웹화면에서 복사하여 사용시 일부 문자가 누락되는 경우가 있습니다. 하단에 링크된 첨부파일(MusicArtRobot.pde)을 다운로드 받으셔서 사용하실것을 권장드립니다.
DIY 전자 악기 ( Music Art Robot )소스코드
/* Music Art Robot v0.1(2012.Feb.4) --------------------------------------------------------- 아두이노 + MIDI악기쉴드 이용한 DIY 건반악기 예제소스 --------------------------------------------------------- https://robobob.tistory.com/ 재배포시, 위 URL 유지부탁드리고요, 자유롭게 사용해주세요! ---------------------------------------------------------
버튼1 ~ 8 : 도/레/미/파/솔/라/시/도 임의 note(음계)로 변경하시면 됩니다. 버튼9: 다른 악기 선택(현재 악기번호 + 1) 0~127 버튼10: 다른 악기 선택(현재 악기번호 - 1) 0~127 버튼11: 악기를 드럼셋으로 설정. 버튼12: defaultPatch 에 정의된 악기로 변경
외부스위치 연결방법: 버튼의 양쪽선 중 한쪽은 아두이노 해당 핀에 연결하고, 나머지 한쪽은 GND에 공통 연결하면 끝.
참고사항, 전원을 켠 후 소리가 나지않을 경우 리셋버튼을 눌러서 초기화 해주면 작동됩니다.
MIDI악기쉴드에 대한 아래의 영문정보도 참고하세요.
This code works with the VS1053 Breakout Board and controls the VS1053 in what is called Real Time MIDI mode. To get the VS1053 into RT MIDI mode, power up the VS1053 breakout board with GPIO0 tied low, GPIO1 tied high.
I use the NewSoftSerial library to send out the MIDI serial at 31250bps. This allows me to print regular messages for debugging to the terminal window. This helped me out a ton.
Attach a headphone breakout board to the VS1053: VS1053 LEFT : TSH VS1053 RIGHT : RSH VS1053 GBUF : GND
When in the drum bank (0x78), there are not different instruments, only different notes. To play the different sounds, select an instrument # like 5, then play notes 27 to 87.
To play "Sticks" (31): talkMIDI(0xB0, 0, 0x78); //Bank select: drums talkMIDI(0xC0, 5, 0); //Set instrument number //Play note on channel 1 (0x90), some note value (note), middle velocity (60): noteOn(0, 31, 60);
*/
#include <NewSoftSerial.h> #define btn1 11 // 버튼1의 아두이노 핀번호 정의 #define btn2 10 // 버튼2의 아두이노 핀번호 정의 #define btn3 9 // 버튼3의 아두이노 핀번호 정의 #define btn4 8 // 버튼4의 아두이노 핀번호 정의 #define btn5 7 // 버튼5의 아두이노 핀번호 정의 #define btn6 6 // 버튼6의 아두이노 핀번호 정의 #define btn7 5 // 버튼7의 아두이노 핀번호 정의 // 3:midi rx , 4:midi reset 아두이노 핀 3번 4번은 이미 사용중 #define btn8 2 // 버튼8의 아두이노 핀번호 정의 //(SoftSerial에서 Rx핀으로 선언되지만 재 세팅 후 버튼용으로 사용) #define btn9 A5 // 버튼9의 아두이노 핀번호 정의 #define btn10 A4 // 버튼10의 아두이노 핀번호 정의 #define btn11 A3 // 버튼11의 아두이노 핀번호 정의 #define btn12 A2 // 버튼12의 아두이노 핀번호 정의
#define defaultPatch 15 //악기 초기화 버튼 설정 악기번호
NewSoftSerial mySerial(2, 3); //SW시리얼핀 정의 D3이 MIDI신호 전송용, D2는 미사용
int patch = 0; //악기 대응, 연주될 악기 종류 (0~127: 기본 128 가지 선택가능)
int bn1 = 60; //버튼1의 note(음계) 가령 "도" 0~127까지 지정가능 (정확한 음계 설정은 MIDI관련정보참고) int bn2 = 62; //버튼2의 note(음계) 가령 "레" int bn3 = 64; //버튼3의 note(음계) 가령 "미" int bn4 = 65; //버튼4의 note(음계) 가령 "파" int bn5 = 67; //버튼5의 note(음계) 가령 "솔" int bn6 = 69; //버튼6의 note(음계) 가령 "라" int bn7 = 71; //버튼7의 note(음계) 가령 "시" int bn8 = 72; //버튼8의 note(음계) 가령 "도~"
//Send a MIDI note-on message. Like pressing a piano key //channel ranges from 0-15 void noteOn(byte channel, byte note, byte attack_velocity) { talkMIDI( (0x90 | channel), note, attack_velocity); }
//Send a MIDI note-off message. Like releasing a piano key void noteOff(byte channel, byte note, byte release_velocity) { talkMIDI( (0x80 | channel), note, release_velocity); }
//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127 void talkMIDI(byte cmd, byte data1, byte data2) { digitalWrite(ledPin, HIGH); mySerial.print(cmd, BYTE); mySerial.print(data1, BYTE);
후기 MIDI 용어문제: 관련 용어 파악이 어려운것 같습니다. 가령 악기와 대응되는 용어만 instrument, patch, program 이 있네요.
아두이노 1.0용 소스 추가 안내. 2012년 5월 30일 많은분들이 Arduino 1.0 스케치용으로 포팅된 소스를 요청하셨는데요 변환된 파일을 이제야 올려드렸습니다. 2번째 첨부파일을 참고하시기 바랍니다. 바뀐것이라곤 NewSoftSerial.h 대신 기본제공되는 시리얼 라이브러리를 사용하기위해 SoftwareSerial.h 헤더선언을 변경한것과 Serial.print( val, BYTE) 함수를 Serial.write( val ) 로 변경한것 뿐입니다. 어렵지 않으니 직접 한번 수정(포팅)해보시고 성취감을 맛보시는것도 좋으실 것 같습니다.
수개월전 실내 테스트까지만 해왔던 기상측정 트위터 로봇을 중요한 프로젝트에 활용하신다는 분께 양도 후 새로 구하지 못해서 기다려오다 최근 다시 입수하게되었습니다. ^^. 드디어 기다려왔던 실외 설치 후 실제 운영테스트를 해보게되었습니다. 눈도 오고 꽁꽁 얼어붙는 날씨인데도 아직 멀쩡히 작동하고 있습니다. 기존 스토리는 관련글 링크를 참고하시기 바랍니다.
이번엔 실외 설치를 위해 이더넷하우징 케이스에 모든 기능을 넣어버리는 시도를 하였습니다. 아두이노 보드 + 이더넷 쉴드를 이더넷일체형 아두이노보드로 변경한데 이어 관련 부품을 작은 케이스안에 넣고 UTP 케이블 단자만으로 결합이 되도록 구성하였습니다. 어떻게 하는지는 사진을 보시면 참고가 되실 것 같습니다.
다양한 MIDI 작곡 프로그램들에서 MIDI 신호 출력을 지원합니다. PC의 경우 SW적인 음원으로 연주하는것도 가능합니다만, MIDI 신호를 PC 외부에 있는 전용 사운드모듈(악기,음원모듈)로 보내서 연주시킬 수 도 있습니다. MIDI 악기 쉴드로 이 신호를 받아서 연주가 되도록 해봤습니다.
PC용 SW는 MIDI 파일을 단순 연주해주는 Sweet MIDI Player 프로그램을 사용했습니다.
물론 기타 전문가용 MIDI 작곡 프로그램도 마찬가지로 연결해서 사용이 가능합니다. 출력되는 MIDI 신호는 모두 동일합니다.
보통 마스터 키보드는 음원내장이 되지 않아 자체적으로 연주가 불가하고, 외부
사운드 모듈(SW 또는 HW)이 필요합니다. 고가의 사운드카드의 경우엔 모르겠지만 보통의 메인보드 내장형 사운드 카드로 SW 사운드 음원을 대체하여 사용한경우, 키보드로 연주시 엄청난 딜레이가 있네요... 건반을 누르고 소리가 날때까지 수백mSec 지연은 있는것 같습니다. (제경우 연주용으로 사용이 불가한 수준이라고 생각됩니다.)
하지만 MIDI 악기 쉴드에 키보드 MIDI출력 신호를 곧바로 입력시켜 연주를 해본 결과 딜레이를 느낄 수 없었습니다. 고품질의 음원이 필수적이지 않다면 MIDI 악기 쉴드를 외장 악기음원(Sound Module)로 활용하는것도 좋을것 같습니다.
오늘은 귀가 즐거운 녀석을 소개해드리겠습니다. 이녀석을 아두이노 호환보드들에 장착하면 MP3 player 기능 구현이 가능하며, wma, wav, midi 포멧도 지원합니다.
완성도 높은 하드웨어 휴대용 mp3와 같은 조그셔틀 버튼과 음량버튼이 내장되어있고 ipod dock에 장착할수있는 포트도 내장되어있습니다. 게다가 헤드폰단자외에 마이크입력단자도 제공됩니다. 오호~ 녹음도 되냐고요??? 네, 가능합니다. 하지만 ATmega1280이나 2560 급 보드에서만 가능하답니다. 즉, 일반 아두이노 UNO보드는 안되고 Mega2560 보드에서 가능합니다. 그리고, DIY 창작을 하는 여러분들에게는 하드웨어만 좋아서는 안되겠죠!
오픈소스(Open Source) 본 제품을 위한 player 구현 소스코드가 공개되어 있으므로 마음대로 모든 기능을 계량 or 해킹이 가능하다는것이 가장 마음에 드는 점입니다.
첨부파일 제조사 wiki 페이지 링크가 문제일경우 첨부된 소스코드 파일을 참고하시기 바랍니다.
이번엔 기상측정기구와 이더넷 쉴드가 장착된 아두이노(Arduino)로 기상관측 자료를 트위터(Twitter)에 자동으로 올려주는 기특한 녀석을 소개시켜 드리겠습니다. 제법 시스템이라 불릴 만한 구성입니다. 바람의 방향과 속도 및 강수량을 측정할 수 있는 기상관측 기구로 부터 측정된 값을 모니터링하고 이를 곧바로 인터넷을 통해 트위터(twitter)에 올리는 것입니다. 기상 데이타 측정용으로 사용된
가상 관측기기에 대해선 관련글 링크
를 참고하시기 바랍니다.
본 글을 이해하기위해 필요한 사전지식: 기본적인 아두이노 스케치 개발환경 사용법, 라이브러리 설치법, 이더넷쉴드 사용경험, 트위터의 기본적인 이해, 기상관측 기구 센싱방법 등
트위터? 트위터(Twitter)가 뭔지는 저보다 여러분이 더 잘 알고 계실것 같습니다. 제경우 트위터 사용법도 잘 모릅니다만 순서가 뒤바껴서 트위터 포스팅해주는 로봇을 먼저 만들게 되었습니다;;; 이글을 이해하시려면 일단 트위터에 가입하셔서 트위(Tweet) 하나를 올려보시면 됩니다.
아두이노 + 이더넷 쉴드 썰렁한 아두이노(Arduino) 보드에 이더넷 쉴드를 얹으면 인터넷을 통해 전세계와 의사소통이 가능합니다. 더불어 천재적이면서 친절하기까지 하신 분들이 아두이노로 트위터에 메시지를 보내는 예제와 라이브러리를 공개해 주셨으므로 저와 여러분들은 손쉽게 엄청난?;; 시스템 구현을 할 수 있는 상황입니다. 이더넷 쉴드 사용 경험이 없으신 분들은 우선 공개된 정보와 아두이노 스케치IDE에 포한된 기본 예제를 참고하시기 바랍니다.
아두이노 + 이더넷 쉴드의 한계 이더넷 쉴드를 장착하면 아두이노 보드로 정보서비스를 제공해주는 서버 역활을 할 수 있습니다. 외부 접속이 가능한 IP주소를 사용한다면 전세계의 인터넷 접속가능 기기를 통해 정보를 제공받을 수 있습니다. 하지만 동시 접속수 제한이나 퍼포먼스 문제로 원할한 서비스 제공에는 한계가 있습니다. 이때문에 아두이노를 데이타 센싱이 용이한 현장에 설치 후 취합한 데이타를 웹서비스를 담당하는 PC급 서버로 전달하여 제대로된 웹서비스 환경에 응용하는 것이 더 안정적인 방법일 수 있습니다.
이때 손쉽게 사용가능한 서비스가 HTTP Client입니다. 즉, 아두이노는 웹클라이언트로써 웹서버에 필요할 때만 접속하여 데이타를 송/수신 하는 방식입니다. 이더넷 라이브러리와 함께 제공되는 기본예제(WebClient)를 조금만 수정하면 활용이 가능합니다. IP주소로 접속이 가능한 웹서버가 있는경우 추천할만한 방법입니다. 다만 문제는 기본 이더넷 쉴드 라이브러리를 이용한 Web Client 로는 domain name ( http://robobob.co.kr 같은) 을 통한 서버 접속이 안되고 123.123.123.123 같은 숫자형식의 ip를 이용한 접속만 가능하다는 점입니다. 예전에는 ip주로를 통한 접속 주소를 지원하는 웹호스팅 서비스가 있었지만 요즘엔 이를 지원하지 않는곳이 대부분인것 같습니다. 때문에 특정 웹호스팅 서비스나 단독 호스팅서비스를 사용하지 않으면 Web Client 사용한 접속이 불가한 상황입니다. (일반적인 URL 주소를 통한 아두이노의 HTTP Client 접속 방법을 아시는 분은 안내 부탁드립니다.)
트위터 활용 HTTP Client 활용에 문제가 있으나 오히려 더 효과적일 수 있는 데이타 공유 방법이 있으니 바로 트위터입니다. 짧은 단문을 포스팅하면 수많은 팔로워에게 전달되는 효과적인 데이타 공유시스템을 활용하는 것입니다. 게다가 요즘 대세인 스마트폰에서도 손쉽게 접근이 가능한 최신병기입니다. 그런데 방법이 어렵냐고요??? 제가 해보니 생각보다 매우 간단했습니다. 트위터 엡 개발을 위해 API니 뭐니 습득하고 복잡한 절차가 필요한지 알았는데요, 그게 아니고 그냥 사용만 하면 되네요...
별 설명이 필요없습니다만, 정리하자면 아래와 같습니다. 1. 트위터 앱(O Auth)에 접속하여 승인을 해주면 복잡한 문자열로 된 토큰 정보가 생성됩니다. 이 값을 복사하여 잘 보관합니다. 2. 관련 라이브러리들을 설치해줍니다. 두군데 정도 접속하여 파일을 받아서 아두이노 library 폴더에 적절한 이름으로 복사합니다. 3. 예제소스를 실행해봅니다. 위 라이브러리를 제대로 설치하면 스케치 IDE Examples 리스트에 Twitter가 생깁니다. File menu > Examples > Twitter > SimplePost 예제를 선택해줍니다.
이더넷 쉴드 사용시 수정해주는 ip주소와 네트웍정보 몇개만 수정해주시고 추가로 "YOUR-TOKEN-HERE" 부분을 위에서 발급받은 토큰값으로 대체해 주면 준비 끝~ 입니다. 이젠 잘 전송되는지 확인을 위해 시리얼 모니터링 창을 열고 속도(9600)를 맞쳐줍니다.
SimplePost 예제 소스 내용보기
#if defined(ARDUINO) && ARDUINO > 18 // Arduino 0019 or later #include <SPI.h> #endif #include <Ethernet.h> #include <EthernetDNS.h> #include <Twitter.h>
// Ethernet Shield Settings // 쉴드 밑면에 있는 mac 정보를 적어줍니다. 쉴드가 하나인경우 안바꿔도 무방 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// substitute an address on your own network here byte ip[] = { 192, 168, 2, 250 }; //공유기에서 사용되지않는 IP값을 지정
// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/) Twitter twitter("YOUR-TOKEN-HERE"); // 발급받은 토큰값을 이곳에 붙여넣으세요
// Message to post char msg[] = "Hello, World! I'm Arduino!"; // 한글 전송도 가능합니다!
Serial.println("connecting ..."); //부팅시 1회 포스팅 시도합니다. if (twitter.post(msg)) { // Specify &Serial to output received response to Serial. // If no output is required, you can just omit the argument, e.g. // int status = twitter.wait(); int status = twitter.wait(&Serial); if (status == 200) { Serial.println("OK."); } else { Serial.print("failed : code "); Serial.println(status); } } else { Serial.println("connection failed."); } }
void loop() { //아무것도 안합니다. }
SimplePost 예제 소개 예제로 사용된 소스에는 아두이노가 부팅할때마다 1회 포스팅을 하고, 포스팅 될때마다 결과 상태를 시리얼 통신으로 전달해 줍니다. (참고로 시리얼 창 새로 열거나 통신속도를 변경하여도 아두이노가 재부팅이되어 새로 포스팅을 시도합니다.) 결과가 Okay로 뜬다면 잠시 후 여러분의 트위터 페이지에 새 트윗이 올라온것이 보일 겁니다. Okay 외의 오류 메시지를 잘 살펴보시면 디버깅에 도움이 됩니다.
포스팅 시도후 오류메시지가 뜨는 경우가 종종 있는데요 제가 발견한 주요 오류 내용은 아래와 같습니다. 1. 동일한 내용을 중복하여 전송한 경우: 이경우 중복 전송된 값은 무시됩니다. 2. 트윗 작성 한계치 초과 : 시스템 보호를 위해 일정 시간당 한정된 개수의 트윗만 허용됩니다. 이 수량을 초과시 일정기간 동안 트위 작성이 불가하며 일정 시간이 지난뒤에 다시 작성이 가능해집니다. 가령 수십초에 한번씩 계속 트윗을 하신다면 얼마지나지 않아 트윗 등록이 거부될 겁니다. 아래의 예제에서는 1시간에 1회 트윗을 발신하게됩니다.
드디어 트위터 기상로봇
이제 포스팅될 정보를 여러분의 용도에 맞게 잘 구성해주시면 여러분만의 활용도 만빵인 트위터 포스팅 봇이 완성됩니다. 제 경우 이미 소개드렸었던 기상측정기기를 활용하여 1시간마다 기상데이타를 측정하여 전송해주는 예제를 만들어봤습니다. 실제 포스팅된 내용들을 아래의 페이지에서 확인 가능합니다.
한동안 실내 테스트만 하다가 2012년 1월 29일 현재, 옥외 설치하여 운영중입니다. 위 링크에 가보시면 실제 기상자료를 참고하실 수 있습니다. (경기도 수원시 오목천동)
위에서 트윗된 메시지의 포스팅 시간을 보시면 (오차가 1분도 안되네요^^.)1시간 간격으로 전송이 된것을 보실 수 있습니다. 하지만 가끔씩 몇 시간에 한번만 트윗된 것도 보이실 겁니다. 이때는 테스트를 위해 실내에서 측정된 풍량/풍속/강수량 수치의 변화가 없어서 동일한 내용을 반복 포스팅한것으로 인지되어 무시된 경우입니다. (계속 변화하는 시간값이나 랜덤숫자를 함께 전송하시면 이문제가 해결됩니다.)
사진. 기상측정 기구
+
사진. 아두이노로 만든 트위터 포스팅해주는 로봇
사용된 예제 소스 소개 값의 정밀도나 완성도를 무시하고 필요하신 분들에게 참고가 될 수 있도록 예제소스를 공개합니다. 풍향, 풍속, 강수량의 측정치 산정의 기준은 기상측정기기 제조사에서 제공한 데이타 시트를 참고하여 계산된 값입니다. 센서 연결 방법 및 기본 사용법 소개는 관련글 링크에 있는 글을 참고하시기 바랍니다.
/* * 풍향, 풍속, 강수량을 Twitter에 포스팅하는 예제 수정일시: (2011.09.08a) 디버깅 및 기능개선을 위해 수시로 변경될 수 있습니다.
풍향: 포스팅시 1회 계산 (16방위 중 하나로 측정) 풍속: 20ms 주기로 10초간 모니터링 후 풍속계산 강수량: 20ms 주기로 모니터링하여 1시간동안 누적(1시간에 1회 공식 데이타로 사용)
핀연결 풍향계: A0 풍향센서 전선 2개 중 하나는 GND에 나머지선은 A0에 연결 및 10k저항 거쳐 5V에 연결 풍속계: D2 풍속센서 전선 2개 중 하나는 D2에 나머지는 GND 강수계: D3 강수센서 전선 2개 중 하나는 D3에 나머지는 GND
기타 핀 연결 (없어도 무방) D7: 풍속계 상태 LED D8: 강수량계 상태 LED D9: 버튼 ( 버튼을 누르면 10초내로 즉시 포스팅)
// substitute an address on your own network here byte ip[] = { 192, 168, 100, 55 }; //바꿔주세요
// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/) Twitter twitter("발급받으신 토큰값을 적어주세요"); //바꿔주세요
// Message to post char msg[100] = "";
const int windVanePin = A0; // 풍량계 센서 입력핀 int windVaneValue = 0; // float windSpeed = 0; float rainGauge = 0; float windDirection = 0; char windName[4]; // N (North) S South, NS(north south) NNS(north north south) etc
unsigned long windSpeedTimer; int windSpeedState = true; int windSpeedPin = 2; int windSpeedCounter = 0; unsigned long rainGaugeTimer; int rainGaugeState = true; int rainGaugePin = 3; int rainGaugeCounter = 0; int buttonState = true; int buttonPin = 9; int postTrigger = false; int postingCounter = 0;
void postMessage(){ Serial.println("connecting ..."); if (twitter.post(msg)) { // Specify &Serial to output received response to Serial. // If no output is required, you can just omit the argument, e.g. // int status = twitter.wait(); int status = twitter.wait(&Serial); if (status == 200) { Serial.println("OK."); } else { Serial.print("failed : code "); Serial.println(status); } } else { Serial.println("connection failed."); } }
float getWindDirection(void){ // 풍향센서의 출력 전압을 아날로그 센서로 읽어옴 int readValue = analogRead(windVanePin); // ADC입력치를 0~5V 범위로 변환, 데이타시트 값과 대응이 쉽도록. windVaneValue = map(readValue, 0, 1023, 0, 500);
추가사항 (2011.11.29) 아두이노와 이더넷 쉴드를 하나로 결합한 Ethernet Pro 보드로 기상측정 트위터 기능을 구현할 수도 있습니다. 특히 PoE 케이블을 이용하시면 전원과 이더넷케이블을 하나로 줄일 수 있어 더욱편리합니다. 가령 위의 시스템을 아래의 이미지와 같이 간소화 시킬 수 있습니다.
안녕하세요 재밌는 창작재료가 너무 많아 무엇부터 갖고 놀아야 할지 고민이 됩니다. ^^. 즐거운 고민이죠;; 오늘은 기상측정용 기구를 소개해 드리겠습니다.
참고로,
다음글
에서는 기상측정기구와 이더넷 연동되는 아두이노(Arduino)로 기상관측 자료를 트위터(Twitter)에 자동으로 올려주는 기특한 녀석을 소개시켜 드리겠습니다. 제법 시스템이라 불릴 만한 구성입니다. 바람의 방향과 속도 및 강수량을 측정할 수 있는 기상관측 기구로 부터 측정된 값을 모니터링하고 이를 곧바로 이더넷 쉴드가 장착된 아두이노로 트위터(twitter)에 올리는 것입니다.
일단은 기상측정기구에 대해 좀더 알아봅시다!
Weather Meter (기상 관측기구 , Weather Sensor Assembly) 본 장비는 3가지 기상 관측 기초 자료를 측정할 수 있습니다.
1. Rain Gauge (강수량계) 입수되는 수량에 비례하여 스위칭을 해주는 특수 기구를 이용하여 1회 스위치시마다 0.2794mm 의 강수량에 대응되게 됩니다. 물시계 작동원리를 응용한것인데 아이디어가 참 좋네요
사진에는 안나왔네요;; 일단, 동영상을 참고하시길~
2. Anemometer (풍속계) 회전시마다 일정수의 스위칭이 이뤄지며 기준 시간당 스위칭 수를 측정하여 풍속 계산이 가능합니다. 1초 동안 1회 스위칭시 2.4km/h ( 0.6666m/s)의 속력에 대응합니다.
3. Wind Vane ( 풍향계) 바람의 방향을 16방위로 측정 가능한 센서입니다. 내장된 저항들과 회전각에 따라 작동되는 스위치에 의해 내부저항 값이 변화하며, 이 값을 10k옴 저항 한개와 기준전압 5V를 통해 아두이노 아나로그 입력 핀으로 감지하게 됩니다. 회전각에 따른 출력 전압 값은 데이타시트에 나와 있습니다. ( 회로연결법은 매우 간단합니다. 광센서나 온도센서의 저항 변화를 전압변화로 출력해주는 회로와 동일)
그림2. 풍향계 연결법( 5V와 10k저항을 사용하면 아래의 테이블에 있는 전압값이 Output핀에 출력됩니다.)
가령 0도(North,정북)을 향할 경우 내부저항은 약 33k옴이고 이때 10k옴 저항과 5V에 연결시 약 3.84V 가 측정됩니다.
Direction
esistance
Voltage
(Degrees)
(Ohms)
(V=5v, R=10k)
0
33k
3.84v
22.5
6.57k
1.98v
45
8.2k
2.25v
67.5
891
0.41v
90
1k
0.45v
112.5
688
0.32v
135
2.2k
0.90v
157.5
1.41k
0.62v
180
3.9k
1.40v
202.5
3.14k
1.19v
225
16k
3.08v
247.5
14.12k
2.93v
270
120k
4.62v
292.5
42.12k
4.04v
315
64.9k
4.78v(4.34v)
337.5
21.88k
3.43v
테이블1. 회전각/저항/전압 관계
참고. 제 경우 실측결과 315도 경우의 측정전압이 데이타시트와 달랐습니다. 참고하시기 바랍니다.
측정기의 비밀 본 장치를 회전시켜보면 풍향계와 풍속계 모두 매우 매끄럽게 회전됩니다. 센싱을 위해 스위치를 눌러주는 방식이라면 회전을 조금이라도 방해를 하게 될 테지만 이 기구는 그렇지 않습니다. 왜 그런지는 속을 들여다보면 나옵니다. 바로 마그네틱 센서입니다. 초소형 고강도 자석을 회전부에 설치해두고 회전시마다 자력으로 자석스위치를 일시적으로 단락시키는 방식을 사용하네요. 단순하고도 사용하기 편리한 메카니즘입니다.
연결 방법 풍향/풍속/강우량계 모두 각각의 케이블이 있으므로 총 3개의 케이블이 있습니다. 하지만 이중 풍속계 케이블을 풍향계 하단의 단자에 결합하게 되어 있으므로 2개의 케이블만 사용하면 됩니다. 케이블 전선은 일반 전화선과 유사하고 단자는 인터넷 케이블에 사용되는 것과 동일한 RJ45-8pin 단자입니다. 즉, 인터넷 케이블과 결합소켓을 이용하여 원하는 길이로 늘려줄 수 있게됩니다. 이더넷 케이블을 절단하여 라인을 브레드 보드에 결합하면 손쉽게 센서 스위치와 연결할 수 있습니다.(사진참조) 풍향계+풍속계 케이블 한곳에서 4개의 라인, 강수량계 케이블에서 2라인만 뽑아서 사용하면 됩니다.
측정 방법 풍속계와 강수량계는 스위치가 ON되는 횟수를 카운팅하면 되며 아두이노(Arduino)나 MCU를 이용하여 디지탈 입력핀으로 버튼이 눌려진 횟수를 카운팅하는 방법으로 측정이 가능합니다. 단, 스위칭시 노이즈로인해 1회 스위칭이 수~수십회 단락된 것으로 인지되므로 적절한 샘플링 주기(가령 20ms)마다 측정을 하여 스위치의 상태가 변이하는 순간에만 카운팅을 하도록 프로그램해줘야 합니다. 또한 강수량은 일정기간(가령 1시간)동안 그 값을 누적하여 결과로 사용하고, 풍속계도 일정 시간동안의 스위칭 횟수를 카운트하여 속력을 계산할 필요가 있습니다. 풍향 측정시엔 1개의 아날로그 입력핀이 필요하며, if else 구문으로 16 구간의 범위 조건으로 나눠서 각도를 구분해주면 됩니다.
예제 소스 막상 어떻게 측정이 가능한지 궁굼하신 분들을 위해 참고용 소스코드를 함께 수록합니다. 정확성은 보장 못드리지만 참고하시기 바랍니다.
/* 풍향, 풍속, 강수량 측정 예제
풍향: 10초마다 1회 계산 (16방위 중 하나로 측정) 풍속: 20ms 주기로 10초간 모니터링 후 풍속계산 강수량: 20ms 주기로 모니터링하여 1시간동안 누적(1시간에 1회 공식 데이타로 사용)
핀연결 풍향계: A0 풍향센서 전선 2개 중 하나는 GND에 나머지선은 A0에 연결 및 10k저항 거쳐 5V에 연결 풍속계: D2 풍속센서 전선 2개 중 하나는 D2에 나머지는 GND 강수계: D3 강수센서 전선 2개 중 하나는 D3에 나머지는 GND
const int windVanePin = A0; // 아날로그 0번핀에 연결 int winVaneValue = 0; // float windSpeed = 0; float rainGauge = 0; float windDirection = 0; char windName[4]; // N (North) S South, NS(north south) NNS(north north south)
unsigned long windSpeedTimer; int windSpeedState = true; int windSpeedPin = 2; int windSpeedCounter = 0; unsigned long rainGaugeTimer; int rainGaugeState = true; int rainGaugePin = 3; int rainGaugeCounter = 0;
결과 출력예 위 예제의 경우 10초마다 아래와 같은 결과가 PC로 전송됩니다. ArtRobot's Weather Bot said => Wind: N/0.0, 3.83(km/h) Rain 0.0(mm/h). ArtRobot's Weather Bot said => Wind: W/270.0, 4.79(km/h) Rain 0.0(mm/h). ...
아두이노와 전자회로를 배울때 가장 먼저 해보는것이 LED ON/OFF 제어인데요, LED 대신 IRED(적외선 LED)를 장착하고 마치 모르스 부호같이 규칙에 맞쳐 ON/OFF를 해주면 복잡한 데이타도 송수신이 가능합니다. 여러분이 매일 사용하고 계신 TV같은 가전기기가 바로 이렇게 눈에 보이지 않는 빛을 통해 제어되고 있습니다. 이 기술을 잘 활용하면 여러분의 아두이노로 리모콘을 대체하거나 반대로 리모콘 명령에 따라 동작하는 아두이노 기기의 제작이 가능합니다.
본 글을 통해 아래의 적외선 송수신 기본회로를 소개해 드리고 실제로 리모콘으로 조정되는 로봇을 아두이노로 제어하는 방법도 안내해 드리겠습니다
1. 초간단 적외선 송신 회로 2. 고출력 적외선 송신 회로 ( 5미터 이상의 장거리? 전송가능) 3. 리모컨 신호 수신 회로
1. 초간단 적외선 송신 회로
그림1.의 회로를 보시면 바로 아시겠죠? 네, 일반적인 LED를 켤때 사용하는 회로와 동일하게 연결하면 됩니다. 차이점이라면 보통 IRED는 대부분의 LED보다 좀더 저 전압에서 구동된다는 점입니다. 따라서 일반 LED보다는 조금더 큰 저항을 사용하면 됩니다. 저항값이 작으면 좀더 IRED를 밝게 켤 수 있지만 대신 IRED와 아두이노에 무리가 갈 수 있으므로 적당한 저항값을 선정해주시면 됩니다. 하지만 정답은 없습니다. 예제에서는 560옴 저항을 사용하였습니다.
예제에 사용된 IRED 규격: 정격 1.36V , 최대 1.7V, 피크주파수 940nm, 화각+-20도
5V 전압을 가할 경우, I= V/R 공식을 참고하시면 약, 9mA 전류가 흐를 수 있음을 계산으로 예상할 수 있습니다. 아두이노의 경우 핀 한개에서 출력할 수 있는 전류허용량은 20mA에 불과합니다. 초간단 회로로 광신호 도달 거리가 짧을 경우 그림2. 와 같은 고출력 전송회로를 사용하면 됩니다. 위 예제에선 아두이노 디지탈3번 핀을 통해 ON/OFF 제어를 하게됩니다. 참고로, 디지탈 3번핀은 PWM 출력을 지원해주는 핀중 하나입니다.
2. 고출력 적외선 송신 회로
본 회로는 보통의 가전기기 제어용 리모콘에서 사용되는 회로입니다. 수십에서 수백 mA의 고출력 송신이 가능하므로 비교적 원거리(5미터 이상)로 광신호를 전송할 수 있습니다. 이를 위해 트랜지스터를 사용하는데요 아두이노에서 저 전류 제어로 ON/OFF를 제어하고 실제로 IRED에 전류공급은 트랜지스터가 담당하여 비교적 큰 전류를 사용할 수 있게 됩니다. 그림2.를 참고하여 회로를 구성하시면 됩니다. 여기서 R1은 330옴 R2는 1옴을 사용하였습니다. 실제로 테스트 해본 결과 방이나 거실 전역에서 방향에 상관없이 신호전달이 되는것을 확인했습니다. 기본 제공되는 리모콘보다 더 고출력인것 같네요;; (사실 본 회로에 5V는 조금 과할 수 있습니다. 아두이노와 함께 사용하실 경우 5V 대신 3.3V 전압을 사용하면 좋습니다.)
예제 회로의 경우 일시적으로 매우 큰 전류가 흐르게되지만 매우 짧은 시간동안만 구동되므로 전체적인 전류소모율은 적은 편입니다. 참고로, 상용 리모콘의 경우 미작동중엔 sleep모드로 대기하다가 버튼이 눌리는 순간 깨어나서 IR송신 후 다시 잠에 들게 되므로 건전지 2개로 수개월씩 작동이 가능합니다. 회로도로 잘 이해가 가지 않으신 분들은 아래의 실제 연결된 사진을 참고하시기 바랍니다.
사진1. 고출력 IR 송신회로 실제 구성예
3. 적외선 수신 회로
적외선 송신측 IRED의 피크 주파수와 일치하는 파장의 포토트랜지스터나 포토다이오드를 이용하여 수신부 구현이 가능합니다. 하지만 우리주변엔 다양한 파장의 빛들이 가득차 있으므로 노이즈에 해당하는 빛신호를 차단하고 원하는 광신호만 추출해주는 필터회로가 있어야 실용이 가능해 집니다. 리모콘 수광 모듈은 이를 위한 소자와 필터회로가 일체화된 제품으로 매우 손쉽게 특정 파장 및 주파수의 빛 신호에 반응하는 수신기로 활용할 수 있습니다.
예제에 사용된 적외선 수광모듈 사양: 감응되는 빛의 파장: 940nm , 빛 신호의 주파수: 38KHz
참고로, 적외선 송신시 사용된 IRED가 850nm 파장의 빛을 출력한다면, 수광모듈도 850nm 용으로 맞쳐줘야 수신률이 높아집니다. 마찬가지로 빛 신호의 캐리어 주파수(가령 38KHz)도 송/수신 모듈이 일치되어야 합니다. 예제에선 940nm 피크 파장의 IRED와 940nm형 수광모듈을 사용하였으며, 캐리어 주파수는 38KHz로 맞췄습니다.
IR 수광 모듈의 연결법도 매우 간단하며 (그림3을 참고) 전원만 공급해주고 VOUT단자로 출력되는 신호를 참고하기만 하면 됩니다. 다만, 전원 입력부에 노이즈가 있어 문제가 되는경우라면 전원 입력부에 저항과 콘덴서를 이용하여 노이즈를 감쇄시켜줘야 합니다. (보통은 생략이 가능합니다. 필요한 경우 관련자료에서 IR수광모듈 데이타 시트를 참고하시기 바랍니다.) 위 회로에서는 VOUT 출력을 아두이노 디지탈11번 핀에 연결하여 신호를 감지하는 경우를 가정하였습니다.
아두이노로 적외선 신호 송신 및 수신하기 - 프로그래밍 편
위에서 소개해드린 방법으로 하드웨어 준비는 간단히 끝났습니다. 이제는 아두이노로 리모콘 제어 신호를 발신하기 위해선 전송규약에 맞쳐 ON/OFF제어가 필요한데 많은 분들에게 쉽지 않은 과제입니다. 따라서 전용 라이브러리를 활용하시면 좋은데요 공개된 아두이노 라이브러리들을 둘러보시고 적절한것을 선택하시면됩니다. 본 글에선 IR Remote 라는 라이브러리를 참고로 하였습니다. IR Remote 라이브러리의 경우 IR 송신을 위해서 D3핀을, 수신을 위해서 D11핀을 기본으로 사용하고 있습니다.
IR Remote 라이브러리로 적외선 리모콘 신호 발신하여 로봇 원격 제어하기
이제는 실제로 리모콘으로 제어되는 로봇을 아두이노로 제어해 보도록 하겠습니다.
제어대상: 원격제어 6족보행 로봇 전송프로토콜: 유사 NEC 코드 전송부 회로: 그림1. 또는 그림2 의 회로 모두 사용 가능
if (Serial.available() > 0) { // read the incoming byte: incomingByte = Serial.read(); // say what you got: Serial.print("I received: "); Serial.println(incomingByte, DEC); Serial.flush(); } switch( incomingByte){ case 56: //forward irsend.sendNEC( 0xc5000000, 8); //전진 break; case 50: //backward irsend.sendNEC( 0x45000000, 8); //후진 break; case 52: // turn reft irsend.sendNEC( 0x25000000, 8); //좌회전 break; case 54: // turn right irsend.sendNEC( 0x85000000, 8); //우회전 break; case 53: //stop 정지 , 아무신호도 안 보내면 정지합니다. break; } delay(500); // 0.5초를 주기로 반복 }
아두이노에 위 소스를 프로그래밍 하신 뒤 시리얼 모니터 창을 여시고, send 입력란에 아래의 해당 숫자키를 입력한 뒤 엔터를 입력하여 전송해줍니다.
전진
8
후진
2
좌회전
4
우회전
6
정지
5 or 기타키 or 그냥 엔터
가령, 전진을 하려면 숫자 8을 누르고 엔터를 쳐주면됩니다. 중지하려면 5번을 누르고 엔터를 치면됩니다.
소스 해석: 시리얼 포트를 통해 값이 전송되면 첫번째 바이트 값을 읽고 이값에 따라 방향제어 변수값을 수정합니다. 또한 이값은 별도의 입력이 없는경우 그대로 유지되므로 매번 순환루프 마다 보관해둔 방향제어 변수값에 따라 리모콘 신호를 발신하게 됩니다.
방향 제어 명령을 유선 시리얼 통신으로 받는 대신, 무선으로 전송 하거나 조이스틱이나 버튼 또는 센서를 이용하여 변화시켜주면 전파를 이용한 로봇제어나 자율이동형 로봇의 제작도 가능합니다.
동영상1. 실행 예제 보기
키보드 숫자를 입력후 엔터를 치면 시리얼통신으로 아두이노에 전송되고 이 값에 따라 적절한 리모콘 신호를 보내어 로봇을 제어하게됩니다. 본래 적외선은 사람 눈으로는 보이지 않지만 대부분의 카메라로는 볼 수 있습니다. 동영상 후반부를 보시면 광신호가 약 0.5초에 한번씩 송출될때 로봇이 움직이고, 신호가 없으면 로봇이 멈추는것을 확인하 실 수 있습니다.
끝으로, 온갖 가전기기들이 리모콘으로 제어되고 있습니다. 이는 아두이노로 제어할 수 있는 기기들이 많다는 뜻이기도 한데요 여러분은 어떤 기기를 제어해 보시겠습니까? 가령 저렴하게 구입이 가능한 리모컨 제어되는 MP3플레이어로 말하는 로봇 만들기도 가능합니다. 아래의 관련글에서 좀더 세부적인 리모콘 프로토콜 정보도 참고하시기 바랍니다.
즐거운 DIY 생활 보내시길!!
관련 제품 링크
.무선제어 6족보행 로봇
.아두이노 UNO
.적외선 무선통신킷
기타정보 링크 .아두이노로 무선제어 6족보행 로봇 제어하기 63 .말하는 로봇 만들기( 적외선 리모콘 프로토콜 ) 31 .IR수광모듈 데이타시트(첨부파일 참조)