Buletoothで位置検知ができると便利かと思いNordicのAoAの動作確認をしてみました。
ハードウェア環境
- nRF52833DK 2台
- マトリックスアンテナは後日作成するとしてとりあえず無しで試してみました。よって値は位相差無し0度の全部同じになる予定です。
ソフトウェア環境
- nRF ConnectSDK 2.4
構成
nRF52833DK 2台をそれぞれ以下のプロジェクトでビルド&書込み
- Bluetooth: Direction finding connectionless locator (受信側 nRF52833DK 1台を使用)
- Bluetooth: Direction finding connectionless beacon (送信側 nRF52833DK 1台を使用)
nRF ConnectSDKの設定
Direction finding connectionless locator
Create a new applicationでソースの取得
- Application type : Workspce
- nRF Connect SDK : 2.4.0
- Application teplate : direction_finding_connectionless_rx
- build configrationの設定
nRF Connect -> APPLICATION -> direction_finding_connectionless_tx -> Add build configrationを選択
- Bouard : nrf52833dk_nrf52833
- Configration : prj.conf
- Kconfig fragments : board\nrf52833dk_nrf52833.conf
child_image/hci_rpmsg.confの編集
- overlay-aoa.confをコピーし最終行に追加
Direction finding connectionless beacon
Create a new applicationでソースの取得
- Application type : Workspce
- nRF Connect SDK : 2.4.0
- Application teplate : direction_finding_connectionless_tx
- build configrationの設定
nRF Connect -> APPLICATION -> direction_finding_connectionless_tx -> Add build configrationを選択
- Bouard : nrf52833dk_nrf52833
- Configration : prj.conf
- Kconfig fragments : overlay-aoa-.conf と board\nrf52833dk_nrf52833.confの2つを指定
RTT Consoleの設定
main.cにprintk()が使用されていてをれをVSCodeのターミナルに出力ができると便利です。
ついでにprj.confに以下記述を追加します。
- CONFIG_USE_SEGGER_RTT=y
- CONFIG_RTT_CONSOLE=y
- CONFIG_UART_CONSOLE=n
- CONFIG_LOG_BACKEND_RTT=y
- CONFIG_LOG_BACKEND_UART=n
Build
エラーなくBuildができるはずです。
もしエラーが出た場合はnRF Connect SDKの設定が違っているかもです。
私がはまったエラーがあり
Direction finding connectionless beaconの
build configrationの
nRF Connect -> APPLICATION -> direction_finding_connectionless_tx -> Add build configrationで
Kconfig fragments : overlay-aoa-.conf と board\nrf52833dk_nrf52833.confの2つを指定
しないといけませんでした。
エラーの原因を探してprj.confなどを修正するよりもnRF Connect SDKの設定を見直した方が良いかもです。
DEBACK
エラーなく実行ができるはずです。
もしエラーが出た場合はnRF Connect SDKの設定が違っているかもです。
エラーの原因を探して修正するよりもnRF Connect SDKの設定を見直した方が良いかもです。
(NordicのDevZoneでエラーログで検索してもあまり良い情報がなかったりします。)
結果確認
結果としては位相差またはIQ値が得られると思ったのですが、
デフォルトのソースでは出力されませんでした。
main.cに以下のコードを追加することでIQ値が得られます。
static void cte_recv_cb(struct bt_le_per_adv_sync *sync,
struct bt_df_per_adv_sync_iq_samples_report const *report)
{
printk("CTE[%u]: samples count %d, cte type %s, slot durations: %u [us], "
"packet status %s, RSSI %i\n",
bt_le_per_adv_sync_get_index(sync), report->sample_count,
cte_type2str(report->cte_type), report->slot_durations,
packet_status2str(report->packet_status), report->rssi);
printk("Channel index:%x Id of antenna used:%x Value of the paEventCounter:%x Type of IQ samples:%x\n",
report->chan_idx, report->rssi_ant_id, report->per_evt_counter, report->sample_type);
uint8_t *i_q;
char buf[512];
i_q = report->sample;
for (uint8_t scnt = 0; scnt < report->sample_count; scnt++) {
// printk("I:%d Q:%d Count:%d\n", *(i_q + scnt*2) , *(i_q + scnt*2+1), scnt);
snprintk(buf+scnt*9, 10 ,"(%03d,%03d)",*(i_q + scnt*2), *(i_q + scnt*2+1));
}
printk("%s\n", buf);
}
VSCodeのターミナルに以下のログがでるようになります。
CTE[1]: samples count 25, cte type AOA, slot durations: 2 [us], packet status CRC OK, RSSI -500
Channel index:1f Id of antenna used:0 Value of the paEventCounter:8ac Type of IQ samples:0
(230,216)(033,031)(218,227)(041,019)(214,235)(048,007)(211,251)(047,006)(212,014)(229,037)(001,047)(025,037)(037,028)(046,004)(035,225)(021,214)(255,208)(230,217)(211,240)(207,006)(218,028)(241,043)(007,046)(034,030)(046,005)
(a,b)は250 kHz変調でIQ分離された値です。
データがストレートバイナリのため符号付きにしたあと、次に偏角を求めます。
まずはすべてのデータ対して行います。
ここからがポイントです。
最初の8サンプル目は基準と呼ばれるもので1 MHzサンプリングされたものです。
よって、250 kHz変調の波形は正弦波とはならずナイキスト周波数の2倍にしかなりません。
しかし、 1と5、2と6、3と7、4と8は変調250 kHzの360度の値となるため、
1と5、2と6、3と7、4と8の4つの位相差を取りれば
送信受信の2402MHz, 2426MHz, 2480MHzのズレや、変調250 kHzのズレを知ることができます。
9サンプル目以降は250 KHzサンプリングとなります。
それぞれの偏角に対し、基準で求めたオフセット加えてあげると、
位相差に変換できるというものになります。
マトリックスアンテナではなく単一のアンテナのため、もちろん0度になります。
今後マトリックスアンテナを作成して角度を求めてみたいと思っています。
コメントをお書きください
KeiichiKawaoka (土曜日, 05 8月 2023 14:13)
Test