6.BluetoothLE

Edit

6.1BluetoothLE 소개

BluetoothLE(Bluetooth Low Energy, BLE)는 Bluetooth SMART라고도 하며 단거리 무선 통신 기술인 블루투스 4.0 기술중 하나입니다. 기존의 블루투스(Classic Bluetooth)의 과도한 배터리 소모를 해결하기 위해 생겨난 기술로 기본 개념은 기존의 블루투스와 동일하나 전력 소모를 최소화하고 배터리 수명을 연장하는데 중점을 둔 버전입니다. 따라서 적은 전력를 사용하고 데이터 전송량이 작아 느린 속도를 허용하는 BluetoothLE 장치(근접 센서, 피트니스, 심박수, 환경 모니터링 등)와 통신하는데 사용됩니다.

넥사크로플랫폼에서 제공하는 BluetoothLE는 BluetoothLE 장치와 통신 할 수 있게 해주는 오브젝트입니다. BluetoothLE 오브젝트에서 제공하는 기능은 다음과 같습니다.

BluetoothLE 통신은 다음과 같이 진행됩니다.

  1. 스캔: 주변의 연결 가능한 BluetoothLE 장치의 이름과 주소를 검색합니다. 이 때, 다른 장치와 연결되지 않은 주변의 BluetoothLE 장치는 광고 시그널을 주기적으로 브로드캐스팅합니다. 스캔은 이런 주변의 BluetoothLE 장치의 광고 시그널을 청취하여 연결 가능한 장치를 선별하는 과정입니다.

  2. 연결 설정: BluetoothLE 장치의 주소로 연결을 요청합니다. 연결이 설정되면 BluetoothLE 장치는 더이상 광고 시그널을 보내지 않습니다.

  3. 서비스(Service) 검색: 연결된 BluetoothLE 장치가 가진 서비스를 조회합니다.

  4. 서비스의 특성(Characteristic)으로 데이터 조회 및 조작: 각 특성들의 값을 읽어오거나 씁니다.

  5. 연결 종료: BluetoothLE 장치와의 연결을 종료합니다.

BluetoothLE는 Bluetooth 4.0 기술로 안드로이드 4.3(API 레벨18 이상), iOS 5 이상의 환경에서 사용할 수 있습니다.

6.2장치 스캔/연결하기

BluetoothLE 오브젝트를 사용해 BluetoothLE 장치를 스캔하고 연결할 수 있습니다. BluetoothLE를 지원하는 장치만 지원하며 일반 블루투스 장치는 사용할 수 없습니다.

장치를 스캔하려면 scanStart/scanStop 메소드를 사용합니다. 이 메소드는 광고 시그널을 보내는 주변의 장치를 검색하여 이름과 주소(MAC) 정보를 얻습니다.

장치와 연결하려면 connect/disconnect 메소드를 사용합니다. 이 메소드는 장치의 주소로 연결을 수립합니다.

6.2.1예제

다음은 주변의 BluetoothLE 장치를 스캔하고 연결하는 예제입니다. 단순히 스캔과 연결이 가능한지만을 확인할 수 있습니다.

화면이 로딩되면 자동으로 주변 장치에 대한 스캔을 시작합니다. 스캔 시간은 10초로 설정되어 있으며 스캔된 장치는 목록에 표시됩니다. 스캔 시간 내에 장치간의 타이밍이 맞지 않아 스캔에 실패한 경우에는 상단의 리플레시 버튼을 터치하면 다시 스캔을 시작합니다.

스캔이 완료되면 장치 이름과 주소가 Grid에 표시됩니다. 목록에서 장치를 터치하면 연결이 진행되는데 연결 시도중에는 "Connecting"이라 표시되며 연결이 성공하면 "Connected"라고 표시됩니다. 연결이 실패하면 아무 내용도 표시되지 않습니다.

목록에서 이미 연결이 설정된 장치를 다시 터치하면 연결이 해제되고, 다른 장치를 터치하면 기존 연결은 해제되고 새로운 장치로 연결을 시도합니다.

그림 6-1sample_bluetoothle_01

현재 블루투스의 상태는 우측 상단에 있는 아이콘의 모양으로 확인할 수 있습니다. 각 상태에 따른 아이콘 모양은 다음과 같습니다.

모바일 장치의 블루투스 기능이 비활성화 상태입니다.

모바일 장치의 블루투스 기능이 활성화 상태입니다.

주변의 블루투스 장치를 스캐닝하는 상태입니다.

특정 블루투스 장치와 연결이 설정된 상태입니다.

6.2.2예제에서 사용한 핵심 기능

BluetoothLE > scanStart 메소드

광고(advertisement)중인 주변 BluetoothLE 장치를 스캔하는 메소드입니다. 스캔 시간과 서비스 UUID를 인수로 받아 수행할 수 있습니다. 장치가 스캔될 때마다 onscanresult 이벤트가 발생합니다.

BluetoothLE > connect 메소드

주변 BluetoothLE 장치와의 연결을 수행하는 메소드입니다. 메소드 호출시 장치를 식별할 수 있는 인수를 사용합니다. 안드로이드 환경에서는 MAC 주소를 사용하며 iOS 환경에서는 스캔된 장치 목록의 인덱스 값을 사용합니다. 장치의 주소는 onscanresult 이벤트 함수에서 확인할 수 있습니다.

BluetoothLE > disconnect 메소드

연결된 BluetoothLE 장치와의 연결을 해제하는 메소드입니다.

BluetoothLE > onscanresult 이벤트

BluetoothLE 장치가 검색되었을 때 발생하는 이벤트입니다. 검색된 장치의 이름과 주소 정보는 e(BluetoothLEScanDeviceEventInfo) 객체를 통해 얻을 수 있습니다.

6.2.3예제 구현 방법

1

화면 구성하기

BluetoothLE 오브젝트를 추가합니다. 추가된 오브젝트는 Invisible Object 창에서 확인할 수 있습니다.

현재 블루투스 상태를 표시할 Button, ImageViewer 컴포넌트와 검색된 BluetoothLE 장치의 정보를 표시할 Grid 컴포넌트를 예제의 그림과 같이 적절히 배치합니다.

화면 구성을 위해 사용한 컴포넌트 및 오브젝트는 다음과 같습니다.

컴포넌트/오브젝트

ID

BluetoothLE

BluetoothLE00

Button

btn_ble

ImageViewer

img_ble_status

Grid

Grid00

Dataset

ds_address

2

Form 이벤트 함수 작성하기

Form의 onload 이벤트 함수를 다음과 같이 작성합니다. Form이 로딩되면 바로 BluetoothLE 장치를 스캔합니다. scanStart 메소드의 인수로 주어지는 10000은 10초를 의미합니다.

스캔 작업은 배터리 소모를 촉진하므로 스캔 시간을 너무 길게 설정하지 않는 것이 좋습니다.

this.example_bluetoothle_01_onload = function(obj:nexacro.Form,e:nexacro.LoadEventInfo)
{
    this.BluetoothLE00.scanStart(10000);
};

Form의 onbeforeclose 이벤트 함수를 다음과 같이 작성합니다. Form이 종료되기 전 블루투스 연결을 종료합니다.

this.example_bluetoothle_01_onbeforeclose = function(obj:nexacro.Form,e:nexacro.CloseEventInfo)
{
    this.BluetoothLE00.disconnect();
};

3

ds_address Dataset 설정하기

BluetoothLE 장치의 이름과 주소를 저장할 ds_address 데이터셋을 다음과 같이 설정합니다. 설정을 완료한 후 화면에 배치한 Grid 컴포넌트에 바인딩해줍니다.

그림 6-2demo_bluetoothle_01_dataset

4

BluetoothLE 오브젝트 이벤트 함수 작성하기

onsuccess 이벤트 함수를 다음과 같이 작성합니다. BluetoothLE 오브젝트에 요청한 작업이 성공했을 때 호출됩니다. 어떤 이벤트인지는 e.reason 속성의 값으로 확인할 수 있습니다.

this.BluetoothLE00_onsuccess = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEEventInfo)
{    
    switch(e.reason)
    {
        case 10:    //scanStart() scan start
            this.img_ble_status.set_image("imagerc::ico_bluetooth-signal-indicator_128_blue.png");
            break;
        
        case 11:    //scanStart() scan timeout"
            this.img_ble_status.set_image("imagerc::ico_blueetooth-logo_128_blue.png");
            break;
            
        case 12:    //scanStart() discovered for a device that provides specific service
            break;        
        
        case 20:    //scanStop() scan stop
            this.img_ble_status.set_image("imagerc::ico_blueetooth-logo_128_blue.png");            
            break;
        
        case 30:    //connect() connected
            this.img_ble_status.set_image("imagerc::ico_bluetooth-connected_128_blue.png");            
            this.ds_address.setColumn(this.ds_address.rowposition, "StatusMessage", "Connected");
            break;
        
        case 40:    //disconnect() disconnected
            this.img_ble_status.set_image("imagerc::ico_blueetooth-logo_128_blue.png");
            this.resetStatusMsg();
            break;
        
        case 50:    //discoverService() discover service Start        
        case 51:    //discoverService() service discovered    
        case 60:    //subscribe() Subscribe, Notification Start        
        case 61:    //subscribe() Subscribe, Notification message received    
        case 70:    //unsubscribe() Unsubscribe, Notification Stop        
        case 80:    //readCharacteristic() Read Characteristics
        case 90:    //writeCharacteristic() Write Characteristics            
        default:
            break;
    }

};

onerror 이벤트 함수를 다음과 같이 작성합니다. BluetoothLE 오브젝트에 요청한 작업이 실패했을 때 발생하는 이벤트입니다. 어떤 이벤트인지는 e.reason 속성의 값으로 확인할 수 있습니다.

this.BluetoothLE00_onerror = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEErrorEventInfo)
{
    var strResult = "["+ e.eventid +"] "+ e.reason +":"+ e.errormsg;
    alert(strResult);
};

onscanresult 이벤트 함수를 다음과 같이 작성합니다. scanStart 메소드 수행 중 주변 BluetoothLE 장치가 스캔될 때 마다 발생하는 이벤트입니다.

this.BluetoothLE00_onscanresult = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEScanDeviceEventInfo)
{
    var row = this.ds_address.addRow();
    
    this.ds_address.setColumn(row, "DeviceName", e.device_name);
    this.ds_address.setColumn(row, "DeviceAddress", e.device_address);    
};

5

사용자 함수 작성하기

BluetoothLE 장치와의 연결/해제시 상태 메시지를 초기화해주는 함수를 다음과 같이 작성합니다.

this.resetStatusMsg = function()
{
    nRowCnt = this.ds_address.getCount();
    
    for(var i=0; i<nRowCnt; i++)
    {
        this.ds_address.setColumn(i, "StatusMessage", "");
    }
};

6

Grid 이벤트 함수 작성하기

oncellclick 이벤트 함수를 다음과 같이 작성합니다. 검색된 BluetoothLE 장치 목록이 표시된 Gird의 Cell을 터치하면 연결이 수행됩니다. 이전에 연결된 장치가 있으면 연결을 해제합니다.

this.Grid00_oncellclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo)
{
    var rowPos = this.ds_address.rowposition;        
    var strStatus = this.ds_address.getColumn(rowPos, "StatusMessage");
    
    if(strStatus == "Connected")
    {
        this.BluetoothLE00.disconnect();
        return;
    }
    else
    {    
        this.BluetoothLE00.disconnect();
        
        this.ds_address.setColumn(rowPos, "StatusMessage", "Connecting");    
        var strAddr = this.ds_address.getColumn(rowPos, "DeviceAddress");
        this.BluetoothLE00.connect(strAddr);
    }
};

7

Button, ImageViewer 이벤트 함수 작성하기

Button/ImageViewer의 onclick 이벤트 함수를 다음과 같이 작성합니다. Button 혹은 ImageViewer를 터치하면 BluetoothLE 장치와의 연결을 해제합니다.

this.btn_ble_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    this.BluetoothLE00.disconnect();
};

this.img_ble_status_onclick = function(obj:nexacro.ImageViewer,e:nexacro.ClickEventInfo)
{
    this.btn_ble_onclick();
};

8

모바일 장치에서 확인하기

Form이 로딩되면 자동으로 주변 BluetoothLE 장치를 스캔하여 장치 목록을 표시합니다.

연결을 수행하려면 목록에서 원하는 장치를 터치합니다. 장치와의 연결이 성공하면 'connected'라고 표시됩니다. 연결된 다른 장치가 있는 경우 기존의 연결을 해제하고 새로운 장치와 연결을 시도합니다.

연결을 종료하려면 Grid 목록에서 해당 장치 항목을 터치하거나 상단의 블루투스 아이콘을 터치합니다. 버튼을 터치하면 현재 연결이 종료되고 다시 장치 스캔을 시도합니다.

6.3서비스 조회하기

BluetoothLE 장치와 통신하려면 먼저 장치가 어떤 서비스(Service)와 특성(Characteristic)을 제공하는지 알아야 합니다. 그래야 필요한 데이터를 얻기 위해 어떤 서비스로 접근해야 하는지 어떤 특성의 데이터를 조회할 지 판단할 수 있습니다.

특성은 데이터를 나타내는 최소 단위로 데이터를 표현하는 정보와 값으로 구성됩니다. 관련된 특성들을 논리적으로 모아놓은 집합이 서비스이며 서비스는 하나 이상의 특성을 포함할 수 있습니다. 이해를 위해 심박 측정기를 예로 들면 심박 측정기에는 심박 측정이라는 서비스가 존재할 수 있고 심박 측정에 관계된 심박값, 센서 위치값 등의 데이터가 각각의 특성이 될 수 있는 것입니다.

서비스 혹은 특성은 UUID(Universally Unique Identifier) 값으로 식별할 수 있는데 데이터를 조회하거나 명령을 내릴 때 이 UUID 값을 이용합니다. UUID는 16비트(스펙에 공식적으로 명시된) 혹은 128비트(사용자 지정) 숫자로 구성됩니다.

BluetoothLE는 장치간에 데이터를 주고 받는 방법으로 GATT(Generic Attribute) 프로파일을 사용합니다. GATT은 ATT(Attribute Protocol)을 이용하여 두 BluetoothLE 장치간에 데이터를 전송하는 방식을 결정하는 서비스 프레임워크입니다. ATT는 서비스 및 특성이라는 개념을 사용하여 데이터를 전송하는 방식을 정의합니다. GATT에 관한 더 자세한 내용은 다음 링크를 참조하십시오.

https://www.bluetooth.com/specifications/gatt

BluetoothLE 장치가 제공하는 서비스는 BluetoothLE 오브젝트의 discoverService 메소드를 사용해 얻을 수 있습니다. 장치와 연결이 수립된 후 discoverService 메소드를 호출하면 장치가 제공하는 서비스의 UUID 값이 반환됩니다.

이 장에서는 BluetoothLE 장치에서 제공하는 서비스의 UUID 값을 조회하는 방법에 대해 설명합니다. 특성의 UUID 정보는 GATT 표준 문서 및 BluetoothLE 장치 제조업체에서 제공하는 정보를 확인해야 합니다.

6.3.1예제

다음은 연결된 BluetoothLE 장치가 제공하는 서비스를 조회하는 예제입니다. 화면이 로딩된 후 자동으로 주변의 BluetoothLE 장치를 스캔하며 스캔이 완료된 후 검색된 장치 이름을 터치하면 연결이 진행됩니다.

연결이 완료되면 자동으로 해당 장치에서 제공하는 서비스를 검색하고 서비스가 검색될 때 마다 서비스의 UUID를 Service 목록에 표시합니다. 이 때, 서비스의 UUID를 선택하면 서비스에서 제공하는 특성의 UUID가 Characteristic 목록에 표시됩니다.

그림 6-3sample_bluetoothle_02

이 예제에서 사용한 공기질 측정기 에어큐브의 서비스와 특성은 nordic semiconductor 사에서 만든 사양을 사용합니다. 이 사양은 GATT 표준에는 정의되어 있지 않으나 블루투스상에서 UART 통신을 에뮬레이션 할 때 자주 사용되는 사실상의 표준(De facto)입니다.


참고로 GATT 표준에 정의된 서비스인 경우에는 표준 문서에 명시된 특성의 UUID를 이용하면 되고 업체에서 만든 커스텀 서비스인 경우에는 특성의 UUID를 업체에 문의하거나 제공되는 스펙을 참조해야 합니다.

6.3.2예제에서 사용한 핵심 기능

BluetoothLE > discoverService 메소드

연결된 주변 BluetoothLE 장치가 제공하는 서비스 UUID를 요청하는 메소드입니다. 요청에 성공하여 서비스 UUID를 받을 때 마다 onsuccess 이벤트가 발생합니다.

6.3.3예제 구현 방법

1

화면 구성하기

BluetoothLE 오브젝트를 추가합니다. 추가된 오브젝트는 Invisible Object 창에서 확인할 수 있습니다.

현재 블루투스 상태를 표시할 Button, ImageViewer 컴포넌트와 검색된 BluetoothLE 장치의 정보를 표시할 Grid 컴포넌트 그리고 서비스와 특성 정보를 표시할 Static과 Grid 컴포넌트를 예제의 그림과 같이 적절히 배치합니다.

화면 구성을 위해 사용한 컴포넌트 및 오브젝트는 다음과 같습니다.

컴포넌트/오브젝트

ID

BluetoothLE

BluetoothLE00

Button

btn_ble_display

ImageViewer

img_ble_status

Grid

grd_address

grd_service

grd_characteristic

Dataset

ds_address

ds_service

ds_characteristic

ds_uart_characteristic

Static

stt_service

stt_characteristic

2

Form 이벤트 함수 작성하기

Form의 onload 이벤트 함수를 다음과 같이 작성합니다. Form이 로딩되면 바로 BluetoothLE 장치를 스캔합니다. scanStart 메소드의 인수로 주어지는 10000은 10초를 의미합니다.

this.example_bluetoothle_02_onload = function(obj:nexacro.Form,e:nexacro.LoadEventInfo)
{
    this.BluetoothLE00.scanStart(10000);
};

Form의 onbeforeclose 이벤트 함수를 다음과 같이 작성합니다. Form이 종료되기 전 블루투스 연결을 종료합니다.

this.example_bluetoothle_02_onbeforeclose = function(obj:nexacro.Form,e:nexacro.CloseEventInfo)
{
    this.BluetoothLE00.disconnect();
};

3

Dataset 오브젝트 설정하기

BluetoothLE 장치의 이름과 주소를 저장할 ds_address 데이터셋을 다음과 같이 설정합니다. 설정을 완료한 후 화면에 배치한 grd_address Grid 컴포넌트에 바인딩합니다.

그림 6-4demo_bluetoothle_01_dataset

  • DeviceName: BluetoothLE 장치명

  • DeviceAddress: BluetoothLE 주소(MAC)

  • StatusMessage: 연결 상태

BluetoothLE 장치에서 제공하는 서비스 목록을 저장할 ds_service 데이터셋을 다음과 같이 설정합니다. 설정을 완료한 후 화면에 배치한 grd_service Grid 컴포넌트에 바인딩합니다.

그림 6-5demo_bluetoothle_02_ds_service

  • ServiceUUID: 서비스 UUID

서비스의 특성 정보를 저장할 ds_characteristic 데이터셋을 다음과 같이 설정합니다. 설정을 완료한 후 화면에 배치한 grd_characteristic Grid 컴포넌트에 바인딩합니다.

그림 6-6demo_bluetoothle_02_ds_chracteristic

  • CharacteristicName: 특성명

  • CharacteristicUUID: 특성 UUID

UART 서비스에서 제공하는 특성의 UUID를 저장한 ds_uart_characteristic 데이터셋을 다음과 같이 설정합니다. 이 데이터셋은 조회 용도로만 사용하므로 컴포넌트에 바인딩시키지 않습니다. ds_uart_characteristic 데이터셋에 저장한 서비스와 특성의 UUID는 업체에서 정의해서 사용하는 값으로 표준 문서에서는 확인할 수 없습니다.

그림 6-7demo_bluetoothle_02_ds_uart_chracteristic

  • CharacteristicName: 특성명

  • CharacteristicUUID: 특성 UUID

  • ParentServiceUUID: 특성이 소속된 서비스의 UUID

4

BluetoothLE 오브젝트 이벤트 함수 작성하기

onsuccess 이벤트 함수를 다음과 같이 작성합니다. BluetoothLE 오브젝트에 요청한 작업이 성공했을 때 호출됩니다. 어떤 이벤트인지는 e.reason 속성의 값으로 확인할 수 있습니다.

this.BluetoothLE00_onsuccess = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEEventInfo)
{
    switch(e.reason)
    {
        case 10:    //scanStart() scan start
            this.img_ble_status.set_image("imagerc::ico_bluetooth-signal-indicator_128_blue.png");
            break;
        
        case 11:    //scanStart() scan timeout"
            this.img_ble_status.set_image("imagerc::ico_blueetooth-logo_128_blue.png");
            break;
            
        case 12:    //scanStart() discovered for a device that provides specific service
            break;        
        
        case 20:    //scanStop() scan stop
            this.img_ble_status.set_image("imagerc::ico_blueetooth-logo_128_blue.png");            
            break;
        
        case 30:    //connect() connected
            this.img_ble_status.set_image("imagerc::ico_bluetooth-connected_128_blue.png");            
            this.ds_address.setColumn(this.ds_address.rowposition, "StatusMessage", "Connected");
            this.BluetoothLE00.discoverService();            
            break;
        
        case 40:    //disconnect() disconnected
            this.img_ble_status.set_image("imagerc::ico_blueetooth-logo_128_blue.png");
            this.resetStatusMsg();
            this.resetDS();
            break;
                
        case 51:    //discoverService() service discovered
            var row = this.ds_service.addRow();
            this.ds_service.setColumn(row, "ServiceUUID", e.service_uuid);
            this.grd_service.selectRow(row);
            break;
            
        case 50:    //discoverService() discover service Start        
        case 60:    //subscribe() Subscribe, Notification Start        
        case 61:    //subscribe() Subscribe, Notification message received    
        case 70:    //unsubscribe() Unsubscribe, Notification Stop        
        case 80:    //readCharacteristic() Read Characteristics
        case 90:    //writeCharacteristic() Write Characteristics
        default:
            break;
    }
};

onerror 이벤트 함수를 다음과 같이 작성합니다. BluetoothLE 오브젝트에 요청한 작업이 실패했을 때 발생하는 이벤트입니다. 어떤 이벤트인지는 e.reason 속성의 값으로 확인할 수 있습니다.

this.BluetoothLE00_onerror = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEErrorEventInfo)
{
    var strResult = "["+ e.errortype +" "+ e.statuscode +"] "+ e.errormsg;    
    trace(strResult);
};

onscanresult 이벤트 함수를 다음과 같이 작성합니다. scanStart 메소드 수행 중 주변 BluetoothLE 장치가 스캔될 때 마다 발생하는 이벤트입니다.

this.BluetoothLE00_onscanresult = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEScanDeviceEventInfo)
{
    var row = this.ds_address.addRow();
    
    this.ds_address.setColumn(row, "DeviceName", e.device_name);
    this.ds_address.setColumn(row, "DeviceAddress", e.device_address);    
};

5

사용자 함수 작성하기

BluetoothLE 장치와의 연결/해제시 상태 메시지를 초기화해주는 함수를 다음과 같이 작성합니다.

this.resetStatusMsg = function()
{
    nRowCnt = this.ds_address.getCount();
    
    for(var i=0; i<nRowCnt; i++)
    {
        this.ds_address.setColumn(i, "StatusMessage", "");
    }
};

this.resetDS = function()
{
    this.ds_service.deleteAll();
    this.ds_characteristic.deleteAll();    
};

6

Grid 이벤트 함수 작성하기

스캔된 BluetoothLE 장치 목록이 표시된 Grid(grd_address) 컴포넌트의 oncellclick 이벤트 함수를 다음과 같이 작성합니다. Cell을 터치하면 연결이 수행됩니다. 이전에 연결된 장치가 있으면 연결을 해제합니다.

this.grd_address_oncellclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo)
{
    var rowPos = this.ds_address.rowposition;        
    var strStatus = this.ds_address.getColumn(rowPos, "StatusMessage");
    
    if(strStatus == "Connected")
    {
        this.BluetoothLE00.disconnect();
        return;
    }
    else
    {    
        this.BluetoothLE00.disconnect();
        
        this.ds_address.setColumn(rowPos, "StatusMessage", "Connecting");    
        var strAddr = this.ds_address.getColumn(rowPos, "DeviceAddress");
        this.BluetoothLE00.connect(strAddr);
    }
};

연결된 장치의 서비스 목록을 표시하는 Grid 컴포넌트의 oncellclick 이벤트 함수를 다음과 같이 작성합니다. Cell을 터치하면 서비스 특성의 UUID 목록이 grd_characteristic 에 표시됩니다.

this.grd_service_oncellclick = function(obj:nexacro.Grid,e:nexacro.GridClickEventInfo)
{
    var selectedService_uuid = this.ds_service.getColumn(e.row, "ServiceUUID");
    
    this.ds_characteristic.deleteAll();
    
    for (var i=0; i<this.ds_uart_characteristic.getRowCount();i++)
    {
        if( selectedService_uuid == this.ds_uart_characteristic.getColumn(i, "ParentServiceUUID"))
        {
            var row = this.ds_characteristic.addRow();
            
            this.ds_characteristic.setColumn(row, "CharacteristicName", this.ds_uart_characteristic.getColumn(i, "CharacteristicName"));
            this.ds_characteristic.setColumn(row, "CharacteristicUUID", this.ds_uart_characteristic.getColumn(i, "CharacteristicUUID"));
        }    
    }
};

7

Button, ImageViewer 이벤트 함수 작성하기

Button/ImageViewer의 onclick 이벤트 함수를 다음과 같이 작성합니다. Button 혹은 ImageViewer를 터치하면 BluetoothLE 장치와의 연결을 해제하고 주변의 BluetoothLE 장치를 다시 스캔합니다.

this.btn_ble_display_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    this.BluetoothLE00.disconnect();
    this.ds_address.deleteAll();

    this.BluetoothLE00.scanStart(10000);
};

this.img_ble_status_onclick = function(obj:nexacro.ImageViewer,e:nexacro.ClickEventInfo)
{
    this.btn_ble_display_onclick();
};

8

모바일 장치에서 확인하기

Form이 로딩되면 자동으로 주변 BluetoothLE 장치를 스캔하여 장치 목록을 표시합니다. 목록의 장치를 터치하면 연결이 수행되며 장치에서 제공하는 서비스를 요청합니다. 장치로부터 받은 서비스 목록은 Service에 목록으로 표시되며 서비스에 해당하는 특성은 Characteristic 목록에 표시됩니다.

연결을 종료하려면 grd_address Grid 목록에서 해당 장치 항목을 터치하거나 상단의 블루투스 아이콘을 터치합니다. 버튼을 터치하면 현재 연결이 종료되고 다시 장치 스캔을 시도합니다.