[아두이노] 2륜 RC카 Bluetooth를 통해 스마트폰(무선) 조정하기
[아두이노] 2륜 RC카 Bluetooth를 통해 스마트폰(무선) 조정하기
- 온라인 가상시뮬레이터 : https://www.tinkercad.com
- 참고 : [아두이노] Bluetooth 통신 제어
- RC Car post 과정 :
[아두이노] L293D Motor Shield+DC MOTOR 제어
[아두이노] 아두이노 RC카 준비
[아두이노] 아두이노 2륜 RC카 주행 패턴 실험
[아두이노] 2륜 RC카 Bluetooth를 통해 스마트폰(무선) 조정하기
[아두이노] 아두이노 RC카를 조정하는 다양한 코딩 접근법
지난시간에는 아두이노 2륜 RC카의 주행 패턴을 실험을 해 보았습니다. 오늘은 실험한 주행 패턴을 가지고 Bluetooth로 한번 조정하는 실험을 하겠습니다. 스마트폰에서 Bluetooth 앱을 미리 깔아놓고 그 앱을 통해서 아두이노 2륜 RC카에 부착된Bluetooth로 명령을 내리고 RC카를 조정하게 됩니다. 아래 사진은 아두이노 RC카에 Bluetooth를 연결한 모습입니다.
1. 2륜 RC카 + Bluetooth 회로도
- 준비물 : Bluetooth, DC 기어모터 2개, L293D Motor Shield, AAx4개 배터리 케이스 배터리 홀더(6V), 아두이노우노
지난시간의 2륜 RC카를 회로도에서 Bluetooth 부품만 추가 연결은 아래와 같습니다.
제가 사용한 L293D Motor Shield에는 따로 Bluetooth를 연결할 수 있는 핀이 없습니다. 대부분 0,1번핀을 이용하여 Serial 통신을 합니다. 전선으로 0, 1번핀을 아두이노와 쉴드 사이에 선을 중간에 묶거나 납탬하는 방법뿐이 없습니다. 대부분 이런식으로 실험을 하지만 자세히 L293D Motor Shield의 기판을 보시면 2번 핀에 구멍이 있고 A0~A5라는 위치에 구명이 뚫려 있습니다. 즉, 핀을 꼽을 수 있는 위치에 핀구멍이 있는데 이 핀구멍을 이용하면 Bluetooth를 쉽게 이용할 수 있습니다.
BlueTooth은 Rx, Tx 핀으로 구성되는데 읽는 핀과 출력 핀으로 나뉩니다. 즉, 2번핀은 디지털핀으로 출력이 가능하고 A0~A5핀은 아날로그핀으로 입력이 가능합니다.
BlueTooth Tx -> Motor Shield A0
BlueTooth Rx -> Motor Shield 2
이렇게 핀 구멍을 활용하면 Bluetooth 통신을 따로 선을 납땜을 할 필요 없이 연결 할 수 있습니다.
2, A0 Pin 위치는 위 사진에서 확인하시고 어느 위치인지 잘 기억해 두세요. Vcc, Gnd pin 위치도 기판에 써있으니깐 보시면 쉽게 찾을 수 있을 꺼에요.
2. 코딩
DC Motor
#include <AFMotor.h>
- AF_DCMotor motor(3) : M3핀을 DC Motor 제어용으로 사용.
- motor.setSpeed(200) : 모터 속도 200으로 설정
- motor.run(FORWARD) : FORWARD, BACKWARD, RELEASE 회전 명령 중 하나를 선택해서 실행 시킴.
SoftwareSerial 통신
#include <SoftwareSerial.h>
- SoftwareSerial mySerial (rx, tx) : 소프트시리얼 객체선언(rx(수신), tx(전송))
- mySerial.begin(9600) : 시리얼 통신 시작(예로 9600 통식속도를 사용해 봤네요.)
- mySerial.write(값) : 데이터 전송
- mySerial.available() : 데이터 들어왔는 확인
- mySerial.read() : 전송된 데이터 1byte 읽기
복습으로, Adafruit Industries에서 제공해주는 Motor 라이브러리 함수를 다시 post에 담았습니다. 중요한 부분이니깐 다시 살펴봐 주세요. 그리고 아두이노 내부 시리얼통신 0,1번 핀으로 실험하는게 아니라 다른 핀을 활용하기 때문에 SoftwareSerial 통신 부분도 다시 복습해 주세요.
1) Bluetooth 연결
#include <SoftwareSerial.h> const int rxPin = A0; const int txPin = 2; SoftwareSerial mySerial(rxPin, txPin); // RX, TX
이렇게 해서 SoftwareSerial 통신 객체를 만들었습니다.
void setup() { mySerial.begin(9600); }
setup()함수안에다 begin()함수로 9600 통신속도로 통신을 시작합니다.
void loop() { if (mySerial.available()){ char ch = mySerial.read(); } }
이렇게 loop()함수에서 bluetooth을 통해 들어온 데이터을 읽게 됩니다. available() 함수를 통해 수신 데이터가 있는지 체크합니다. 수신 데이터가 있게 되면 read()함수로 1byte을 읽게 되는데 char 자료형으로 한 문자를 읽어서 저장하게 됩니다.
이미 예전에 다뤘던 내용인데 혹시 잊으신 분들이 있을 수 있기 때문에 다시 설명을 드립니다.
[0,1번 시리얼통신을 할 경우]
따로, SoftwareSerial 라이브러리를 이용하실 필요는 없습니다.
void setup() { Serial.begin(9600); } void loop() { if (Serial.available()){ char ch = Serial.read(); } }
이렇게 기본 Serial 통신을 이용하시면 됩니다. 0,1번 Pin을 이용할 경우에 이렇게 하고 다른 Pin을 이용할 경우는 SoftwareSerial 라이브러리를 이용하셔야 합니다.
2) 스마트폰에 Bluetooth 앱 설정
안드로이드폰이면 구글스토어에서 Bluetooth 앱을 치시면 아무거나 적당한 것을 다운로드 받아서 설치하시면 됩니다.
앱에서 Controller mode를 선택합니다.
위 그림처럼 버턴에 대한 키값을 지정합니다. 오른쪽 상단에 환경설정 아이콘을 누르시면 아래 창이 뜹니다.
빈칸에 키값을 위에 표시한 알파벳을 등록하시면 됩니다. 그러면 스마트폰에서의 모든 설정은 끝납니다.
3) Bluetooth를 통해 읽은 데이터 값을 통한 동작 제어
Bluetooth를 통해 수신된 데이터 값을 통해서 RC카를 조정하도록 하겠습니다.
전진/후진, 좌/우 명령을 수행한다면 스마트폰 등록된 키값 알파벳 문자들이 수신되면 그 값에 따라서 동작명령을 내려야 합니다.
void loop() { if (mySerial.available()){ char ch = mySerial.read(); } }
위 로직에서 if문 안에 수신된 키값에 대한 Motor를 제어하는 명령을 표현 해야 겠죠.
지난 시간 post에서 주행 패턴을 전부 삽입했습니다. 전진/후진과 좌/우만 넣어도 되지만 그냥 실험한 김에 전부 넣었습니다. 여러분들은 전진/후진과 좌/우와 정지 명령만 표현하셔서 실험하세요. 구지 아래처럼 전부 다 넣어서 실험하실 필요는 없습니다.
switch(ch){ case 'w': motor1.run(FORWARD); //전진 motor2.run(FORWARD); break; case 's': motor1.run(BACKWARD); //후진 motor2.run(BACKWARD); break; case 'a': motor1.run(BACKWARD); //제자리 좌회전 motor2.run(FORWARD); break; case 'd': motor1.run(FORWARD); //제자리 우회전 motor2.run(BACKWARD); break; case 'z': motor1.run(RELEASE); //정지 motor2.run(RELEASE); break; case 'o': motor1.run(RELEASE); //좌회전 motor2.run(FORWARD); break; case 'p': motor1.run(FORWARD); //우회전 motor2.run(RELEASE); break; case 'm': //속도증가 speed+=10; if(speed>=250) speed=250; motor1.setSpeed(speed); motor2.setSpeed(speed); break; case 'n': //속도감소 speed-=10; if(speed<=0) speed=0; motor1.setSpeed(speed); motor2.setSpeed(speed); break; }
위 코딩을 보시면 속도 증가와 감소가 있는데 이 부분은 실제 변화하는 수치는 실험에 사용하는 앱에서는 확인할 수 없어서 불편합니다. 따로 앱인벤터로 전용 Bluetooth를 만들면 되는데 그냥 생략 합니다.
코딩 명령부분만 살펴보면은
speed+=10; if(speed>=250) speed=250;
예전 post에 표현했던 방법인데 speed를 무조건 10씩 증가시키고 그다음 if문에서 max값으로 해서 그 이상 값이 나오면 max로 무조건 speed 값으로 고정시키는 표현입니다. 그러면 반대로 10씩 감소하면 if문으로 min값 이하 값이 되면 무조건 speed값을 min값으로 고정시켠 되겠죠.
speed-=10; if(speed<=0) speed=0;
이렇게 어떤 값의 범위을 벗어날려고 하면 min or max 값으로 고정화 시키는 표현은 자주 사용하는 표현이니깐 잘 기억해 두세요. 다른 곳에서 이 표현을 사용할 수 있으니깐요.
4) 종합 소스
지난 시간의 주행 패턴을 Bluetooth 통신을 한다면 다음과 같습니다.
#include <AFMotor.h> #include <SoftwareSerial.h> const int rxPin = A0; const int txPin = 2; SoftwareSerial mySerial(rxPin, txPin); // RX, TX AF_DCMotor motor1(3); AF_DCMotor motor2(4); int speed =200; void setup() { mySerial.begin(9600); motor1.setSpeed(speed); motor2.setSpeed(speed); motor1.run(RELEASE); motor2.run(RELEASE); } void loop() { if (mySerial.available()){ char ch = mySerial.read(); switch(ch){ case 'w': motor1.run(FORWARD); motor2.run(FORWARD); break; case 's': motor1.run(BACKWARD); motor2.run(BACKWARD); break; case 'a': motor1.run(BACKWARD); motor2.run(FORWARD); break; case 'd': motor1.run(FORWARD); motor2.run(BACKWARD); break; case 'z': motor1.run(RELEASE); motor2.run(RELEASE); break; case 'o': motor1.run(RELEASE); motor2.run(FORWARD); break; case 'p': motor1.run(FORWARD); motor2.run(RELEASE); break; case 'm': speed+=10; if(speed>=250) speed=250; motor1.setSpeed(speed); motor2.setSpeed(speed); break; case 'n': speed-=10; if(speed<=0) speed=0; motor1.setSpeed(speed); motor2.setSpeed(speed); break; } } }
지난시간의 패턴을 전부 키에 등록시켜서 실험하기 때문에 switch()문이 꽤! 길게 코딩이 되었네요.
간단히, 동작 FORWARD, BACKWARD, RELEASE 기준으로 Bluetooth 통신으로 읽은 ch(키값)에 해당된 모터 동작 명령을 내리면 됩니다. 주행 패턴이 지난시간에 실험한 것들과 속도까지 컨트롤 하다보니깐 코딩이 길어졌을 뿐 원리는 아래 코딩이 전부입니다.
switch(ch){ case '키값1': motor1.run(동작1); motor2.run(동작1); break; case '키값2': motor1.run(동작2); motor2.run(동작2); break; }
이 코딩만 이해하시면 됩니다. switch문에서 인수 ch값과 같은 case을 찾고 그 케이스의 라인아래로 명령문들이 수행되는데 break 문을 만나면 switch문을 빠져나오는 로직입니다. 즉, ch값이 키값1이면 motor1.run(동작1)과 motor2.run(동작1) 함수를 수행한뒤에 다음 라인 break문을 만나 switch문을 빠져나오게 됩니다. 만약 동작1을 수행한 뒤에 break문이 없으면 두번째 케이스의 동작2을 수행하게 됩니다. break문이 switch문에서 꼭 필요하니깐 switch문에서 실수하지 말아주세요.
3. 결과
스마트폰으로 조정하면 이렇게 주행을 할 수 있게 됩니다. 이 주행이 정석은 아닙니다. 여러가지 표현 중 하나이고 그 하나를 그냥 소개하는 것일 뿐 다른식으로 조정을 하고 싶다면 한번 코딩에 도전 해보는 것도 괜찮습니다.
마무리
지난 시간의 주행패턴을 전부 사용하다 보니깐 코딩이 길어졌을 뿐 전진/후진, 좌/우 키와 Stop 키로 구성된 5개 키값 만으로 테스트 하셔도 됩니다. 제가 코딩한 것처럼 전부 하실 필요는 없습니다. 좌/우회전 패턴이 2종류인데 원하는 한 종류만 조정값으로 선택하셔도 됩니다.
참고로, speed 코딩이 추가되었는데 어떤식으로 코딩했는지 기억하셨다가 이 원리는 여기뿐 아니라 다른곳에서도 활용이 자주 되는 코딩이라서 원리를 꼭 기억해 주세요.
그렇게까지 어렵지 않습니다. Bluetooth 앱도 구글 검색에서 "앱인벤터 Bluetooth" 키워드로 찾으시면 유튜브 동영상 강좌나 블로그 같은 곳에서 튜토리얼로 잘 나와 있으니깐 따라서 만드시면서 자신만의 Bluetooth 앱으로 개조하셔도 됩니다.
http://ai2.appinventor.mit.edu
이곳에 가셔서 구글계정으로 로그인하면 됩니다. 그리고, 검색하셔서 튜토리얼을 따라서 하시면 됩니다.
이제 여기까지 해서 Bluetooth로 아두이노 RC카를 무선 조정까지 하였습니다. 이제 아두이노 RC카에 어떤 부품을 연결하여 재밌는 것을 만들지 한번 상상의 나래를 펼쳐보세요.
'IOT > 아두이노' 카테고리의 다른 글
[아두이노] 2륜 RC카 원리를 가상시뮬레이터로 실험 (0) | 2019.05.24 |
---|---|
[아두이노] 아두이노 RC카를 조정하는 다양한 코딩 접근법 (0) | 2019.05.23 |
[아두이노] 아두이노 2륜 RC카 주행 패턴 실험 (0) | 2019.05.21 |
[아두이노] 아두이노 RC카 준비 (0) | 2019.05.20 |
[아두이노] L293D Motor Shield+DC MOTOR 제어 (0) | 2019.05.19 |