Nordic nRF52840 で Zigbee

Nordic nRF52840 で使える無線通信は Bluetoothだけではなく、

- Zigbee
- Thread
- ANT
- NFC
- Nordic独自プロトコル

が使える。この中の Zigbee を使ってみた。

# Nordic の対応

Nordic はいろんなチップにおいて Zigbee 使えるお！ としているが、現在(2020/02/14) まともに使えるのは nRF52840 のみのようだ。

nRF52840は、Zigbeeの認証を取得している。
「Nordic SemiconductorのマルチプロトコルSoC nRF52840および 開発キットがZigbee準拠プラットフォームとしての認証を取得」
https://www.nordicsemi.com/News/2018/09/nRF52840-SoC-and-supporting-dev-kit-certified-as-a-Zigbee-Compliant-platform?lang=ja-JP



nRF52832 対応していないらしい
https://devzone.nordicsemi.com/f/nordic-q-a/37602/zigbee-thread-support-for-nrf52832

nRF52811 対応していないらしい
https://devzone.nordicsemi.com/f/nordic-q-a/55285/52811-zigbee-support/228590#228590

nRF52833 SDKでは対応しているぽいが、Zigbee準拠認証はまだ得られていないらしい
> nRF52833 Zigbee compliant platform with the ZBOSS stack and the nRF52840 (and soon nRF52833)


# 使い方

## SDK ダウンロード

Bluetooth用のSDKとは異なるSDKが必要らしい

nRF5 SDK for Thread and Zigbee
https://www.nordicsemi.com/Software-and-Tools/Software/nRF5-SDK-for-Thread-and-Zigbee
から、nRF5_SDK_for_Thread_and_Zigbee_v4.0.0_dc7186b.zip をダウンロードして解凍。

このSDK用のドキュメントはこちら
https://infocenter.nordicsemi.com/index.jsp?topic=%2Fstruct_sdk%2Fstruct%2Fsdk_thread_zigbee_latest.html

## サンプルプログラム

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

# スマート照明を実験

今回、light_bulbを試してみる。

ドキュメントはこちら
https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.thread_zigbee.v2.0.0/zigbee_example_light_control.html

## 環境

- 開発ボード アオノドン2019(Raytac MDBT50Q / Nordic nRF52840 搭載)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/87636065-85a3-13e0-ef44-72d73b57480f.png)

- IDE Segger Enbedid Studio
- 開発PC Ubuntu 18.04LTS
- Zigbee コーディネーター Amazon Echo Plus


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/65990a84-2deb-5c8c-311e-e24434b7bde1.png)


## zigbee_light_bulb

このプログラムは照明のエンドデバイスとして動作する。

- pca10056 (nF52840ボード)
- pca10059 (nRF52840ドングル)
- pca10100 (nRF52833ボード)

用のものが用意されている。

アオノドン2019 はI/O構成が pca10056 に準拠しているので

(SDKディレクトリ)/zigbee/light_control/light_bulb/pca10056/blank/ses/zigbee_light_bulb_pca10056.emProject 

を開く。

pca10056のI/Oは、以下のように使用されている。

|プログラム上のシンボル|ボード定義|ボード上の機能|GPIO割当|機能|
|:---:|:---:|:---:|:---:|:---:|
| ZIGBEE_NETWORK_STATE_LED|BSP_BOARD_LED_2|オンボードLED3|GPIO0.15| Zigbee ネットワーク接続中：点灯|
|BULB_LED|BSP_BOARD_LED_3|オンボードLED4|GPIO0.16|調光照明として機能|
|WS2812_LED_CHAIN||外部にWS2812LEDストリップを接続|GPIO1.07|調光照明として機能|




アオノドン2019のI/Oに合わせて以下のように設定します。

|プログラム上のシンボル|ボード定義|ボード上の機能|GPIO割当|機能|
|:---:|:---:|:---:|:---:|:---:|
| ZIGBEE_NETWORK_STATE_LED|BSP_BOARD_LED_2|オンボードLED青|GPIO0.15| Zigbee ネットワーク接続中：点灯|
|BULB_LED|BSP_BOARD_LED_0|オンボードLED赤|GPIO0.13|調光照明として機能|
|WS2812_LED_CHAIN||外部にWS2812LEDストリップを接続|GPIO1.07|調光照明として機能|

## LED論理の変更

アオノドン2019はオンボードLED3つで4番目は搭載されていないのでBULB_LEDの割当を変更する。
また、pca10056のオンボードLEDは負論理なので、点灯するためには該当GPIOをLowにしなければならない。それに対しアオノドンのオンボードLEDは正論理。Highで点灯。それに伴い以下のように変更する。

BULB_LEDの割当変更

```

#define BULB_LED                          BSP_BOARD_LED_3                       /**< LED immitaing dimmable light bulb. */
```
↓変更

```

#define BULB_LED                          BSP_BOARD_LED_1                       /**< LED immitaing dimmable light bulb. */
```
ZIGBEEネットワークに接続状態の表示LEDを負論理から正論理へ変更

```

void zboss_signal_handler(zb_bufid_t bufid)
{
    /* Update network status LED */
    zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);

    /* No application-specific behavior is required. Call default signal handler. */
    ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    zb_buf_free(bufid);
}
```
↓変更

```

void zboss_signal_handler(zb_bufid_t bufid)
{
    /* Update network status LED */
    uint32_t led_idx = ZIGBEE_NETWORK_STATE_LED ;
    zb_zdo_app_signal_hdr_t  * p_sg_p = NULL;
    zb_zdo_app_signal_type_t   sig    = zb_get_app_signal(bufid, &p_sg_p);
    zb_ret_t                   status = ZB_GET_APP_SIGNAL_STATUS(bufid);

    switch (sig)
    {
        case ZB_BDB_SIGNAL_DEVICE_REBOOT:
            /* fall-through */
        case ZB_BDB_SIGNAL_STEERING:
            if (status == RET_OK)
            {
                bsp_board_led_off(led_idx);
            }
            else
            {
                bsp_board_led_on(led_idx);
            }
            break;

        case ZB_ZDO_SIGNAL_LEAVE:
            /* Update network status LED */
            bsp_board_led_on(led_idx);
            break;

        default:
            break;
    }

    /* No application-specific behavior is required. Call default signal handler. */
    ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    zb_buf_free(bufid);
}
```
BULB_LEDを負論理から正論理へ変更

```

static void light_bulb_onboard_set_brightness(zb_uint8_t brightness_level)
{
    app_pwm_duty_t app_pwm_duty;

    /* Scale level value: APP_PWM uses 0-100 scale, but Zigbee level control cluster uses values from 0 up to 255. */
    app_pwm_duty = ( brightness_level * 100U) / 255U;
```
↓

```

static void light_bulb_onboard_set_brightness(zb_uint8_t brightness_level)
{
    app_pwm_duty_t app_pwm_duty;

    /* Scale level value: APP_PWM uses 0-100 scale, but Zigbee level control cluster uses values from 0 up to 255. */
    app_pwm_duty = ( (255 - brightness_level) * 100U) / 255U;
```



## WS2812の接続先の変更


アオノドン2019では GPIO1.07は外部に引き出されていないため、GPIO0.27に変更。

```

#if (APP_BULB_USE_WS2812_LED_CHAIN)
#define LED_CHAIN_DOUT_PIN                NRF_GPIO_PIN_MAP(1,7)                 /**< GPIO pin used as DOUT (to be connected to DIN pin of the first ws2812 led in chain) */
#endif

```
↓変更

```

#if (APP_BULB_USE_WS2812_LED_CHAIN)
#define LED_CHAIN_DOUT_PIN                NRF_GPIO_PIN_MAP(0,27)                 /**< GPIO pin used as DOUT (to be connected to DIN pin of the first ws2812 led in chain) */
#endif

```

## Amazon Echo に接続できるようにする 

https://devzone.nordicsemi.com/f/nordic-q-a/40612/zigbee-interoperability
を参考に、

```

    /* Set static long IEEE address. */
    zb_set_network_router_role(IEEE_CHANNEL_MASK);
    zb_set_max_children(MAX_CHILDREN);
    zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
```
↓変更

```

    /* Set static long IEEE address. */
    zb_set_network_router_role(ZB_TRANSCEIVER_ALL_CHANNELS_MASK);
    zb_set_max_children(MAX_CHILDREN);
    zigbee_erase_persistent_storage(ERASE_PERSISTENT_CONFIG);
    zb_set_keepalive_timeout(ZB_MILLISECONDS_TO_BEACON_INTERVAL(3000));
```

動かします。

## Amazon Echoに登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/576f18f7-ebee-ee64-215a-2b8ecd78610d.png)

あっさりと認識しました。

## WS2812の動作

![IMG_20200214_160905.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/b6addd45-4fef-6d47-27ec-5ab72ee30efc.jpeg)

EchoからWS2812のON/OFFがコントロールできます。しかしながらWS2812の動作が結構不安定です。

https://devzone.nordicsemi.com/f/nordic-q-a/56513/driving-ws281x-led-strips-with-nrf52810/228963#228963

には、
The Thread and Zigbee SDK has an “experimental” example for WS8212 led strips that uses the PWM peripheral. It’s nothing like FastLED but is at least a place to start.
とあります。それでかな。

## オンボードLEDの調光

![IMG_20200215_131116.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f89e2d54-f4f0-507c-8888-5a86b4def4a4.jpeg)

WS2812は調子が悪いですが、オンボードLEDのON/OFF/調光は問題なく動作しました。
(写真はZIGBEEネットワークに接続状態の表示LEDを負論理から正論理へ変更してない時のもののため、ZIGBEEネットワークに接続しているけれども青LEDが点灯していません)