ビーコンのMajor値を場所、Minor値を温度の値としてアドバタイズして、
それを受信する温度管理アプリを作るまでのメモ。
今回は、温度取得のサンプルソースを見てみる
参考
BLE112に関する各種情報。実装に必要な情報はほぼここにある。iOSのサンプルプロジェクトもある。 BLE112 Bluetooth Smart Module
BGScriptのソースは誰かがGithubにアップロードしている Github scott-42/BLE112Examples
調査
今回もリファレンスのソースを読んでみる。
hardware.xml
<?xml version="1.0" encoding="UTF-8" ?>
<hardware>
<!—- 必須。BLE112の場合はこの設定のまま変更しない -—>
<sleeposc enable="true" ppm="30" />
<!—- BLE112の場合は常にfalse。USBはBGAPIプロトコル用に使用(?) -—>
<usb enable="false" endpoint="api"/>
<!—- BLE112の場合は15がMAX。biasは常に5を設定する -—>
<txpower power="15" bias="5" />
<!—- よくわからん… -—>
<usart channel="0" mode="spi_master" alternate="2" polarity="positive" phase="1" endianness="msb" baud="57600" endpoint="none" />
<!—- BGScriptとVMを有効にする(どういうタイミングでfalseにするんだ..?) -—>
<script enable="true" />
<!—- 電源関係? DKBLE112の場合は7 -—>
<pmux regulator_pin="7" />
</hardware>
温度センサーからの入力を受け取るピン番号をhardware.xmlで受け取ると思ったけどここではなさそう。
gatt.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>Thermometer</value>
</characteristic>
<characteristic uuid="2a01">
<properties read="true" const="true" />
<value type="hex">4142</value>
</characteristic>
</service>
<!—- デフォルトはtype=”primary”。primaryの場合、外部に公開されると思うけど ”At the moment the type feature does not have any meaningful use.”とマニュアルに書いてる… ? -—>
<service type="primary" uuid="180A" id="manufacturer">
<!—- シリアルナンバー -—>
<characteristic uuid="2A25">
<properties read="true" const="true" />
<value type="hex">000780c0ffeef00d</value>
</characteristic>
<characteristic uuid="2A24">
<properties read="true" const="true" />
<value>modelnumber</value>
</characteristic>
<characteristic uuid="2A29">
<properties read="true" const="true" />
<value>Bluegiga</value>
</characteristic>
</service>
<!—- 標準サービスUUID。Health Thermometer -—>
<service uuid="1809">
<uri>org.bluetooth.service.health_thermometer</uri>
<!—- 別サービスからインクルード。(設定を見たいのだがどこにある…?) -—>
<include id="manufacturer" />
<description>Health Thermometer Service</description>
<!—- 標準キャラクタリスティックUUID。Temperature Measurement -—>
<characteristic uuid="2a1c" id="xgatt_temperature_celsius">
<description>Celsius temperature</description>
<!—- Characteristic value can be indicated. Indication is confirmed. ここでのindicatedの意味が不明… -—>
<properties indicate="true"/>
<value type="hex">0000000000</value>
</characteristic>
</service>
</configuration>
tempservice.bgs
dim tmp(5)
dim ascii(6)
dim celsius
dim offset
dim a
dim b
dim c
system_boot(major ,minor ,patch ,build ,ll_version ,protocol_version ,hw )
# アドバタイズ有効、ペアリング有効状態にする
gap_set_mode(gap_general_discoverable,gap_undirected_connectable)
# ペアリング有効
call sm_set_bondable_mode(1)
# 一秒毎にhardware_set_soft_timerイベントを呼び出す
call hardware_set_soft_timer(32768,0,0)
# ポート有効化(1,$7ってどのピン…? ディスプレイのことか…)
call hardware_io_port_write(1,$7,$1)
# 1, $7を出力先として設定
call hardware_io_port_config_direction(1,$7)
# SPIに11Bytes出力。SPIに出力するためには、hardware.xmlにusartの設定が必要。
call hardware_spi_transfer(0,11,"\x30\x30\x30\x39\x14\x56\x6d\x70\x0c\x06\x01")
# Change display cursor pos
call hardware_spi_transfer(0,1,"\x80")
# set the display to data mode
call hardware_io_port_write(1,$7,$3)
# Write temperature to display
call hardware_spi_transfer(0,16," Temp Service ")
#set the display to command mode
call hardware_io_port_write(1,$7,$1)
# Change display cursor pos
call hardware_spi_transfer(0,1,"\xc0")
#set the display to data mode
call hardware_io_port_write(1,$7,$3)
#Write temperature to display
call hardware_spi_transfer(0,16,"Temp: ")
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
#set flags
tmp(0:1)=0
#set as float
tmp(1:4)=float(celsius, -1)
#write the temperature information to the GATT database
call attributes_write(xgatt_temperature_celsius,0,5,tmp(0:5))
#Extracting desimals from integer
a = (celsius / 100) #2X.X
b = (celsius / 10) + (a*-10) #X4.X
c = (celsius) + (a*-100) + (b*-10) #XX.8
#+48 is for desimal -> ascii
ascii(0:1) = a + 48 #"2"
ascii(1:1) = b + 48 #"4"
ascii(2:1) = 46 #"."
ascii(3:1) = c + 48 #"8"
ascii(4:1) = $df #"deg"
ascii(5:1) = 67 #"C"
#set the display to command mode
call hardware_io_port_write(1,$7,$1)
# Change display cursor pos
call hardware_spi_transfer(0,1,"\xc6")
#set the display to data mode
call hardware_io_port_write(1,$7,$3)
#Write temperature to display
call hardware_spi_transfer(0,6,ascii(0:6))
#set the advertising data
call gap_set_adv_data(0, 6, ascii(0:6))
end
event connection_disconnected(handle,result)
# in case if disconnect, return to advertisement mode
call gap_set_mode(gap_general_discoverable,gap_undirected_connectable)
end
わかったこと
たぶん、温度センサーはBLE112の内部センサーを利用しており、数値もだいたいあっている。
次回は取得した温度をiBeaconのminor値にセットしたアドバタイズしてみる。