기술문서 2014. 11. 08 기초부터프로젝트완성까지, 아두이노 첫걸음 을위한 Arduino Bluetooth Car Control Project 작성자 : 인천대학교 OneScore 임승한 lim_designer@naver.com
Contents 1. Arduino 1.1 아두이노개발환경구성 p.03 아두이노통합개발환경 (IDE) 소프트웨어설치 p.03 아두이노보드와컴퓨터연결 p.09 아두이노보드용드라이버설치 p.12 1.2 IDE p.19 아두이노 IDE 보드선택 p.19 아두이노 IDE 포트선택 p.21 아두이노스케치프로그램작성 p.22 아두이노스케치라이프사이클 p.23 아두이노스케치저장 p.25 아두이노스케치컴파일 p.28 아두이노스케치업로드 p.29 아두이노스케치실행확인 p.31 2. Project p.33 2.1 프로젝트설명 p.33 2.2 부품 p.33 2.3 무작정따라하기 p.34 2.4 전체소스코드 p.46 2.5 Bluetooth 로실행하기 p.52 3. 회로구성도 p.55 4. 참고문헌 p.56
1. Arduino 1.1 아두이노개발환경구성 아두이노통합개발환경소프트웨어설치 먼저아두이노스케치를작성, 컴파일하고보드상에업로드하기위한환경을구성해보 자. 다음과같은아두이노통합개발환경소프트웨어를설치할것이다.
1. 다음과같이구글사이트등을통해서 [ 아두이노 IDE] 를검색한다. 아두이노 IDE(Integrated Development Environment ) 는아두이노통합개발환경을의미한다. 2. 그러면다음과같이아두이노 IDE 소프트웨어를다운로드받을수있는사이트를찾 을수있다. 이사이트를클릭해들어간다. 3. 그러면다음과같이 ARDUINO 로고가그려진아두이노웹사이트를찾을수있다. [Download the Arduino Software] 라는문장을볼수있다. 페이지아래쪽으로이동해보자.
4. 다음부분이나올때까지페이지를이동한다. [Windows(ZIP files)] 를선택해마우스왼 쪽버튼을클릭한다. 그러면다운로드가시작된다. 5. 다음과같이다운로드가완료되면, 적당한곳에압축을푼다. 6. 압축을풀면다음과같은디렉터리를볼수있다. 7. 이디렉터리를윈도우바탕화면으로옮긴다. 다른적당한위치로옮겨도상관없다.
8. 디렉터리안으로들어가보자. 다음과같은하위디렉터리들과파일들이있는것을볼 수있다. 9. 이중에다음프로그램을선택해마우스오른쪽버튼을클릭한다. 앞으로이프로그램 을이용하여아두이노 IDE 소프트웨어를구동하게된다.
10. 처음엔다음과같은보안경고창이뜬다. 아두이노 IDE 소프트웨를사용하기위해 필요한부분이기때문에액세스허용버튼을누른다. 11. 그러면다음과같이아두이노 IDE 소프트웨어프로그램이실행되는것을볼수있다. 앞으로우리는이프로그램을이용하여 1) 아두이노스케치를작성하고, 2) 컴파일하고 3) 아두이노보드상에업로드하게된다. 4) 그리고보드를통해서결과를확인하게된다.
아두이노보드와컴퓨터연결 이번엔아두이노보드와컴퓨터를연결해보자. 아두이노보드의 USB는다음과같이세가지기능을제공한다. 1) 먼저전원을공급받을수있고, 2) 컴파일한프로그램을업로드할수있고, 3) 시리얼포트를통해디버깅메시지를볼수있다. 이런이유로아두이노보드는 USB 케이블하나로컴퓨터로연결될수있으며, 따라서, 아주간단한인터페이스를이용하여, 개발을진행할수있는장점이있다. 이러한기능들은곧살펴보게될것이다. 조금만더가보도록하자. 1. 다음과같이 ARDUINO MEGA ADK for Android 보드를준비한다. 보드의이름에서알수있는것처럼이보드는안드로이드디바이스와연결해서사용할수있는보드이다. 안드로이드디바이스란안드로이드스마트폰, 안드로이드태블릿등안드로이드기반하드웨어를의미한다.
2. 다음과같은모양의 USB 케이블을준비한다. 이케이블을이용하여아두이노보드와 컴퓨터를연결할것이다. 3. 다음과같이 USB 케이블의한쪽끝을아두이노보드에연결한다.
4. 다음과같이 USB 케이블의다른쪽끝을컴퓨터에연결한다.
아두이노보드용드라이버설치 1. 아두이노보드를 USB 케이블을통해처음연결하면, 다음과같이화면에 USB 디바이 스인식실패창이뜨는것을볼수있다. 장치드라이버소프트웨어를설치해보자. 2. 다음과같은시작버튼을찾아마우스왼쪽클릭한다.
3. 그러면다음과같이메뉴창이뜬다. 컴퓨터를마우스오른쪽버튼을누르고 [ 속성 ] 을 선택한다. 4. 그러면다음과같은창이뜬다. [ 장치관리자 ] 를선택해마우스왼쪽버튼을클릭한다.
5. 그러면다음과같이 [ 장치관리자 ] 창이뜬다. [ 기타장치 ] 에 [Arduino Mega ADK] 장치 를볼수있다. 6. 다음과같이 [Arduino Mega ADK] 항목에서마우스오른쪽버튼을클릭한후, [ 드라이 버소프트웨어업데이트 (P) ] 항목을선택한다.
7. 그러면다음과같이 [ 드라이버소프트웨어업데이트 ] 창이뜬다. 두번째항목인 [ 컴퓨 터에서드라이버소프트웨어찾아보기 (R)] 를선택한다.
8. 그러면다음과같은창이뜬다. [ 찾아보기 ] 버튼을눌러드라이버위치를앞에서설치 했던 arduino-1.5.5 디렉터리내에있는 drivers 위치를선택한다. 하위폴더포함부분도 체크해준다. 이제다음버튼을누르자.
9. 그러면다음과같은 Windows 보안창이뜬다. 아두이노보드용디바이스드라이버에 대한경고메시지이며, 실제로는문제가없으니, 두번째항목인 [ 이드라이버소프트웨 어를설치합니다 (I)] 를선택하여, 마우스왼쪽버튼을클릭한다.
10. 그러면다음과같이 [Arduino Mega ADK] 용드라이버가설치된다. 닫기버튼을누른 다. 11. 창을닫고나면, 다음과같이포트항목에 [Arduino Mega ADK(COM11)] 항목이추가 된것을볼수있다. COM11 부분을기억하기바란다. 환경에따라독자여러분들의포트 는다를수도있다. 그포트번호를기억하면된다. 이제아두이노보드드라이버설치가완료되었다. 보드기반의개발에서는자주보게되 는과정이며, PC 기반의응용프로그래밍만해본독자분들이라면이과정이낯설수도 있다.
1.2 IDE 여기서는아두이노 IDE에서사용할보드로 MEGA ADK를선택하고, 아두이노스케치프로그램을다운로드할포트를선택하는방법을살펴본다. 그리고간단한 Hello Arduino 스케치프로그램을작성한후, 컴파일하고보드상으로업로드하여테스트하는과정을살펴본다.
아두이노 IDE 보드선택 아두이노 IDE 에서사용할보드를선택하기위해다음과같이아두이노 IDE 에서 [ 도구 ]- [ 보드 ]-[Arduino Mega ADK] 보드를선택한다. 사용하는보드에대한선택은이메뉴를통 해서하면된다.
아두이노 IDE 포트선택 다음은아두이노스케치프로그램을업로드하고, 시리얼을통한디버깅메시지를확인하기위해포트를선택한다. 다음과같이 [ 도구 ]-[ 포트 ]-[COM11] 을선택한다. 독자여러분의경우이부분이달라질수있다. 드라이버를설치하는과정에서기억했던 COM 포트를선택해준다.
아두이노스케치프로그램작성 이제간단한아두이노스케치프로그램을작성해보자. 1. 다음과같이예제를작성한다. 소스파일 : 부록 \Source\Chapter01\01Hello
아두이노스케치라이프사이클 예제의내용을살펴보기전에아두이노보드상에서프로그램이동작하는방식을살펴 보도록하자. 아두이노스케치프로그램은두개의중요한메서드로구성된다. 하나는 setup 메서드이며, 코드실행을시작할때한번만수행된다. 여기에서하드웨어를제어하기위한초기화루틴을작성할수있다. 두번째메서드는 loop 메서드이다. 이메서드는보드가리셋될때까지반복해서수행되는루틴이다. 아래 loop() 박스내에회전화살표는반복수행을의미한다. 이부분에서보드를구동시키는프로그램로직을구현하면되겠다. 다음그림과같이아두이노스케치프로그램의라이프사이클은아주간단하다. < 그림 > 아두이노스케치라이프사이클 예제를살펴보도록하자. void setup() {
// 한번실행될설정코드를여기에놓는다 Serial.begin(9600); 여기서는 Serial 클래스의 begin 메서드를통해디버깅메시지를보게될시리얼디바이스의통신속도를설정하고있다. 9600 bps의속도로시리얼통신을하도록설정한다. 디버깅메시지를보는방법은조금뒤에소개된다. Serial 클래스는시리얼통신용디바이스를다루기위한코드와데이터들의집합으로이해하면된다. void loop() { // 반복해서실행될, 주요코드를여기에놓는다. Serial.println("Hello Arduino!"); delay(1000); 여기서는 Serial 클래스의 println 메서드를통해 Hello Arduino! 메시지를시리얼모니터로보낸다. 그리고 delay 메서드를통해 1초가지날때까지프로그램의진행을멈춘다. 1000은 1000분의 1초단위이다. 예를들어 0.1 초멈추려고할경우 100을 delay 메서드에넘겨주면된다. 이상예제를살펴보았다.
아두이노스케치저장 그러면작성한 Hello Arduino 프로그램을저장해보도록하자. 1. 아두이노 IDE 상단에있는다음버튼을눌러스케치프로그램을저장할수있다. 2. 버튼을누르면다음과같이저장창이뜬다. 기본으로선택되는디렉토리내에 hello 라 는이름으로저장하자. 파일이름항목에 hello 라고입력하고, 저장버튼을누른다.
3. 그러면다음과같이파일의이름이 hello 로변경되는것을볼수있다. 이후에나오는 예제들도이와같은방법으로저장하면되겠다.
4. 다음과같이 [ 파일 ]-[ 저장 ] 메뉴로저장할수도있다.
아두이노스케치컴파일 이제아두이노스케치를컴파일해보자. 컴파일이란우리가작성한코드를아두이노보드상에있는마이크로컨트롤러가읽을수있는코드로변형하는작업이며, 컴파일러라는프로그램이이작업을수행하게된다. 한글로쓴소설을영어로번역하여, 영어를사용하는사람들이읽을수있도록하는작업과같다고보면되겠다. 1. 다음버튼을눌러컴파일을수행한다. 2. 다음과같이하단부에컴파일완료메시지가뜨는것을볼수있다. 3. 다음과같이 [ 스케치 ]-[ 확인 / 컴파일 ] 메뉴를통해서도스케치파일을컴파일할수있 다.
아두이노스케치업로드 컴파일이완료되었으니, 이제 MEGA ADK 상에컴파일된스케치프로그램을업로드하여 실행시켜보자. 1. 다음버튼을눌러보드상에업로드를한다. 2. 다음과같이업로드완료메시지가뜨는것을볼수있다. 3. 다음과같이 [ 파일 ]-[ 업로드 ] 메뉴를통해서도보드상에프로그램을업로드할수있다.
아두이노스케치실행확인 이제보드상에서어떻게동작하는지확인해보도록하자. 1. 보드의실행동작을확인해보기위해다음과같이 [ 도구 ]-[ 시리얼모니터 ] 메뉴를선 택한다. 2. 그러면다음과같은창이뜨고 COM11 을통해 Hello Arduino! 메시지가뿌려지는것을 볼수있다. loop 메서드가반복되서호출되기때문에메시지도반복되서뿌려지게된다.
2. Project 2.1 프로젝트설명블루투스를통한근거리통신아두이노자동차제어프로젝트를개발한다. 2.2 부품 제품명 수량 Arduino Uno R3 1 점퍼와이어 - 케이블메이트 USB2.0(AM-BM) 케이 블 1 Bluetooth Slave UART Board 1 소형브레드보드 1 L293DNE (H 브리지 ) 1 9v 건전지 1 DC 모터 2 자동차모형 ( 로봇라인 X-2) 1 * 반드시로봇라인 X-2 라는모델일필요는없다. DC 모터에장착이되는바퀴와자동차모형처럼보일수있는것이면 O.K. * 추천제품구매싸이트 : 엘레파츠 www.eleparts.co.kr 디바이스마트 www.deviecemart.co.kr ( 로봇라인 X-2)
2.2 부품설명 H 브리지 프로젝트에사용할 H 브리지는다음과같으며두개의모터를제어할수있다. 먼저 8 번핀은 9V VCC 로연결하고 4 번, 5 번핀은 GND 로연결한다. DC 모터는 3 번핀과 6 번 핀에연결해준다. 모터의선은 3 번, 6 번핀에어떻게연결해도상관없다. 16 번핀을 VCC 로연결하면 H 브리지가동작하게된다. 2 번핀과 7 번핀은서로다른입력값을주 어모터의방향을결정하게된다. 예를들어 2 번핀에는 LOW, 7 번핀에는 HIGH 값을 주거나, 반대로 2 번핀에는 HIGH, 7 번핀에는 LOW 값을주면된다. 두핀에같은값을 입력하면모터가멈추게된다. 1 번핀을통해서는모터를구동시키거나멈추게할수 있다. 1 번핀에 HIGH 값을주게되면모터가동작을시작하며, LOW 값을주게되면모 터가멈추게된다. 1 번핀에 PWM 을연결하여모터의속도를조절한다. 2.3 무작정따라하기 1. Arduino IDE 설치 2. notepad++ 설치플러그인 >Plugin Manager>Show Plugin Manager>JSTool 설치플러그인 >JSTool>JSFormat(Ctrl+Alt+M) 을이용하여소스정렬할수있다. 3. Arduino 실행 void setup() { // put your setup code here, to run once: void loop() {
// put your main code here, to run repeatedly: 4. setup() 함수다음과같이수정 void setup() { // put your setup code here, to run once: Serial.begin(9600); while(!serial) { ; Serial.println( FUNCTION ); 5. 도구 > 보드 > Arduino Uno 도구 > 포트 > COM7(Arduino Uno) 체크표시로컴파일화살표표시로업로드도구 > 시리얼모니터띄우기 6. 단축키이용 ctrl+u -> 컴파일 / 업로드 ctrl+shift+m -> 시리얼모니터 7. 파일 > 환경설정에디터글꼴크기조정다음동작중자세한출력보이기 : 컴파일, 업로드체크줄번호표시업로드후코드검증하기체크해제외부에디터사용나중에체크 ( 나중에코드량이많아지면, 아두이노에디터사용불편 ) 다른부분은그대로! 8. loop() 함수다음과같이수정 void loop() { // put your main code here, to run repeatedly: Serial.println( FUNCTION ); 무한히반복된다. 다음파일에서 main() 함수확인 C:\Program Files(x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp int main(void) { init();
setup(); for(;;) { loop(); if (serialeventrun) serialeventrun(); return 0; 다음함수확인 init(); setup(); loop(); serialeventrun(); 9. 파일을다음과같이수정하고, arduino_test 로저장 void initsystem(){ void showmenu(){ void getusercmd(){ void processcmd(){ void setup() { // put your setup code here, to run once: Serial.begin(9600); while(!serial) { ; Serial.println( FUNCTION ); initsystem(); showmenu(); void loop() { // put your main code here, to run repeatedly: getusercmd(); processcmd(); 10. initsystem(), showmenu() 함수를다음과같이수정한후실행시켜본다. void initsystem() { Serial.println( FUNCTION ); void showmenu()
{ Serial.println( FUNCTION ); 11. getusercmd(), processcmd() 함수를다음과같이수정한후실행시켜본다. void getusercmd() { Serial.println( FUNCTION ); void processcmd() { Serial.println( FUNCTION ); 12. arduino_test 파일을다음과같이수정한다. void initsystem(); void showmenu(); void getusercmd(); void processcmd(); void setup() { // put your setup code here, to run once: Serial.begin(9600); while(!serial) { ; Serial.println( FUNCTION ); initsystem(); showmenu(); void loop() { // put your main code here, to run repeatedly: getusercmd(); processcmd(); 13. work 라는파일을새로추가한다. 그리고다음과같이함수를작성한다. void initsystem() { void showmenu() { void getusercmd() { void processcmd() {
14. showmenu() 함수를다음과같이수정한다. void showmenu() { Serial.println( FUNCTION ); Serial.println("1. menu item 1"); Serial.println("2. menu item 2"); Serial.println("3. menu item 3"); Serial.println("\nINPUT> "); 15. 예제를하나새로열로다음예제를테스트해본다. int incomingbyte = 0; // for incoming serial data void setup() { Serial.begin(9600); // opens serial port, sets data rate to 9600 bps void loop() { // send data only when you receive data: while (Serial.available() > 0) { // read the incoming byte: incomingbyte = Serial.read(); // say what you got: Serial.print("I received: "); Serial.println(incomingByte, DEC); aaa를입력해본다. 엔터키를쳐본다. 16. 다음사이트를참조해사용자입력을완성한다. http://arduino.cc/en/tutorial/serialevent /* Serial Event example When new serial data arrives, this sketch adds it to a String. When a newline is received, the loop prints the string and clears it. A good test for this is to try it with a GPS receiver that sends out NMEA 0183 sentences.
Created 9 May 2011 by Tom Igoe This example code is in the public domain. http://www.arduino.cc/en/tutorial/serialevent */ String inputstring = ""; // a string to hold incoming data boolean stringcomplete = false; // whether the string is complete void setup() { // initialize serial: Serial.begin(9600); // reserve 200 bytes for the inputstring: inputstring.reserve(200); void loop() { // print the string when a newline arrives: if (stringcomplete) { Serial.println(inputString); // clear the string: inputstring = ""; stringcomplete = false; /* SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available. */ void serialevent() { while (Serial.available()) { // get the new byte: char inchar = (char)serial.read(); // add it to the inputstring: inputstring += inchar; // if the incoming character is a newline, set a flag // so the main loop can do something about it: if (inchar == '\n') { stringcomplete = true;
17. 사용자입력을받기위한 cmd,inputstring,stringcomplete 변수를 work 파일의맨위에다음과같이추가한다. static char cmd = '?'; static String inputstring = ""; static boolean stringcomplete = false; 18. getusercmd() 함수를다음과같이수정한다. void getusercmd() { if (stringcomplete) { cmd = inputstring[0]; inputstring = ""; if(cmd!= '\r' && cmd!= '\n') { Serial.println(cmd); stringcomplete = false; 19. serialevent() 함수를 processcmd() 함수아래에다음과같이추가한다. 컴파일하고입력해본다. void serialevent() { while (Serial.available()) { char inchar = (char)serial.read(); inputstring += inchar; if (inchar == '\n') stringcomplete = true; 20. processcmd() 함수를다음과같이수정한다. void processcmd() { Serial.print("\nprocess command : "); Serial.println(cmd); Serial.print('\n'); 21. processcmd() 함수를다음과같이수정한다.
void processcmd() { 21. 메뉴출력과메뉴처리를위한루틴을수정해보자. 먼저다음과같이루틴을 work 파일맨위에추가해준다. struct MenuFunc { bool enable; char * pmenu; void (* pfunc)(); ; void func1(){ void func2(){ void func3(){ MenuFunc menu_funcs[] = { {false, "menu item 1", func1, {false, "menu item 2", func2, {false, "menu item 3", func3, ; 23. showmenu() 함수를다음과같이수정한다. void showmenu() { int i; Serial.println( FUNCTION ); for(i=0;i<sizeof(menu_funcs)/sizeof(menu_funcs[0]);i++) { Serial.print(i+1); Serial.print(". "); Serial.println(menu_funcs[i].pMenu); Serial.println("\nINPUT> "); 24. getusercmd() 함수를다음과같이수정한다. void getusercmd() { if (stringcomplete) { cmd = inputstring[0]; inputstring = ""; if(cmd!= '\r' && cmd!= '\n') { int cmdindex = cmd - '0' - 1; int howmanycmds = sizeof(menu_funcs)/sizeof(menu_funcs[0]); if(cmdindex>=0 && cmdindex<howmanycmds) { bool * pfuncen = &menu_funcs[cmdindex].enable;
*pfuncen =!*pfuncen; stringcomplete = false; 25. processcmd() 함수를다음과같이수정한다. void processcmd() { int cmdindex; int howmanycmds = sizeof(menu_funcs)/sizeof(menu_funcs[0]); for(cmdindex=0;cmdindex<howmanycmds;cmdindex++) if(menu_funcs[cmdindex].enable) menu_funcs[cmdindex].pfunc(); 26. func1(),func2(),func3() 함수를다음과같이수정한다. void func1(){serial.println( FUNCTION ); void func2(){serial.println( FUNCTION ); void func3(){serial.println( FUNCTION ); 27. funcs 파일을추가하고 work 파일의다음부분을옮긴다. struct MenuFunc { bool enable; char * pmenu; void (* pfunc)(); ; void func1(){serial.println( FUNCTION ); void func2(){serial.println( FUNCTION ); void func3(){serial.println( FUNCTION ); MenuFunc menu_funcs[] = { {false, "menu item 1", func1, {false, "menu item 2", func2, {false, "menu item 3", func3, ; 28. work 파일에서 funcs 파일로옮겨진부분은다음과같이대체한다. struct MenuFunc; extern MenuFunc menu_funcs[];
29. 4 번항목을다음과같이추가해본다. struct MenuFunc { bool enable; char * pmenu; void (* pfunc)(); ; void func1(){serial.println( FUNCTION ); void func2(){serial.println( FUNCTION ); void func3(){serial.println( FUNCTION ); void func4(){serial.println( FUNCTION ); MenuFunc menu_funcs[] = { {false, "menu item 1", func1, {false, "menu item 2", func2, {false, "menu item 3", func3, {false, "menu item 4", func4, ; 30. funcs 파일을다음과같이수정한다. struct MenuFunc { bool enable; char * pmenu; void (* pfunc)(); ; void func1(); void func2(); void func3(); void func4(); MenuFunc menu_funcs[] = { {false, "menu item 1", func1, {false, "menu item 2", func2, {false, "menu item 3", func3, {false, "menu item 4", func4, ; void func1(){serial.println( FUNCTION ); void func2(){serial.println( FUNCTION ); void func3(){serial.println( FUNCTION ); void func4(){serial.println( FUNCTION ); 31. Bluetooth Car 기능을추가하기위해 work 파일을다음과같이수정한다. struct MenuFunc {
; bool enable; char * pmenu; void (* pfunc)(); void controlcar(); void func2(); void func3(); void func4(); MenuFunc menu_funcs[] = { {false, "Arduino Controlled Bluetooth Car", controlcar, {false, "menu item 2", func2, {false, "menu item 3", func3, {false, "menu item 4", func4, ; void controlcar(){serial.println( FUNCTION ); void func2(){serial.println( FUNCTION ); void func3(){serial.println( FUNCTION ); void func4(){serial.println( FUNCTION ); 32. control_car 함수를하나추가하고다음함수를옮겨온다. void controlcar(){serial.println( FUNCTION ); 33. controlcar() 함수를다음과같이수정한다. void car_init(); char get_dir(); void go_forward(); void go_backward(); void turn_left(); void turn_right(); void stop_car(); void controlcar() { char dir = 's'; Serial.println("\n\n==Arduino Bluetooth Car Control=="); Serial.println("f. go forward"); Serial.println("b. go backward"); Serial.println("l. trun left"); Serial.println("r. trun right"); Serial.println("s. stop"); Serial.println("q. Exit");
Serial.println("\nINPUT> "); car_init(); while(1) { dir = get_dir(); switch(dir) { case 'f': go_forward(); break; case 'b': go_backward(); break; case 'l': turn_left(); break; case 'r': turn_right(); break; case 's': stop_car(); break; case 'q': return; default: break; void car_init(){ char get_dir(){ void go_forward(){ void go_backward(){ void turn_left(){ void turn_right(){ void stop_car(){
2.4 ( 위, 아래, 좌, 우모터방향제어 Source Code 포함 ) 전체소스코드 <arduino_test> void initsystem(); void showmenu(); void getusercmd(); void processcmd(); void setup() { // put your setup code here, to run once: Serial.begin(9600); while(!serial) { ; Serial.println( FUNCTION ); initsystem(); showmenu(); void loop() {
// put your main code here, to run repeatedly: getusercmd(); processcmd(); <funcs> const int dirpin1=2; //moter_1 const int dirpin2=3; //moter_1 const int dirpin3=4; //moter_2 const int dirpin4=5; //moter_2 const int speedpin1=9; //moter_1 speed control pin const int speedpin2=10; //moter_2 speed control pin int motorspeed=175; int motordir=1; char inchar; struct MenuFunc { bool enable; char * pmenu; void (* pfunc)(); ; // 프로토타입만정렬 - - 가독성 - overview 효과 void controlcar(); void func2(); void func3(); void func4(); void getdir(); MenuFunc menu_funcs[] = { {false, "Arduino Controlled Blutooth Car", controlcar, {false, "menu item 2", func2, {false, "menu item 3", func3, {false, "menu item 4", func4, ; void controlcar() { Serial.println("==Arduino Blutooth Car Contril=="); Serial.println("w. go forward"); Serial.println("s. go backward"); Serial.println("a. turn left"); Serial.println("d. turn right"); Serial.println("x. stop"); Serial.println("q. Exit");
Serial.println("\nINPUT> "); while(1){ getdir(); switch(inchar){ case 'w': go_forward(); break; case 's': go_backward(); break; case 'a': turn_left(); break; case 'd': turn_right(); break; case 'x': stop_car(); break; case 'q': showmenu(); inchar = 0; return;//continue; break; default : break; void getdir(){ while (Serial.available()) { inchar = (char)serial.read(); void go_forward() { pinmode(dirpin1,output); pinmode(dirpin2,output); pinmode(dirpin3,output); pinmode(dirpin4,output); motordir = 1; setmotordir(motordir); setmotorspeed1(motorspeed); setmotorspeed2(motorspeed); void go_backward() { pinmode(dirpin1,output); pinmode(dirpin2,output); pinmode(dirpin3,output); pinmode(dirpin4,output); motordir = 0; setmotordir(motordir); setmotorspeed1(motorspeed); setmotorspeed2(motorspeed); void turn_left() { pinmode(dirpin1,output); pinmode(dirpin2,output); pinmode(dirpin3,input);
pinmode(dirpin4,input); motordir = 0; setmotordir(motordir); setmotorspeed1(motorspeed); void turn_right() { pinmode(dirpin1,input); pinmode(dirpin2,input); pinmode(dirpin3,output); pinmode(dirpin4,output); motordir = 0; setmotordir(motordir); setmotorspeed2(motorspeed); void stop_car() { setmotorspeed1(0); setmotorspeed2(0); void func2(){serial.println( FUNCTION ); void func3(){serial.println( FUNCTION ); void func4(){serial.println( FUNCTION ); void setmotordir(int motordir) { if(motordir==1) { digitalwrite(dirpin1,high); digitalwrite(dirpin3,high); digitalwrite(dirpin2,low); digitalwrite(dirpin4,low); else { digitalwrite(dirpin1,low); digitalwrite(dirpin3,low); digitalwrite(dirpin2,high); digitalwrite(dirpin4,high); void setmotorspeed1(int motorspeed) { analogwrite(speedpin1,motorspeed); void setmotorspeed2(int motorspeed) { analogwrite(speedpin2,motorspeed);
<work> static char cmd = '?'; static String inputstring = ""; static boolean stringcomplete = false; struct MenuFunc; extern MenuFunc menu_funcs[]; void initsystem() { void showmenu() { int i; // Serial.println( FUNCTION ); for(i=0;i<sizeof(menu_funcs)/sizeof(menu_funcs[0]);i++) { Serial.print(i+1); Serial.print(". "); Serial.println(menu_funcs[i].pMenu); Serial.println("\nINPUT> "); void getusercmd() { if (stringcomplete) { cmd = inputstring[0]; inputstring = ""; if(cmd!= '\r' && cmd!= '\n') { int cmdindex = cmd - '0' - 1; int howmanycmds = sizeof(menu_funcs)/sizeof(menu_funcs[0]); if(cmdindex>=0 && cmdindex<howmanycmds) { bool * pfuncen = &menu_funcs[cmdindex].enable; *pfuncen =!*pfuncen; stringcomplete = false; void processcmd() { int cmdindex; int howmanycmds = sizeof(menu_funcs)/sizeof(menu_funcs[0]); for(cmdindex=0;cmdindex<howmanycmds;cmdindex++) if(menu_funcs[cmdindex].enable) { menu_funcs[cmdindex].pfunc();
bool * pfuncen = &menu_funcs[cmdindex].enable; *pfuncen =!*pfuncen; void serialevent() { while (Serial.available()) { char inchar = (char)serial.read(); inputstring += inchar; //if (inchar == '\n') stringcomplete = true;
2.5 Bluetooth 로실행하기 1 Plaly Store 에서 SENA BTerm 다운로드 ` 2 메뉴클릭후, Bluetooth Management 클릭
3 Connect to 클릭 4 Select 선택
5 Start Scan 을클릭후, 해당 Bluetooth 모듈주소연결
3. 회로구성도 * 참고동영상 : http://www.youtube.com/watch?v=szcskni0724
4. 참고문헌 레시피로배우는아두이노쿡북 마이클마골리스 아두이노와안드로이드로 45 개프로젝트만들기 서민우