유투브:아두이노,앱인벤터,파이선

Remake: 알기쉬운 안드로이드 스튜디오 아두이노 Bluetooth LED Toggle 예제

coding art 2022. 4. 30. 15:14
728x90

안드로이드 스튜디오에서 꼭 작성해보고 싶은 코드가 바로 무선 WiFi 라든지 또는 Blurtooth 통신일 것이다. 주어진 순서대로 따라해서 100% 성공하세요.

 

ListView를 충분히 연습했으면 ListView 기법을 사용하는 블루투스 코드를 다루어 보기로 한다. 스마트 폰 간의 사진파일 전송 기법이 있을 수 있으나 그 보다 간단한 블루투스 클라이언트 응용으로서 스마트폰에서 원격으로 아두이노 우노 보드의 13번 붙박이 LED Toggle 방식으로 ON/OFF 하고 아울러 아두이노로부터 문자열 Count + 숫자를 Read Buffer에서 출력해 보기로 한다. 물론 이 정도의 블루투스 LED on/OFF 코드는 앱 인벤터에서 아주 쉽게 코드 작성이 가능하긴 하지만 그래도 원조 격인 안드로이드 스튜디오를 사용하여 블루투스를 실행해 본다는 것은 코드 작성 능력 향상에 상당히 큰 도움이 되리라 본다.

 

안드로이드 스튜디오 IDE에서 다운받은 코드를 열어둔 상태에서 새 프로젝트 명칭만 바꾸어서 복사 붙이기 기법을 사용하여 성공하더라도 안드로이드 스튜디오 코딩 기법을 상당부분 이해하게 될것이다.

 

스텝 0. 안드로이드 스튜디오를 오픈하면 앞서서 작업했던 코드가 뜸과 동시에 아래의 툴바를 볼 수 있을 것이다. 새로운 앱 코딩을 위한 프로젝트 파일을 생성하려면 File-->New-->New Project... 를 클릭하자.

 

 

스마트폰 폼팩터와 연관된 선택을 요구하는 팝업 창에서 초보자라면 무조건 Empty Activity 를 클릭해야만 한다.

 

 

스텝 1. New Project에서 프로젝트 명 처리

사용자가 앱코드의 파일명 즉 Name을 설정하고 Finish 버튼을 클릭한다.

 

 

아래와 같은 새 프로젝트 스크린 화면이 "디폴트 디렉토리 트리(Tree)구조"와 함께 우측에 기본적인 activity_main.xml 과 MainActivity.java 화면이 나타난다. 초보자라면 kotline 설정은 차후에 스스로 배울것을 권장한다. 안드로이드 스튜디오는 형식 면에서 복잡하다고 여길 수 있는 만큼 "ENTER"키만 몇번 두들리면 될 정도로 가장 쉽게 배우도록 하자.

 

 

"디폴트 디렉토리 트리(Tree)구조"에서 manifest와 res-->layout 폴더를 클릭하면 현재 프로젝트의 기본 폴더 구조를 확인할 수 있다. 

AndroidManifest.xml:  프로젝트 파일 명 과 아울러 시스템 툴 선언--> 예를 들면 Bluetooth  와 같은 통신 기능

MainActivity: 말 그대로 메인 프로그램에 해당한다.

activity_main.xml: 메인 프로그램 수행에 수반되는 스마트폰 화면 입출력 처리-->버튼을 비롯한 각종 위젯 탑재를 지원하며 즉 텍스트 이미지 여부, 크기, 색상을 포함하는 이들의 속성을 부여할 수 있다.

 

 

초기에 사용자가 부여했던 파일 명 정보들이 포함되어 있음을 확인할 수 있으며 아울러 MainActivity.java 파일의 첫줄에서도 앱 프로젝트 명이 같아야 함을 알 수 있다. 

  

 

아울러 스마트폰의 bluetooth 통신을 위해서는 아래에서 볼 수 있는 것처럼 임시로 단말기 통신하드웨어 사용 승인(uses-permission)을 받아야 할 것이다. 이와같이 세부적인 코딩에 앞서 전체 시스템적인 설정을 Android.Manifest.xml에서 처리해야 하는 것이다.

 

 

스텝 2. reslayoutactivity_main.xml 레이아웃의 padding 디자인

처음에 스마트폰 화면 구성이 constriantlayout 으로 설정되어 있다면 반드시 Relativelayout으로 변경해 두자.

Relative 란 참조할만한 위치에 대해서 상대적인 위치를 시벡 코딩할 수 있는 편리성을 제공한다. 아울러 "Hello World" 는 필요 없으므로 TextView 전체를 지워버리자.

 

 

스마트 폰 화면 전체 즉 android: layout_width 와 android: layout_height이 이미 “match_parent” 즉 스마트폰 화면 전체로 설정되어 있음을 확인하자. 이어서 좌우 상하 padding 10 dp로 설정하여 침범할 수 없도록 여백을 설정하자. 

android:padd까지 타이핑하면 관련 명령 메뉴가 자동으로 뜨므로 paddingBottom 을 선택 클릭하면 =" "이 나타난다.

 

 

" " 에 10dp 를 입력하자.

 

 

스텝 3. activity_main.xml 의

RelativeLayout 내부에서 다시

  - LinearLayout을 취하여  그 내부에

     - CheckBox 와 아울러

     - 2개의 TextView를 갖는 LinearLayout, 이어서

     - 4개의 Button들, 그리고

     - ListView 로 

전체 레이아웃을 완성한다.

 

 

스텝 4. 2개의 TextView는?

RX: , <Read Buffer>를 디스플레이 하지만 이번 예제의 특성 상 Toggle 신호를 아두이노에게 블루투스로 송신하지만 거꾸로 아두이노로부터 millis 시간 코딩에 의해서 count number를 보내므로 수신이 필요하다. 한편 Status:,<Bluetooth Status> 부분은 스마트폰 상황에 따라 상황이 디스플레이 된다 3가지 경우가 있는 바 Enabled, Bluetooth disabled, Connected to Device:HC-06  3종류 메시지이다.

 

 

 

스텝 5. ON, OFF, SHOW PAIRED DEVICES, DISCOVER NEW DEVICES 버튼

실제 블루투스를 작동시키기 위해서는 스마트폰 알림줄을 클릭하여 블루투스를 ON OFF 시키지만 이 부분을 코드화 하였으므로 BLUETOOTH ON, OFF 버튼이 그 역할을 수행한다.

 

스텝 6. 주변 블루투스 중 하나와의 Pairing  ID 출력

 

주변에 산재한 블루투스들이 ListView 에 의해 리스팅 되면 그 중에 하나를 선택 클릭하여 Connected to Device:HC-06 상태를 만들어야 블루투스 통신이 가능해 진다. 직접 블루투스 ID 를 터치 클릭하면 페어링 연결이 된다. 현재의 디바이스와의 통신을 끓고 다른 디바이스를 찾아서 통신하려면 NEW DEVICES 버튼을 사용해야 한다.

통신 연결이 되면 체크박스 클릭에 의해 Toggle 신호를 아두이노 보드에 보낼 수 있다.

 

 

스텝 7. ListView 설치

마지막 부분에 ListView를 설치하자. ListView 는 경우에 따라서 주변에 블루투스 소스들이 대단히 많으면 스크롤하여 원하는 소스를 찾아서 선택 클릭할 수 있는 기능을 제공한다. 안드로이드 스튜디오 코딩을 하고자하면 반드시 습득해야 할 부분이다. ListView 관련 MainActivity에서의 코딩은 항상 3개 요소 즉 저장을 위한 ArrayList, 리스팅 할 디바이스 데이터 및 연결을 위한 Adapter를 준비해야 한다. 여기까지가 activity_main.xml 코딩이다.

 

스텝 8. MainActivity.java의 변수 멤버

스마트폰에서의 블루투스 통신 코드의 실행은 동시 다발적인(concurrently multi-threaded) 특성을 가지고 있다. 즉 매 순간 마다 스마트 폰 화면의 업데이트를 진행하는 하나의 메인 코드 (main thread) 실행만으로 끝나는 것이 아니다. 항상 별도로 내부에서 블루투스 데이터의 수신 및 송신을 담당하는 background worker thread  mConnectedThread가 있어 메인 코드와의 협업을 담당하는 Handler를 통해 데이터를 넘겨주거나 받게 된다. 이 작업이 원활하게 이루어지지 않으면 그래픽 병목현상이 발생하여 스마트 폰 화면이 반응하지 못하게 되므로 싱크로(Synchronization)를 위해 scheduler에 의해 통제를 받아야 할 것이다. 특히 background work 은 사용자가 앱을 사용하지 않더라도 계속 실행되므로 전원소모가 많아지므로 사용치 않을때에는 반드시 끄도록 하자.

 

이와 같은 블루투스 코드 실행은 매번 반복 때 마다 스마트폰 화면 시작 단계의 onCreate 이벤트를 감청(Listen)함과 아울러 화면 상의 텍스트 내용(TextView) 업데이트 상황을 처리할 수 있도록 Graphic User Interface(GUI)를 구성하는 모든 아이템들을 MainActivity Class에서 한 번에 참조할 수 있도록 모았다. 이 부분은 코딩이 아니라 무조건 디폴트로 넣어두어야 하는 내용이다.

 

스텝 9. MainActivity.java onCreate 이벤트 처리

첫 번째 @overide protected void onCreate을 검토해 보자. protected 이므로 subClass 범위까지 공유가 가능하다. 다시 말하자면 @이하 override 되는 부분이 subClass 라면 그 상위의 superClass가 있을것이므로 overide 즉 연동시킨다는 뜻이다. 즉 @ 기호가 들어가야 빌드를 담당하는 Compiler 가 알아 먹을 수 있게 된다.

 

구성 내용을 보면 첫 부분에 스마트 폰 화면에서 다루는 모든 정보를 처리하기 위한 변수 값을 가져 오게 된다. 쉽게 말하자면 아두이노에서 setup( ) 과 유사한 기능에 해당한다.

 

스텝 10. 아울러 Handler 에 의해서 Read Buffer  BluetoothStatus 값을 처리할 수 있도록 msg.what 이 MESSAGE_READ 인지 아니면 CONNECTING_STATUS 인지 따져서 확인한다. 만약 MESSAGE_READ 라면 문자열 버퍼 readMessge를 체크하여 mReadBuffer에 저장하도록 한다.

 

 

스텝 11. 그리고 CONNECTING_STATUS 경우에는 mas.arg1을 체크하여 “1”이면 “Connected to Device” “1”이 아니면 “Connection Failed”를 <Bluetooth Status>에 디스플레이 하도록 한다.

 

스텝 12. 아울러 mBTArrayAdapter  null 로 체크 되면 해당 메시지를 mBluetoothStatus 뿐만 아니라 아예 Toast 디스플레이까지 해버리자.

 

 

스텝 13. 반면에 mBTArrayAdapter  null 이 아니라면 즉 다음의 5가지 중 어느 하나의 블루투스 작업을 진행하자. mLED1.setOnClickListner 는 블루투스로 아두이노 보드의 LED Toggle 하는 명령을 실행한다.

 

 

스텝 14. mScanBtn.setOnClickListener는 스마트 폰의 위부분에 위치하고 있는 블루투스 스위치를 코드에 의해서 ON 시키는 명령이며 mOffBtn.setOnClickListener는 그 반대이다. 나머지 버튼을 포함하여 블루투스를 사용해 본 경험이 있다면 그 기능을 쉽게 이해 할 수 있을 것이다.

                                                              

스텝 15. 아두이노 블루투스 코딩

아두이노 우노 보드에서 핀 0 1번을 사용해서 HC-06 블루투스 배선을 하자. 하지만 0 1번 배선을 제거한 상태에서 업로딩을 완료하고 0 1번 점프선 배선을 완료하자. 전원이 ON 되어 있으면 블루투스 페어링이 이루어지기 전까지는HC-06 LED 가 다소 빠르게 점멸 한다. 안드로이드 스마트폰과 페어링이 이루어지면 점멸이 멈추게 된다.

 

다음의 블루투스 데모 유튜브 영상 참조하세요. 보실 경우 구독 좋아요 꼭 부탁드려요!

https://youtu.be/0IfNtPE0wyw

 

 

첨부된 안드로이드 스튜디오 코드를 다운받아 실행해 보자. 2년 전과 동일한 내용이지만 최신 안드로이드 스튜디오에서 업그레이드 되었음을 참조하세요.

 

MyBluetooth.zip
0.14MB

 

첨부된 아두이노 코드도 복사하여 활용하자.

//BT_LED_Toggle.ino

//LED Toggle by Android Bluetooth
unsigned long previousMillis = 0; // will store last time
const long interval = 3000;// interval at which to delay
static uint32_t tmp; // increment this

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  if (Serial.available()) { // check if anything in UART buffer
    if(Serial.read() == '1'){ // did we receive this character?
       digitalWrite(13,!digitalRead(13)); // if so, toggle the onboard LED
    }
  }
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    Serial.print("Count: ");
    Serial.print(tmp++); // print this to bluetooth module
  }
}//끝

 

이 코드를 사용하여 RC CAR 조종을 위한 앱코드 작성을 원하면 아래 블로그 첨부 코드를 참조하기 바란다.

http://blog.daum.net/ejleep1/1285