Windows 8.1 低功耗藍牙開發


 

1. 概述

在藍牙4.0發布以前,給大家的直觀印象就是藍牙耳機,它就是用來滿足短距離內中等帶寬的音頻通信需求。然而藍牙4.0發布之后,用途就大不一樣了,特別是現在物聯網和可穿戴之風盛行的年代,很多小玩意都使用了它,如心率計、手環、鑰匙扣等等物件,最終它能夠和用戶的手機、Pad以及PC等設備連接,實現五花八門的功能。為什么藍牙4.0的用途廣泛了呢?首先歸功於低功耗,運行Bluetooth Low Energy的設備,一節紐扣電池可以支持其半年的時間;其次是低成本,如TI公司的CC2540藍牙SoC售價是1美元。自iOS和Android支持藍牙4.0 BLE以后,在今年4月份微軟的BUILD 2014大會上,終於官方宣布在Windows 8.1和Windows Phone 8.1中支持藍牙4.0 BLE,值得注意的是,目前為止,Windows 8.1 只支持GATT Client模式,而不支持GATT Server模式。下面我們就一起來了解一下如何在Windows 8.1平台上開發藍牙 4.0 BLE的應用。

 

2. 設備

首先是配有藍牙4.0的Windows 8.1系統的PC或者平板,以Surface Pro 2為例,可以打開“設備管理器”->藍牙,查看下面的列表,如果里面有“Microsoft Bluetooth LE 枚舉器”的話,如下圖1所示,就說明是支持藍牙4.0 LE的,如果沒有的話,是無法搜索到藍牙4.0 LE設備的,這時候就需要去更新系統和藍牙驅動了。

clip_image002

圖1

注意,在進行這一步以前,最好先去“設置”->“更改電腦設置”->“電腦和設備”->“藍牙”中,把藍牙打開。因為在我測試的時候發現,Surface Pro 2在藍牙關閉的時候,不會出現“Microsoft Bluetooth LE 枚舉器”這一項,如下圖2所示,只有在藍牙打開的情況下才會出現。

clip_image004

圖2

其次,就是藍牙4.0 BLE設備了,目前最流行的應該就是TI的CC2541 Sensor Tag,淘寶上都有賣,價格在200以內。Sensor Tag內部包含了6種傳感器:IR temperature Sensor, Humidity Sensor, Pressure Sensor, Accelerometer, Gyroscope, Magnetometer。

 

3. 准備

如果在Windows設備上第一次使用Sensor Tag,我們還需要手動進行配對工作,這也是在Windows平台上使用藍牙一貫以來的風格,包括以前的Windows Mobile,Windows CE,也包括現在的Windows Phone。當然,第一次使用配對成功以后,后面就不需要再配對了。首先,需要打開藍牙開關,等待TI BLE Sensor Tag的出現,然后點擊它,首次配對的PIN碼為0000。如下圖3所示。

clip_image006

clip_image008

圖3

之后,系統會自動配置GATT服務,配置完成以后,可以去“設備管理器”->藍牙那一項看看,你會發現里面多了很多GATT Services。如下圖4所示。

clip_image010

圖4

有關Sensor Tag提供的服務和對應的UUID,可以參考TI官方的文檔:TI Development KIT

其中用的典型的UUID包括:

Thermometer "f000aa00-0451-4000-b000-000000000000"
Accelerometer "f000aa10-0451-4000-b000-000000000000"
Humidity "f000aa20-0451-4000-b000-000000000000"
Magnetometer "f000aa30-0451-4000-b000-000000000000"
Barometer "f000aa40-0451-4000-b000-000000000000"
Gyroscope "f000aa50-0451-4000-b000-000000000000"
Key Service "0000ffe0-0000-1000-8000-00805f9b34fb"
Generic Access: 00001800-0000-1000-8000-00805f9b34fb
Generic Attribute: 00001801-0000-1000-8000-00805f9b34fb
Device Information: 0000180A-0000-1000-8000-00805f9b34fb

 

4. 創建應用

創建一個Windows Store應用,然后使用記事本或者在View Code下編輯Package.appxmanifest文件,加入以下Capabilities:

<Capabilities>

<Capability Name="internetClient" />

<m2:DeviceCapability Name="bluetooth.genericAttributeProfile">

<m2:Device Id="any">

<m2:Function Type="serviceId:f000aa00-0451-4000-b000-000000000000"/>

<m2:Function Type="serviceId:F000AA10-0451-4000-B000-000000000000"/>

<m2:Function Type="serviceId:F000AA20-0451-4000-B000-000000000000"/>

<m2:Function Type="serviceId:F000AA30-0451-4000-B000-000000000000"/>

<m2:Function Type="serviceId:F000AA40-0451-4000-B000-000000000000"/>

<m2:Function Type="serviceId:F000AA50-0451-4000-B000-000000000000"/>

<m2:Function Type="serviceId:0000ffe0-0000-1000-8000-00805f9b34fb"/>

<m2:Function Type="serviceId:00001800-0000-1000-8000-00805f9b34fb"/>

<m2:Function Type="serviceId:00001801-0000-1000-8000-00805f9b34fb"/>

<m2:Function Type="serviceId:0000180A-0000-1000-8000-00805f9b34fb"/>

</m2:Device>

</m2:DeviceCapability>

</Capabilities>

然后,使用Generic Access Service來讀取Sensor Tag的Device Name,代碼如下:

//Find the devices that expose the service

var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.GenericAccess));

if (devices.Count==0)

return;

//Connect to the service

var service = await GattDeviceService.FromIdAsync(devices[0].Id);

if (service == null)

return;

//Obtain the characteristic we want to interact with

var characteristic = service.GetCharacteristics(GattCharacteristic.ConvertShortIdToUuid(0x2A00))[0];

//Read the value

var deviceNameBytes=(await characteristic.ReadValueAsync()).Value.ToArray();

//Convert to string

var deviceName=Encoding.UTF8.GetString(deviceNameBytes,0,deviceNameBytes.Length);

接着,我們來看看如何讀取加速度傳感器等數據:

//Find the devices that expose the service

var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(new Guid("F000AA10-0451-4000-B000-000000000000")));

if (devices.Count==0)

return;

//Connect to the service

var accService = await GattDeviceService.FromIdAsync(devices[0].Id);

if (accService == null)

return;

//Get the accelerometer data characteristic

var accData = accService.GetCharacteristics(new Guid("F000AA11-0451-4000-B000-000000000000"))[0];

//Subcribe value changed

accData.ValueChanged += accData_ValueChanged;

//Set configuration to notify

await accData.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

//Get the accelerometer configuration characteristic

var accConfig = accService.GetCharacteristics(new Guid("F000AA12-0451-4000-B000-000000000000"))[0];

//Write 1 to start accelerometer sensor

await accConfig.WriteValueAsync((new byte[]{1}).AsBuffer());

訂閱數據變更的notifications,加速度傳感器默認的數據更新頻率是1秒,這個值我們也可以進行修改。

async void accData_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)

{

var values = (await sender.ReadValueAsync()).Value.ToArray();

var x = values[0];

var y = values[1];

var z = values[2];

}

 

5. 使用第三方庫

大家知道,按照上面的步驟來做,自己需要寫很多數據交互的代碼。如果你想偷懶,可以參考一下第三方庫,SebastianL在codeplex上給出了TI Sensor Tag的開源庫,鏈接地址為:Link。目前的版本是1.2,支持Windows 8.1,據作者說支持Windows Phone 8.1的版本會很快到來。使用這個庫很簡單:

第一步,在新建Store應用中加入應用的Capabilities,步驟與上面第4節中的一樣。

第二步,下載X2CodingLab.SensorTag庫,並在項目中添加對X2CodingLab.SensorTag的引用,如下圖5所示。

clip_image012

圖5

第三步,在需要使用Sensor Tag的頁面后台文件中,實例化相應的傳感器,以加速度傳感器為例:

Accelerometer accelerometer = new Accelerometer();

第四步,初始化傳感器,調用封裝好的Initialize()方法:

await accelerometer.Initialize();

如果沒有配對的Sensor Tag,這里會拋出異常DeviceNotFoundException。

第五步,獲取傳感器數據,使用EnableSensor和DisableSensor方法來打開獲取數據的開關,另外,如果獲取數據結束了,最好調用DisableSensor來節省Sensor Tag的功耗。

await accelerometer.EnableSensor();

await accelerometer.DisableSensor();

使用EnableNotifications() 和 DisableNotification()來允許或者禁止數據通知:

private async void Notify()

{

await accelerometer.DisableNotifications();

await accelerometer.EnableNotifications();

accelerometer.SensorValueChanged += accelerometer_SensorValueChanged;

}

void accelerometer_SensorValueChanged(object sender, X2CodingLab.SensorTag.SensorValueChangedEventArgs e)

{

byte[] sensorData = e.RawData;

}

下面是應用運行界面圖。

clip_image014

圖6

再給出實物的圖片吧,紅色的是Sensor Tag。

clip_image016

最后,還是給出源代碼工程的下載鏈接:Link。最近OneDrive不能用,用微盤代替一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM