ビーコンのMajor値を場所、Minor値を温度の値としてアドバタイズして、
それを受信する温度管理アプリを作るまでのメモ。
今回は、取得した温度をiBeaconのMinor値に設定してアドバタイズして、iPhoneで温度を表示されるところまでがゴール。
ソース
サンプルのbgsファイルの数行をを変えただけ…
BLE112_project.bgproj
<?xml version="1.0" encoding="UTF-8"?>
<project>
<gatt in="gatt112.xml" />
<hardware in="hardware.xml" />
<script in="iBeacon.bgs" />
<image out="iBeacon_BLE112.hex" />
<device type="ble112" />
<boot fw="bootuart" />
</project>
hardware.xml
<?xml version="1.0" encoding="UTF-8" ?>
<hardware>
<sleeposc enable="true" ppm="30" />
<usb enable="false" />
<txpower power="15" bias="5" />
<port index="0" tristatemask="0" pull="up" />
<script enable="true" />
</hardware>
gatt112.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<service uuid="1800">
<description>Generic Access Profile</description>
<characteristic uuid="2a00">
<properties read="true" const="true"/>
<value>iBeacon Demo</value>
</characteristic>
<characteristic uuid="2a01">
<properties read="true" const="true"/>
<value type="hex">0200</value>
</characteristic>
</service>
<service uuid="180a">
<description>Device Information</description>
<characteristic uuid="2a29">
<properties read="true" const="true" />
<value>Bluegiga BLE112</value>
</characteristic>
<characteristic uuid="2a24">
<properties read="true" const="true" />
<value>112</value>
</characteristic>
<characteristic uuid="2a26">
<properties read="true" const="true" />
<value>1.2.1</value>
</characteristic>
<characteristic uuid="2a27">
<properties read="true" const="true" />
<value>1.0</value>
</characteristic>
</service>
</configuration>
iBeacon.bgs
dim advdata(30)
dim celsius
dim offset
dim a
dim b
dim c
dim x
# system boot event listener
event system_boot(major, minor, patch, build, ll_version, protocol_version, hw)
# 一秒毎にhardware_set_soft_timerイベントを呼び出す
call hardware_set_soft_timer(32768,0,0)
# Set advertisement interval to 125ms.
# Use all three advertisement channels
call gap_set_adv_parameters(200, 200, 7)
# Initialize iBeacon ADV data
# Flags = LE General Discovery, single mode device (02 01 06)
advdata(0:1) = $02
advdata(1:1) = $01
advdata(2:1) = $06
# Manufacturer data
advdata(3:1) = $1a
advdata(4:1) = $ff
# Preamble
advdata(5:1) = $4c
advdata(6:1) = $00
advdata(7:1) = $02
advdata(8:1) = $15
# Apple AirLocate Service UUID: e2c56db5-dffb-48d2-b060-d0f5a71096e0
advdata(9:1) = $e2
advdata(10:1) = $c5
advdata(11:1) = $6d
advdata(12:1) = $b5
advdata(13:1) = $df
advdata(14:1) = $fb
advdata(15:1) = $48
advdata(16:1) = $d2
advdata(17:1) = $b0
advdata(18:1) = $60
advdata(19:1) = $d0
advdata(20:1) = $f5
advdata(21:1) = $a7
advdata(22:1) = $10
advdata(23:1) = $96
advdata(24:1) = $e0
# Major : 01
advdata(25:1) = $00
advdata(26:1) = $01
# Minor : 00
advdata(27:1) = $00
advdata(28:1) = $00
# Measured TX power : -58
advdata(29:1) = $c6
# Set advertisement data
call gap_set_adv_data(0, 30, advdata(0:30))
#set to advertising mode - with user data
call gap_set_mode(4, gap_undirected_connectable)
end
# タイマーイベント
event hardware_soft_timer(handle)
# BLE112内部の温度センサーから温度を取得
#
# Call ADC read
# 14 = internal temperature sensor
# 3 = 12 effective bits
# 0 = Internal 1.24V reference
call hardware_adc_read(14,3,0)
end
# ADCの結果を取得した時のイベント
event hardware_adc_result(input,value)
offset=-1500
# ADC value is 12 MSB
celsius = value / 16
# Calculate temperature
# ADC*V_ref/ADC_max / T_coeff + offset
celsius = (10*celsius*1150/2047) * 10/45 + offset
# Extracting desimals from integer
a = (celsius / 100) #2X.X
b = (celsius / 10) + (a*-10) #X4.X
c = (celsius) + (a*-100) + (b*-10) #XX.8
# 整数と小数に分けてアドバタイズデータに設定
advdata(27:1) = (a*10) + b
advdata(28:1) = c
call gap_set_adv_data(0, 30, advdata(0:30))
end
# Disconnection event listener
event connection_disconnected(handle, result)
call gap_set_adv_parameters(20, 100, 7)
#set to advertising mode - with user data
call gap_set_mode(4, gap_undirected_connectable)
end
とりあえず完成
iOS側の実装はよくあるiBeaconの実装なので省略。
最後の3はBLE113を使っている(1と2はBLE112)。温度が全然合ってない。内部の温度センサーを使うのはやっぱりよくないのか…
まとめ
-
第1回目のiBeaconサンプルより今回の方がシンプル(gatt.xmlにUUIDとかを設定しないでもよい)
-
Minor値は16bitまで設定できるから、28.5度なら285と設定して最後の一桁を小数と設定しようとしたが分からず。とりあえず最初の8bitを整数。次の8bitを小数とした。(例:0001101100000010から27.2度をなんとか計算してます…