0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

nRF connect SDK:NUS(Nordic UART Service)

Last updated at Posted at 2021-10-12

初めてのBLE通信

NordicのnRFシリーズを触り始めて最初に実行するBLEでのデータ通信はおそらくNUS(Nordic UART Service)を触ることだと思います。ちなみにこのNUSというのはNordicのSDKには当たり前のように登場しますがBLE標準サービスではないです。

NUSの実装

NUSの実態はNordicのカスタムUUIDなのですが、Nordic側で送受信に必要な関数は全て用意してくれていますのでそれを組み込むだけという形になっています。このあたりからもBLEを初めて使う人が入りやすい仕組みを作ってくれていると思います。
早速アドバタイズのところで作成したアドバタイズ部分にNUS部分を追加します。

main.c
/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

# include <zephyr.h>
# include <sys/printk.h>

# include <bluetooth/bluetooth.h>
# include <bluetooth/gatt.h>
# include <bluetooth/services/nus.h>
# include <drivers/uart.h>
# include <settings/settings.h>

# define DEVICE_NAME CONFIG_BT_DEVICE_NAME
# define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)

static const struct bt_data ad[] = {
    BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};

static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data,
              uint16_t len)
{
    uint8_t buf[256] = {0};

    printk("Received data\n");
    memcpy(buf, data, len);
    printk("%s", buf);
    printk("\n");
}

static struct bt_nus_cb nus_cb = {
    .received = bt_receive_cb,
};

static void connected(struct bt_conn *conn, uint8_t err)
{
    printk("Connected\n");
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
    printk("Disconnected\n");
}

static struct bt_conn_cb conn_callbacks = {
    .connected    = connected,
    .disconnected = disconnected,
};

void main(void)
{
    int err = 0;

    err = bt_enable(NULL);
    if (err) {
        printk("Blutooth failed to start (err %d)\n", err);
        return;
    }

    if (IS_ENABLED(CONFIG_SETTINGS)) {
        settings_load();
    }

    err = bt_nus_init(&nus_cb);
    if (err) {
        printk("Failed to initialize Nordic UART service (err: %d)\n", err);
        return;
    }

    bt_conn_cb_register(&conn_callbacks);

    err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
    if (err) {
        printk("Advertising failed to start (err %d)\n", err);
        return;
    }

    uint8_t data[32];
    uint16_t len;
    strcpy(data, "UART test\n");
    len = 10;
    while (1)
    {
        // Send
        if (bt_nus_send(NULL, data, len))
        {
            printk("Failed to send data over BLE connection\n");
        }
        k_msleep(1000);
    }
}

ちなみにNUSについてはサンプルプロジェクトがありますので、それをそのまま使うのもよいと思います。ここでは関連する最低限の部分だけ切り出して分かり易くしています。

prj.conf
# Use bluetooth
CONFIG_BT=y
CONFIG_BT_DEVICE_NAME="NCS NUS"

# Enable the NUS service
CONFIG_BT_NUS=y

CONFIG_BT_NUSというコンフィギュレーションが用意されているので有効にします。ちなみにnRF SDK時代も同様にsdk_config.h内にNUS_ENABLEDという項目がありました。

接続

コンパイルして実行し、nRF connect for mobileで接続を試みます。
Screenshot_20210806-091631.png

RX Characteristicのアップロードで文字列を送ってみましょう。
Screenshot_20210806-091656.png

コンソール側で受信した文字列が表示されます。
cmd.png

メインスレッドで1秒毎にデータを送信しているので、nRF Connect for MobileのNotificationをONにすると送信が成立してコンソールにエラーメッセージが出なくなります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?