Nordic nRF52840 で Zigbee multi_sensor example を試す

# 環境

- 開発ボード アオノドン2019(Raytac MDBT50Q / Nordic nRF52840 搭載) Zigbee エンドデバイスとして使用
- IDE Segger Enbedid Studio
- 開発PC Ubuntu 18.04LTS
- nRF5_SDK_for_Thread_and_Zigbee_v4.0.0_dc7186b

# プログラム

examplesのzigbeeディレクトリ中に以下がある

├── app_utils
│ └── ws2812
├── experimental
│ ├── cli
│ ├── light_control
│ ├── multi_sensor
│ └── multi_sensor_freertos
├── light_control
│ ├── light_bulb
│ ├── light_coordinator
│ └── light_switch
└── ota
├── bootloader
├── client
└── experimental_server

このうち、以下を使用。

├── experimental
│ ├── cli コーディネーター・アオノドン2019で実行
│ ├── light_control
│ ├── multi_sensor  エンドデバイス・アオノドン2019で実行
│ └── multi_sensor_freertos


# センサーノード


- multi_sensor は 100000bps 8N1
- cli は 115200 bps 8N1 ハードウェアフロー制御

UARTの接続パラメータは元々上記のようになってますが、以下に変更しています。

- multi_sensor は 460800bps
- cliは ハードウェアフロー制御を解除


設定方法は以下を参照
「Nordic nRF52840 で Zigbee 照明とスイッチ」(multi_sensorも同様に設定できます)
https://qiita.com/nanbuwks/items/92a76bc68ebb75a58dfd
「Nordic Zigbee CLI Example の UART設定」
https://qiita.com/nanbuwks/items/cf66d56979ad9a2a7a96


multi_sensor を起動すると、以下のように出ます。

```

<info> app: Production configuration is not present or invalid (status: -1)
<info> app: Zigbee stack initialized
<info> app: Device started for the first time
<info> app: Start network steering

```

しばらく待っていると、以下のようにエラーが出るようになります。

```

<error> app: Failed to join network (status: -1)
<error> app: Failed to join network (status: -1)
・・・
```

CLIデバイスで以下のようにします。

```

> bdb role zc
Coordinator set
Done
> bdb start
Started coordinator
Done
```

multi_sensor で以下のように接続したことがわかります。

```

<info> app: Joined network successfully (Extended PAN ID: f4ce365035f26ad5, PAN ID: 0x6B2E)

```

CLIでセンサデバイスを検索します。


```

> zdo match_desc 0xffff 0xffff 0x0104 2 0x0402 0x0403 0
Sending broadcast request.
> 
> 
src_addr=17D5 ep=10
```

短縮アドレスが 17D5 ということがわかったのでこれを元に IEEEアドレスを調べます。

````

zdo ieee_addr 0x17D5
> f4ce36a90365d8fb
Done
```

これに対して、現在の温度を取得します。

```
zcl attr read f4ce3686fe8d957b 10 0x0402 0x0104 0x0000 
> 
ID: 0 Type: 29 Value: 2340
Done

```

同様に、圧力を取得します。

```

> zcl attr read 7bf0 10 0x0403 0x0104 0x0000
> 

ID: 0 Type: 29 Value: 1004
Done
```

リクエストの書式は
zcl attr read <h:dst_addr> <d:ep> <h:cluster> [-c] <h:profile> <h:attr_id>
ですが、アドレス指定は、短縮アドレス／IEEEアドレスどちらでもOKのようです。またパラメータも h: とある箇所は 0x をつけてもつけなくてもOKのようです。

さて、自分のIEEEアドレスを調べます。

```

zdo eui64
f4ce365035f26ad5
Done
```
# 接続


```

zdo bind on f4ce36a90365d8fb 10 f4ce365035f26ad5 64 0x0402 0x05b9
> 
Error: Bind/unbind request timed out

```

エラーが出ましたね

Nordic Dev Zone にて質問してみました。
https://devzone.nordicsemi.com/f/nordic-q-a/60379/zigbee-multi_sensor-example

結果、0x05b9 というのは相手先のショートアドレスを指定するべきだそうで、以下のようにしたら繋がりました。


```

zdo bind on f4ce36a90365d8fb 10 f4ce365035f26ad5 64 0x0402 0x5479
> 
Done

```
繋がりました。
0x5479 となっているのは日を改めているからで、ショートアドレスが変わっています。

## zdo bind on コマンド

上記の zdo bind on 構文の引数は以下の通りです。

- h:source eui64
- d:source ep
- h:destination addr
- d:destination ep
- h:source cluster id
- h:request dst addr

# レポートの購読

```


> zcl subscribe on f4ce36a90365d8fb 10 0x0402 0x0104 0 41
> Done
zcl subscribe on f4ce36a90365d8fb 10 0x0403 0x0104 0 41
> Done

```
これで、
0x0402 Temperature Measurement
および
0x0403 Pressure Measurement が登録されます。

zcl subscribe on 構文のパラメータは以下のとおりです。

- h:addr
- d:ep
- h:cluster
- h:profile
- h:attr ID
- d:attr type
- [d:min interval (s)]
- [d:max interval (s)]



```

log enable info zigbee.report

```
とすると、以下のようにログが取得できます。

```
<info> zigbee.report: Received value updates from the remote node 0x5479
<info> zigbee.report:     Profile: 0x0104 Cluster: 0x0402 Attribute: 0x0000 Type: 41 Value: 3850
<info> zigbee.report: Received value updates from the remote node 0x5479
<info> zigbee.report:     Profile: 0x0104 Cluster: 0x0402 Attribute: 0x0000 Type: 41 Value: 3800
<info> zigbee.report: Received value updates from the remote node 0x5479
<info> zigbee.report:     Profile: 0x0104 Cluster: 0x0402 Attribute: 0x0000 Type: 41 Value: 3750
> 
・
・
・
```

zcl subscribe on しておけばログが取得できるかなと思いましたが、 zdo bind on もしておかないとダメでした。

# 値表現

ここで取得した 0x0402 の値、3850,3800,3750 の値は、-273.15°C <= temperature <= 327.67 ºC,の間の値が 0ºC を Value:0 として、0.01 ºC 単位で表現されます。

cf.,「ZigBee Cluster Library Specification Revision 6 Draft Version 1.0」4.4.2.2.1.1 MeasuredValue Attribute 
 https://zigbeealliance.org/wp-content/uploads/2019/12/07-5123-06-zigbee-cluster-library-specification.pdf

なお、圧力については
-3276.7 kPa <= Pressure <= 3276.7 kPa の値が 0 kPa を Value:0 として、0.1 kPa 単位で表現されます。

cf., 4.5.2.2.1.1 MeasuredValue Attribute




# Zigbee サンプルプログラムで接続情報をクリアする方法

今回のような実験で、エンドデバイスが以下のようなエラーが出たままずっと繋がらない時があります。

```

<error> app: Failed to join network (status: -1)
<error> app: Failed to join network (status: -1)
・・・
```

そのような場合は、CLI も エンドデバイスも 一旦 Segger Embeddid Studio で、Target - Erase All でフラッシュを初期化し、ファームを書き込み直すと接続できるようになります。


そのような処理をして muilti_sensor を起動すると以下のようにシリアルに流れます。

```

Terminal ready
<info> app: Production configuration is not present or invalid (status: -1)
<info> app: Zigbee stack initialized
<info> app: Device started for the first time
<info> app: Start network steering
```

このうち、

```

<info> app: Device started for the first time
```

となれば初期化ができています。

これについて、それぞれの main.c 中に

```

#define ERASE_PERSISTENT_CONFIG            ZB_FALSE                             /**< Do not erase NVRAM to save the network parameters after device reboot or power-off. */

```


とあるのを ZB_TRUE   にすると、接続情報を記憶しなくなります。


なお、エンドデバイスはこれで期待通り動きましたが CLI についてはデバイスを消去しないと新たに接続を受け付けないことがありました。

https://devzone.nordicsemi.com/f/nordic-q-a/49156/zigbee-attribute-reporting-not-reporting-as-configured

によると、この設定にはバグがあるそうです。
このバグが関係しているかどうかは調査中です。