iBeacon温度センサーを作るまで その2


ビーコンのMajor値を場所、Minor値を温度の値としてアドバタイズして、
それを受信する温度管理アプリを作るまでのメモ。

今回は、温度取得のサンプルソースを見てみる

## 参考

BLE112に関する各種情報。実装に必要な情報はほぼここにある。iOSのサンプルプロジェクトもある。 [BLE112 Bluetooth Smart Module](https://www.bluegiga.com/en-US/products/bluetooth-4.0-modules/ble112-bluetooth--smart-module/documentation/)

BGScriptのソースは誰かがGithubにアップロードしている [Github scott-42/BLE112Examples](https://github.com/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値にセットしたアドバタイズしてみる。