iBeacon温度センサーを作るまで 第3回


ビーコンの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

```

## とりあえず完成

![](https://dl.dropboxusercontent.com/u/72730511/iOS%20Screenshot%2020140727-194929%2001.png "")

iOS側の実装はよくあるiBeaconの実装なので省略。

最後の3はBLE113を使っている(1と2はBLE112)。温度が全然合ってない。内部の温度センサーを使うのはやっぱりよくないのか…

## まとめ

* 第1回目のiBeaconサンプルより今回の方がシンプル（gatt.xmlにUUIDとかを設定しないでもよい）

* Minor値は16bitまで設定できるから、28.5度なら285と設定して最後の一桁を小数と設定しようとしたが分からず。とりあえず最初の8bitを整数。次の8bitを小数とした。（例:0001101100000010から27.2度をなんとか計算してます…