nRF52840でOpenThread（２）：Adafruit Featherでサンプルを実行

#はじめに
　nRF52840でOpenThread開発の続き。
NordicのnRF5 SDK for Thread and Zigbeeの中のsimple_coap_clientとsimple_coap_serverをAdafruit Feather nRF52840 Express（以下、Feather）で動かす時のメモ。このサンプルはnRF52840 DK用に作られているのでLEDやボタン等の配置が違います。そのため、軽くプログラムの修正が必要です。

#開発環境と機材
　開発環境 ： SEGGER Embeded Studio
　機材 ： nRF52840 DK
　　　 ： Adafruit Feather nRF52840 Express

#simple_coap_clientとsimple_coap_server
　simple_coap_clinet（送信側）を書き込んだボードのボタンを押すと、simple_coap_server（受信側）のLEDを制御できます。消えているときにボタンを押すと光り、光っている時にボタンを押すと消えます。

#simple_coap_client（送信側）の修正箇所
　simple_coap_client（送信側）から修正します。
main.c内にボタンによる割り込みを制御しているメソッドがあります（main.c内70行目〜100行目）。ボタン0を押すと、ユニキャスト通信で受信側のLEDを制御するメソッド、ボタン1を押すとマルチキャスト通信で受信側のLEDを制御するメソッド、ボタン3を押すとプロビジョニングのリクエストを送るメソッドが呼び出されます。


```c:main.c
static void bsp_event_handler(bsp_event_t event)
{
    switch (event)
    {
        case BSP_EVENT_KEY_0:
            thread_coap_utils_unicast_light_request_send(THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE);
            break;

        case BSP_EVENT_KEY_1:
        {
            m_command = ((m_command == THREAD_COAP_UTILS_LIGHT_CMD_OFF) ? THREAD_COAP_UTILS_LIGHT_CMD_ON :
                                                                          THREAD_COAP_UTILS_LIGHT_CMD_OFF);

            thread_coap_utils_multicast_light_request_send(m_command,
                                                           THREAD_COAP_UTILS_MULTICAST_REALM_LOCAL);
            break;
        }

        case BSP_EVENT_KEY_3:
            thread_coap_utils_provisioning_request_send();
            break;

        default:
            return; // no implementation needed
    }
}
```
　nRF52840 DKにはボタンが4つありますが、Featherにこんなにたくさんボタンはありません。なのでとりあえず、ボタンは使わないプログラムに変えてみました。この部分のコードはコメントアウトして、以下のコードを代わりに追加します。

```c:main.c
void send_multicast_request(){

    m_command = ((m_command == THREAD_COAP_UTILS_LIGHT_CMD_OFF) ? THREAD_COAP_UTILS_LIGHT_CMD_ON :
                                                                          THREAD_COAP_UTILS_LIGHT_CMD_OFF);

    thread_coap_utils_multicast_light_request_send(m_command,
                                                           THREAD_COAP_UTILS_MULTICAST_REALM_LOCAL);
}
```

そしてmain文の中でsend_multicast_request()を呼び出すように、main文も修正します。

```c:main.c
int main(int argc, char * argv[])
{
    log_init();
    scheduler_init();
    timer_init();

    thread_instance_init();
    thread_coap_init();
    thread_bsp_init();

    //ここから追加
    int count = 0;
    //ここまで追加

    while (true)
    {
        thread_process();
        app_sched_execute();

        //ここから追加
        count++;
        NRF_LOG_INFO("count : %d", count);
        if (count == 13000){
            send_multicast_request();
            count = 0;
        }
        //ここまで追加

        if (NRF_LOG_PROCESS() == false)
        {
            thread_sleep();
        }
    }
}
```

これで、元はボタンが押されたら受信側のLEDが制御されるプログラムが約1秒ごとに受信側のLEDを自動で制御するプログラムに変わります。Featherは13000をカウントするのに1秒くらいかかるっぽいです。本当はタイマーでも使って、ちゃんと1秒ごとに呼び出した方がいいのですが、追加する項目が多いので簡単にできるこれで。

#simple_coap_server（受信側）の修正箇所
　次に、simple_coap_server（受信側）の修正です。
受信側は光らせるLEDを変えるだけです。以下の画像のようにExampleファイルの中にthread_coap_utils.cというファイルがあります。ここに送信側から送られてきたメッセージを元に、LEDを制御するプログラムが書かれています。

![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_603307_5084bbde-0700-c1e9-3c95-e5e0ea1f6fe8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603307/3a6ec11f-2ee1-9199-5db9-ac9fc1c8fbd4.png)

thread_coap_utils.c内の以下の箇所でLEDを制御しています。

```c:thread_coap_utils.c
static void light_changed_default(thread_coap_utils_light_command_t light_command)
{
    switch (light_command)
    {
        case THREAD_COAP_UTILS_LIGHT_CMD_ON:
            LEDS_ON(BSP_LED_2_MASK);
            break;

        case THREAD_COAP_UTILS_LIGHT_CMD_OFF:
            LEDS_OFF(BSP_LED_2_MASK);
            break;

        case THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE:
            LEDS_INVERT(BSP_LED_2_MASK);
            break;

        default:
            break;
    }
}
```
ここを以下のように変更します。光らせるLEDを変更しているだけです。

```c:thread_coap_utils.c
static void light_changed_default(thread_coap_utils_light_command_t light_command)
{
    //ここから追加
    int bluepin = NRF_GPIO_PIN_MAP(1,10);  // P1.10

    nrf_gpio_cfg_output(bluepin);
    //ここまで追加

    switch (light_command)
    {
        case THREAD_COAP_UTILS_LIGHT_CMD_ON:
            //LEDS_ON(BSP_LED_2_MASK);
            //ここから追加
            nrf_gpio_pin_write(bluepin,1);
            //ここまで追加
            break;

        case THREAD_COAP_UTILS_LIGHT_CMD_OFF:
            //LEDS_OFF(BSP_LED_2_MASK);
            //ここから追加
            nrf_gpio_pin_write(bluepin,0);
            //ここまで追加
            break;

        case THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE:
            //LEDS_INVERT(BSP_LED_2_MASK);
            break;

        default:
            break;
    }
}
```

修正はこれで終わりです。

#動作確認
simple_coap_serverを書き込んだ方のLEDが青くチカチカしていたら成功です。