BluetoothLE Introduction
BluetoothLE (Bluetooth Low Energy, BLE), also known as Bluetooth SMART, is one of the Bluetooth 4.0 technologies, which is short-range wireless communication technology. It is a technology developed to solve the excessive battery consumption of the existing Bluetooth (Classic Bluetooth). The basic concept is the same as the existing Bluetooth, but this version focuses on minimizing power consumption and extending battery life. Therefore, it is used to communicate with the BluetoothLE devices (proximity sensor, fitness, heart rate, environmental monitoring, etc.) that use less power and allow for slower speeds due to minimal data transmission.
BluetoothLE provided by Nexacro Platform is the object that enables communication with the BluetoothLE device. The functions provided by the BluetoothLE object are as follows.
Bluetooth Device Scan and Connection
Service Search
Reading/Writing Characteristic
Receiving Notifications
The BluetoothLE communication proceeds as follows.
Scan: It searches for names and addresses of connectable BluetoothLE devices nearby. At this time, nearby BluetoothLE devices that are not connected to other devices periodically broadcast the advertising signal. Scan is the process of selecting connectable devices by listening to the advertising signals from nearby BluetoothLE devices.
Connection setting: It requires a connection to the address of the BluetoothLE device. Once the connection is set, the BluetoothLE device will no longer send the advertising signal.
Service search: It searches the services of the connected BluetoothLE device.
Data search and control with service characteristic: It reads or writes values of each characteristic.
BluetoothLE is a Bluetooth 4.0 technology that can be used in Android 4.3 (API level 18 or higher), iOS 5 or later.
Scanning/Connecting Device
You can use the BluetoothLE object to scan and connect to the BluetoothLE device. It only supports the devices that support BluetoothLE, and general Bluetooth devices cannot be used.
The scanStart/scanStop method is used to scan the device. This method searches for nearby devices that send advertising signals, and it obtains name and address (MAC) information.
The connect/disconnect method is used to connect to the device. This method establishes the connection to the address of the device.
${sample}
The following is an example of scanning and connecting to the nearby BluetoothLE device. You can simply check if scanning and connecting are applicable.
When the screen is loaded, the scan is automatically commenced for nearby devices. The scan time is set to 10 seconds and the scanned devices are displayed in the list. If the scan fails because the timing between devices does not match within the scan time, then you can tap the refresh button on the top to start the scan again.
When the scan is complete, the device name and address are displayed on Grid. When you touch the device in the list, the connection starts. During the connection attempt, "Connecting" is displayed, and when the connection is successful, "Connected" is displayed. If the connection fails, then nothing is displayed.
If you touch the device that is already connected in the list again, then the connection is disabled. If you touch another device, then the existing connection is disabled and a new device is attempted for connection.
The current Bluetooth status can be checked with the icon at the top right. The icons according to each status are as follows.
The Bluetooth function of the mobile device is disabled. | |
The Bluetooth function of the mobile device is enabled. | |
It is scanning for nearby Bluetooth devices. | |
It is connected to a specific Bluetooth device. |
${sample_element}
- BluetoothLE > scanStart
This is the method that scans nearby BluetoothLE devices that are being advertised. It can be performed by taking the scan time and service UUID as arguments. The onscanresult event occurs whenever the device is scanned.
- BluetoothLE > connect
This is the method that connects with nearby BluetoothLE devices. It uses the argument that can identify the device when calling the method. In the Android environment, the MAC address is used, and in the iOS environment, the index value of the scanned device list is used. The device address can be found in the onscanresult event function.
- BluetoothLE > disconnect
This is the method that disables the connected BluetoothLE device.
- BluetoothLE > onscanresult
This is the event that occurs when the BluetoothLE device is searched. The name and address information of the searched device can be obtained through the e(BluetoothLEScanDeviceEventInfo) object.
${sample_step}
1
Configuring the Screen
Add the BluetoothLE object. The added object can be checked in the Invisible Object window.
Place the Button and ImageViewer components to display the current Bluetooth status, and the Grid component to display the information of the searched BluetoothLE device appropriately as shown in the example figure.
Components and objects used to configure the screen are as follows.
Component / Object | ID |
---|---|
BluetoothLE | BluetoothLE00 |
Button | btn_ble |
ImageViewer | img_ble_status |
Grid | Grid00 |
Dataset | ds_address |
2
Writing the Form Event Function
Write the onload event function of Form as follows. As soon as the Form is loaded, the BluetoothLE device is scanned. 10000, which is given as the argument of the scanStart method, translates to 10 seconds.
It is not recommended to set the scan time too long as the scan operation accelerates battery consumption.
this.example_bluetoothle_01_onload = function(obj:nexacro.Form,e:nexacro.LoadEventInfo) { this.BluetoothLE00.scanStart(10000); };
Write the onbeforeclose event function of Form as follows. End the Bluetooth connection before the Form is ended.
this.example_bluetoothle_01_onbeforeclose = function(obj:nexacro.Form,e:nexacro.CloseEventInfo) { this.BluetoothLE00.disconnect(); };
3
Setting the ds_address Dataset
Set the ds_address dataset to store the name and address of the BluetoothLE device as follows. Bind it to the Grid component placed on the screen after completing the setting.
4
Writing the BluetoothLE Object Event Function
Write the onsuccess event function as follows. It is called when the requested operation to the BluetoothLE object is successful. You can check which event it is with the e.reason property value.
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; } };
Write the onerror event function as follows. This event occurs when the requested operation to the BluetoothLE object fails. You can check which event it is with the e.reason property value.
this.BluetoothLE00_onerror = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEErrorEventInfo) { var strResult = "["+ e.eventid +"] "+ e.reason +":"+ e.errormsg; alert(strResult); };
Write the onscanresult event function as follows. This event occurs whenever the nearby BluetoothLE device is scanned during the scanStart method execution.
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
Writing the User Function
Write the function that initializes the status message when enabling/disabling the connection with the BluetoothLE device as follows.
this.resetStatusMsg = function() { nRowCnt = this.ds_address.getCount(); for(var i=0; i<nRowCnt; i++) { this.ds_address.setColumn(i, "StatusMessage", ""); } };
6
Writing the Grid Event Function
Write the oncellclick event function as follows. When you touch Cell of Grid with the BluetoothLE device list displayed, the connection is performed. If there is any device that was connected previously, then the connection is disabled.
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
Writing the Button and ImageViewer Event Functions
Write the onclick event function of Button/ImageViewer as follows. Touch Button or ImageViewer to disable the connection with the BluetoothLE device.
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
Checking on the Mobile Device
When Form is loaded, the nearby BluetoothLE devices are automatically scanned and the device list is displayed.
To perform the connection, touch the desired device in the list. If the connection with the device is successful, then it is displayed as 'connected'. If there is another device connected, then the existing connection is disabled and a new device is attempted for connection.
To end the connection, touch the device item in the Grid list or touch the Bluetooth icon at the top. Touch the button to end the current connection and try to scan the device again.
Searching Service
To communicate with the BluetoothLE device, you first need to know what services and characteristics the device provides. In that way, you can determine which service you need to access to obtain the data you need and what the data characteristics are for which you want to search.
The characteristic is the smallest unit that represents data, and it consists of information and values that represent data. The service is the logical collection of related characteristics, and the service can contain one or more characteristics. For example, a heart rate monitor may have a service called heart rate measure, and data, such as heart rate values and sensor position values related to the heart rate measurement, may be the respective characteristics.
The service or characteristic can be identified with the UUID (Universally Unique Identifier) value and this UUID value is used when searching data or issuing commands. UUID is either a 16-bit (officially stated in the specification) or a 128-bit (user-specified) number.
BluetoothLE uses the GATT (Generic Attribute) profile as a method of sending and receiving data between devices. GATT is a service framework that determines how data is transmitted between two BluetoothLE devices using ATT (Attribute Protocol). ATT uses the concept of services and characteristics to define how data is transmitted. Please refer to the link below for more information on GATT.
The services provided by the BluetoothLE device can be obtained using the discoverService method of the BluetoothLE object. When the discoverService method is called after establishing the connection with the device, the UUID value of the service provided by the device is returned.
This chapter describes how to search the UUID value of the service provided by the BluetoothLE device. For the UUID information of the characteristic, you should check the GATT standard document and the information provided by the manufacturer of the BluetoothLE device.
${sample}
The following is an example of searching for the service provided by the connected BluetoothLE device. After the screen is loaded, the nearby BluetoothLE devices are automatically scanned. Touch the searched device name to connect after the scan is complete.
When the connection is established, it automatically searches for the service provided by the device and displays the UUID of the service in the Service list whenever the service is found. At this time, if you select the UUID of the service, the UUID of the characteristic provided by the service is displayed in the Characteristic list.
The services and characteristics of the air quality meter, Air Cube, used in this example uses specifications made by Nordic Semiconductor. Although these specifications are not defined in the GATT standard, it is a de facto standard often used when emulating the UART communication over Bluetooth.
For reference, in the case of a service defined in the GATT standard, you can use the UUID of the characteristic specified in the standard document, and in the case of a custom service made by a vendor, you must contact the vendor for the UUID of the characteristic or refer to the specifications provided.
${sample_element}
- BluetoothLE > discoverService
This is the method that requests the service UUID provided by the nearby connected BluetoothLE. The onsuccess event occurs whenever the request is successful and the service UUID is received.
${sample_step}
1
Configuring the Screen
Add the BluetoothLE object. The added object can be checked in the Invisible Object window.
Place the Button and ImageViewer components to display the current Bluetooth status, the Grid component to display the information of the searched BluetoothLE device, and the Static and Grid components to display the service and characteristic information appropriately as shown in the example figure.
Components and objects used to configure the screen are as follows.
Component / Object | 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
Writing the Form Event Function
Write the onload event function of Form as follows. As soon as the Form is loaded, the BluetoothLE device is scanned. 10000, which is given as the argument of the scanStart method, translates to 10 seconds.
this.example_bluetoothle_02_onload = function(obj:nexacro.Form,e:nexacro.LoadEventInfo) { this.BluetoothLE00.scanStart(10000); };
Write the onbeforeclose event function of the Form as follows. End the Bluetooth connection before Form is ended.
this.example_bluetoothle_02_onbeforeclose = function(obj:nexacro.Form,e:nexacro.CloseEventInfo) { this.BluetoothLE00.disconnect(); };
3
Setting the Dataset Object
Set the ds_address dataset to store the name and address of the BluetoothLE device as follows. Bind it to the grd_address Grid component placed on the screen after completing the setting.
DeviceName: BluetoothLE device name
DeviceAddress: BluetoothLE address (MAC)
StatusMessage: Connection status
Set the ds_service dataset to store the list of services provided by the BluetoothLE device as follows. Bind it to the grd_service Grid component placed on the screen after completing the setting.
ServiceUUID: Service UUID
Set the ds_characteristic dataset to store characteristic information of the service as follows. Bind it to the grd_characteristic Grid component placed on the screen after completing the setting.
CharacteristicName: Character name
CharacteristicUUID: Character UUID
Set the ds_uart_characteristic dataset that stores the UUID of the characteristic provided by the UART service. Since this dataset is used for search only, do not bind it to the component. The UUID of the service and characteristic stored in the ds_uart_characteristic dataset are the values defined and used by the company and cannot be checked in the standard document.
CharacteristicName: Character name
CharacteristicUUID: Character UUID
ParentServiceUUID: UUID of the service to which the characteristic belongs
4
Writing the BluetoothLE Object Event Function
Write the onsuccess event function as follows. It is called when the requested operation to the BluetoothLE object is successful. You can check which event it is with the e.reason property value.
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; } };
Write the onerror event function as follows. This event occurs when the requested operation to the BluetoothLE object fails. You can check which event it is with the e.reason property value.
this.BluetoothLE00_onerror = function(obj:nexacro.BluetoothLE,e:nexacro.BluetoothLEErrorEventInfo) { var strResult = "["+ e.errortype +" "+ e.statuscode +"] "+ e.errormsg; trace(strResult); };
Write the onscanresult event function as follows. This event occurs whenever the nearby BluetoothLE device is scanned during the scanStart method execution.
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
Writing the User Function
Write the function that initializes the status message when enabling/disabling the connection with the BluetoothLE device as follows.
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
Writing the Grid Event Function
Write the oncellclick event function of the Grid (grd_address) component that displays the list of scanned BluetoothLE devices as follows. When you touch Cell, the connection is performed. If there is any device that was connected previously, then the connection is disabled.
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); } };
Write the oncellclick event function of the Grid component that displays the service list of the connected device. When you touch Cell, the UUID list of the service characteristics is displayed in 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
Writing the Button and ImageViewer Event Functions
Write the onclick event function of Button/ImageViewer as follows. Touch Button or ImageViewer to disable the connection with the BluetoothLE device and scan nearby BluetoothLE devices again.
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
Checking on the Mobile Device
When Form is loaded, the nearby BluetoothLE devices are automatically scanned and the device list is displayed. If you touch the device in the list, then the connection is performed and the service provided by the device is requested. The list of services received from the device is displayed as a list in Service, and characteristics corresponding to the service are displayed in the Characteristic list.
To end the connection, touch the device item in the grd_address Grid list or touch the Bluetooth icon at the top. Touch the button to end the current connection and try to scan the device again.