[아두이노 쿼드콥터] 앱인벤터로 만드는 안드로이드 블루투스 통신앱

Posted by Doony
2015. 11. 25. 01:10 아두이노 드론 프로젝트


안녕하세요 Y.NGneers입니다.


이번에 블로그 개편좀 해봤는데 어떤가요?

변화를 잘 모르시겠다구요? 옆에 카카오톡 친구 추가 버튼을 하나 추가했습니다....ㅋㅋㅋㅋ

모바일에서도, 컴퓨터에서도 잘 되는 것을 확인하였으니...

서로서로 카톡으로 정보 주고받으면서 도움이 되었으면 좋겠습니다.



이번 포스팅은 안드로이드 블루투스 앱을 만드는 편입니다.

궁극적으로는 핸드폰을 통해 실시간영상+조종을 하는 것인데요. 저희가 자바에 대한 지식이 아주 미니멀하기 때문에 앱인벤터를 활용하여 만들기로 했습니다.


일단 실시간 영상부는 라즈베리파이로 따로 실험해보고 있기 때문에 조종기를 어떻게 만드는지만 보도록 하겠습니다.

일단 구동방식은 이렇습니다.


슬라이더를 이용하여 드론의 출력값 조절

핸드폰 기울기를 통해 드론의 움직임 조절


따라서 총 3개의 변수를 안드로이드에서 아두이노로 전송해줘야하는데요. 첫번째는 슬라이더의 값, 두번째는 x축에 해당하는 값, 세번째는 y축에 해당하는 값입니다.





1. 시리얼 통신을 통해 값을 입력받는 알고리즘


기존 저희 포스팅을 보신 분들이라면 아시겠지만, 먼저 저희가 변수를 받는 알고리즘을 설명드리겠습니다.

저희는 현재 시리얼 통신을 통해 드론을 조종하고 있습니다. 따라서 변수를 받는 부분이 아래와 같습니다.



min_output = Serial.parseInt();

x_angle = Serial.parseInt();

y_angle = Serial.parseInt();


네..

입력값은 이런 형태를 띄어야 합니다.


40;170;190


이렇게 되면, min_output인 모터 출력값은 40을, x앵글은 170도(즉 평형인 180도에서 10도 차이나는 기울기), y앵글도 그 반대로 10도 차이나는 값을 입력하는 꼴인데요.


지금은 아두이노 시리얼모니터를 통해 직접 숫자를 입력하고 있죠.

따라서 앱인벤터로 위와 같은 명령을 보내는 앱을 만들어야했습니다.



앱인벤터로 넘어가볼까요?


2. 앱인벤터 코딩


앱인벤터는 누구나? 쉽게 안드로이드 앱을 만들 수 있도록 여러가지 기능을 지원해주고 있는데요.

기본적인 C코딩만 익히신 분들도 충분히 따라하실 수 있으시리라 믿습니다. 




앱인벤터는 굉장히 인터페이스에 충실한듯합니다.

일단 위와 같이 화면을 만들어줍니다. 


하나씩 뜯어볼까요? 위에서부터 보시길.


- Text for ListPicker1 : 블루투스 장치를 확인하기 위한 리스트픽커, 일종의 버튼입니다.


- 노란색슬라이더 : 실제로 앱 실행해보면 좌우로 넓게 퍼져있습니다. 0부터 180까지의 값을 가지게 할겁니다. 왜? 모터가 0부터 180까지의 출력치를 가지니까요.


- Throttle Control : 슬라이더가 가지는 값을 표시하게 될겁니다.


- Text for Label2,3,4 : 핸드폰의 orientation, 즉 기울기 값을 측정하여 각각 표시할겁니다. roll, pitch, yaw가 되겠죠?


이제 이렇게 인터페이스를 구성했으면 블록으로 넘어갑시다. 블록은 크게 2단계로 이루어져 있습니다.

선언부와, 실제 코딩부라고 보면 되는데요. 먼저 선언부를 봅시다.



아두이노 코딩과 마찬가지로 여기서도 변수를 선언해야합니다.


- initialize global (name, x_angle, y_angle) to [] : 괄호 안에 든 변수 3개의 초기값을 0,180 등으로 지정하는 것입니다. 참고로 left는 무시하세요 지우는걸 깜빡했네요.


- When screen1.initialize : 아까 구성한 화면이 screen1입니다. 그 화면이 켜지면, 즉 앱이 실행되면

do set slider1.min, max value to ~~ : 슬라이더의 최소값과 최대값을 0과 180으로 제한하라는 의미입니다.


- when listPicker1.before, after ~~ : 블루투스 쓰신다면 이 부분 복붙하시면 됩니다. 블루투스 장치 찾고 연결하는 코딩입니다.


이제 본격정긴 코딩부로 넘어가봅시다.




복잡해보이지만 크게 2가지로 이루어져 있죠? Orientation 센서, 즉 핸드폰 기울기 센서랑 Slider 부분입니다.


- when Slider.position changed : 슬라이더의 포지션이 바뀌면~~

do set [global name] to ~~thumbposition : 아까 선언한 name이란 변수에 슬라이더의 position을 저장하라는 의미. 즉 아까 0부터 180까지의 수 중에 하나가 저장이 되겠죠 위치에 따라.

do set label1~~~ : name이란 숫자를 label1 의 텍스트로 저장하란 의미입니다. 인터페이스상에서 숫자가 표시됩니다.


- when orientationsensor.orientationchanged : 오리엔테이션, 즉 기울기 센서 값이 변경되면 (실시간적으로 바뀝니다)

do set x_angle,y_angle : 슬라이더와 마찬가지로, x앵글, y앵글이란 변수에 기울기값을 저장합니다.

do label2 to~~ : 마찬가지로 label 텍스트에 기울기값을 띄우라는 것이죠.


if bluetooth.isconnected : 만약 블루투스가 현재 연결이 되어있다면

then call bluetooth~~ join name + ; + x_angle + ; + y_angle

블루투스 장치로 [name;x_angle;y_angle] 이란 텍스트로 명령어를 보내란 소립니다.



어때요, 참 쉽죠?



3. 아두이노 코딩


이제 아두이노 코딩으로 넘어가보죠. 간단하게 하기 위해 예제를 준비했습니다.


int a=0;

int b=0;

int c=0;



void setup() {

  // put your setup code here, to run once:

Serial.begin(115200);

Serial.setTimeout(10);

}


void loop() {

  // put your main code here, to run repeatedly:



Serial.print(a);

Serial.print('\t');

Serial.print(b);

Serial.print('\t');

Serial.print(c);

Serial.println('\t');


}


void serialEvent() {

  while (Serial.available()) {


    a=Serial.parseInt();

    b=Serial.parseInt();

    c=Serial.parseInt();


  }

}


네 단순한 구조입니다.
먼저 정수형 변수 a, b, c 3개를 선언하고, 시리얼 통신으로 그 값을 입력받습니다.
parseInt 를 사용하기 때문에 선언 받는 과정에서 딜레이가 생기는데요.
그 딜레이는 setTimeout() 을 통해 해결할 수 있습니다.

여기서 주의할 점은, 안드로이드와 통신하는 과정에서 위 딜레이를 적절한 수치로 잘 맞춰주어야 변수를 받는데 무리가 없다는 겁니다. 타이밍이 엇나가면 서로 뒤바뀐 수로 통신을 하기도 하더라구요.
저는 10 을 주었습니다. 10ms 죠.


이렇게 해보면, 다음과 같은 영상을 얻을 수 있습니다.




이렇습니다..

시리얼 모니터로 3개의 값을 출력하고 있습니다. 첫번째는 슬라이더값, 두번째는 x기울기값, 세번째는 y기울기값입니다.

화질이 선명하진 않네요..


드론을 조종하기 위해서 이 앱을 사용할 생각입니다. 

pid 튜닝만 완료되는대로 한번 테스트해보도록 하겠습니다!!!