工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

BLEモジュール BL652ブレイクアウトボードで遊ぶ(2) --- アドバタイズ ---

概要

BL652ブレイクアウトボードで、アドバタイズを飛ばしてスマホで受信してみた。



背景と目的

前回、BL652ブレイクアウトボードを使うための開発環境を整え動作を確認した。今回は、実用を想定してアドバタイズでデータを飛ばしスマホで受信できるか試す。



詳細

0. 実施環境と参考情報


1. アドバタイズの仕様

Flags、デバイス名、任意データの3種類で構成し、トータルは31バイト。任意データの部分はBL652につないだセンサ値などを入れることでセンサ値を飛ばせる想定だが、今回は動作確認なので適当な値を入れる。

  • AD Structure1
    • Length: 2バイト(0x02)
    • AD Type: Flags(0x01)
    • Flags: LE Limited Discoverable Mode + BR/EDR Not Supported(0x04)
  • AD Structure2
    • Length: 9バイト(0x09)
    • AD Type: Complete Local Name(0x09)
    • Complete Local Name: 8バイト('My BL652')
  • AD Structure3
    • Length: 17バイト(0x11)
    • AD Type: Manufacture Specific(0xFF)
    • Manufacture Specific: 16バイト(0x00~0x0Fまで1ずつ増やす)

※LE Limited Discoverable Modeについての参考

  • LE Limited Discoverable Mode
  • LE General Discoverable Mode


2. コーディング

BL652は、smartBASICという言語でコーディングするのだが、何しろLaird Technology社デバイス用のものなので、Web上の情報は公式資料以外ほぼ皆無。とはいえ、基本はBASICなので、一応VBAを使ってきた経験が役立ちそうな感じ。

というわけで、一から調べると大変なのでサンプルを探したところ、Laird Technology社がgithub公開しているサンプルがあり、その中のBleAdvertStart.sbがちょうどよかったので参考にコーディングしてみた。

動作としては、1分間所定のアドバタイジングパケットを吹くだけ。

DIM addr$ : addr$ =""
DIM scnRpt$ : scnRpt$ =""
DIM advRpt$ : advRpt$ =""
DIM rc

// アドバタイズタイムアウトのイベントハンドラ
FUNCTION HndlrBlrAdvTimOut() 
   PRINT "\nAdvert stopped via timeout"
   PRINT "\nExiting..."
ENDFUNC 0

// デバイス名の設定
// GAP serviceの初期化関数で設定する
DIM deviceName$, nameWritable, nAppearance, nMinConnInterval, nMaxConnInterval, nSupervisionTimeout, nSlaveLatency
deviceName$ = "My BL652" // デバイス名
nameWritable = 0 // nameWritable
nAppearance = 768 // デバイスの種類(768: 温度計)
nMinConnInterval = 500000 // min_conn_interval
nMaxConnInterval = 1000000 // max_conn_interval
nSupervisionTimeout = 4000000 // supervision timeout
nSlaveLatency = 0 // slave latency
rc = BleGapSvcInit(deviceName$, nameWritable, nAppearance, nMinConnInterval, nMaxConnInterval, nSupervisionTimeout, nSlaveLatency)
PRINT "--- New DevName : "; BleGetDeviceName$(); "\n"

// 初期化
DIM discovMode : discovMode = 0 // 
DIM nFlagsAD: nFlagsAD = 0 // 0はFlags=0x04(LE Limited Discoverable Mode + BR/EDR Not Supported)に相当
DIM nAdvAppearance : nAdvAppearance = 0 // Appearance: 0=省略, 1=表示
DIM nMaxDevName : nMaxDevName = 8 // デバイス名(ShortLocalName or CompleteLocalName)の表示バイト数
IF BleAdvRptInit(advRpt$, nFlagsAD, nAdvAppearance, nMaxDevName) == 0 THEN
    PRINT "Advert report initialised\n"
ENDIF

// 追加データ
DIM nTag : nTag = 0xFF
DIM stData$ : stData$="\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F"
IF BleAdvRptAppendAD(advRpt$, nTag, stData$) == 0 THEN
    PRINT "AD with data '";stData$;"' was appended to the advert report\n"
ENDIF

// 確定させる
PRINT BleAdvRptsCommit(advRpt$, scnRpt$)

PRINT "advRpt="; advRpt$; "\n"

// アドバタイズ開始
DIM nAdvType: nAdvType = 3 // 3=ADV_NONCONN_IND=アクティブスキャン拒否, 接続拒否
DIM nAdvInterval: nAdvInterval = 1000 // アドバタイズ周期: 1000msec
DIM nAdvTimeout: nAdvTimeout = 60000 // アドバタイズタイムアウト: 60sec
DIM nFilterPolicy: nFilterPolicy = 0 // 0=ホワイトリスト無効
IF BleAdvertStart(nAdvType, addr$, nAdvInterval, nAdvTimeout, nFilterPolicy) == 0 THEN    
    PRINT "Adverts Started\n"                  
    PRINT "If you search for bluetooth devices on your device, you should see '"; deviceName$; "'\n"
ELSE                                          
    PRINT "\nAdvertisement not successful\n"
ENDIF

// イベント設定
// アドバタイズタイムアウトを設定
ONEVENT  EVBLE_ADV_TIMEOUT  CALL HndlrBlrAdvTimOut

// イベント待ち
WAITEVENT


3. 動作確認

スマホのLightBlueを立ち上げ、スキャンしてみるとデバイスが見つかった。Complete Local Nameが正しく表示されている。詳細なパケットも、以下のように正しく吹かれている。

f:id:dekuo-03:20211007012946p:plain



まとめと今後の課題

BL652ブレイクアウトボードで、アドバタイズを飛ばすことができた。次回は、 、BL652にセンサをつないでセンサ値を飛ばしたい。