nRF5 SDK for Meshで学ぶBluetooth mesh③~実機動作確認~

はじめに

tomo-wait-for-it-yuki.hatenablog.com

少し間が空きましたが、前回の続きです。

2台のnRF52840 DKが手に入ったので、nRF5 SDK for Meshのlight switch サンプルを動かします。

今回は、nRF52840 DKを2台と、Android端末を1台、利用します。Android端末は、プロビジョナーになります。

Android端末の準備

下記アプリケーションをインストールしておくだけです。

play.google.com

nRF52840 DKの準備

SoftDeviceの書き込み

nRF5 SDK for Meshに含まれているSoftDeviceを書き込みます。

|> nRF5-SDK-for-Mesh/bin/softdevice

nRF52840では、SoftDeviceのversion s140を使います。Nordicのコマンドラインツールnrfjprogが必要です。 開発キットをUSBで接続し、以下のコマンドを実行します。

$ nrfjprog -f nrf52 --program s140_nrf52_6.1.0_softdevice.hex --chiperase  --verify
Parsing hex file.
Erasing user available code and UICR flash areas.
Applying system reset.
Checking that the area to write is not protected.
Programming device.
Verifying programming.
Verified OK.

書き込みが完了しました。Flashに書き込まれた内容を確認すると、以下のメモリアドレスに対して、MBRとSoftDeviceが書き込まれています。

アドレス 内容
0x0000_0000 - 0x0000_0A18 MBR
0x0000_1000 - 0x0002_5E7C SoftDevice

SDK内のサンプルアプリケーションを見ると、アプリケーションは、0x0002_6000からマッピングされます。

Bluetooth Mesh Stackのビルド

下記cmakeの手順に沿って、プロトコルスタックをビルドします。 この手順では、nRF5 SDK for Mesh内のすべてのプロジェクトをビルドします。

www.nordicsemi.com

Tip 1: There is a merge_ for each of the example targets that uses mergehex to generate a hexfile with the application and SoftDevice merged.

SoftDeviceを先に書きこまなくても、cmakeのオプションでmerge_<target>とすれば良かったようです。まぁ良しとしましょう。

ロスコンパイラ

ツールチェインの推奨があるため、ARMツールチェインを更新しておきます。 Ubuntuデフォルトは、gcc 4.9なので、かなり古いです。代わりに下のgcc 7.3.1をインストールしました。

$ sudo add-apt-repository ppa:team-gcc-arm-embedded/ppa
$ sudo apt-get update
$ sudo apt-get install gcc-arm-embedded

nRF SDK

nRF5 SDK for Meshのビルドには、nRF SDKも必要です。

Nordic Semiconductor Developer websiteからSDKをダウンロードし、nRF5 SDK for Meshと同じディレクトリに置きます。

.
+-- nnRF5-SDK-for-Mesh/
+-- nRF5_SDK_15.2.0_9412b96/

ビルド

SDK for Meshのトップディレクトリから、プロトコルスタックと全てのサンプルプロジェクトをビルドします。 cmake実行時のオプションは次の通りです。

build$ cmake -G Ninja -DTOOLCHAIN= -DPLATFORM= ..

今回は、ターゲットがnrf52840なので、-DPLATFORMnrf52840_xxAAを指定します。

# nRF SDK for Meshのルートディレクトリ
$ mkdir build && cd $_
$ cmake -GNinja -DPLATFORM=nrf52840_xxAA ..
-- Configuring CMake for nRF5 SDK for Bluetooth Mesh 3.1.0
-- Found PythonInterp: /usr/bin/python (found version "2.7.12") 
-- Found Doxygen: /usr/bin/doxygen (found version "1.8.11") found components:  doxygen dot 
-- SDK_ROOT=/home/tomoyuki/work/05.nrf52840/02.SDK/nRF5-SDK-for-Mesh/../nRF5_SDK_15.2.0_9412b96 --- set with default PATH
-- Setting build type to 'Debug' as none was specified.
-- PC-Lint executable not found. Linting disabled.
-- SDK: nRF5_SDK_15.2.0_9412b96
-- Platform: nrf52840_xxAA
-- Arch: cortex-m4f
-- SoftDevice: s140_6.1.0
-- Board: pca10056
-- The C compiler identification is GNU 7.3.1
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/arm-none-eabi-gcc
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc -- works
...

ビルドを開始します。数分程度、時間がかかります。

$ ninja

nRF5-SDK-for-Mesh/build/examples/light_switch/clientを見ると、バイナリが生成されています。

$ ls
CMakeFiles
cmake_install.cmake
light_switch_client_nrf52840_xxAA_s140_6.1.0.elf
light_switch_client_nrf52840_xxAA_s140_6.1.0.hex
light_switch_client_nrf52840_xxAA_s140_6.1.0.map

バイナリのアドレスマップを確認したところ、0x0002_6000から開始しており、SoftDeviceが含まれていないことがわかります。

Flashへの書き込み

SoftDeviceは書き込み済みなので、アプリケーションを書き込みます。 まずは、クライアント側から。

$ nrfjprog -f nrf52 --program light_switch_client_nrf52840_xxAA_s140_6.1.0.hex --verify
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programming device.
Verifying programming.
Verified OK.

無事に書き込みが完了しました。 次はサーバー側を別の開発キットに書き込みます。

$ nrfjprog -f nrf52 --program light_switch_server_nrf52840_xxAA_s140_6.1.0.hex --verify
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programming device.
Verifying programming.
Verified OK.

動作確認

Client RTT

今回のサンプルでは、クライアント側にRTTを繋いでおくと、デバッグ情報を見ることができます。 まず、デバイスと接続します。多分スクリプト化できるはずなので、今後やっておきたいですね。

$ JLinkExe
J-Link>connect
Device>NRF52840_XXAA
TIF>S
Speed>4000

別ターミナルでRTT Clientを立ち上げます。

$ JLinkRTTClient
###RTT Client: ************************************************************ 
###RTT Client: *               SEGGER Microcontroller GmbH                * 
###RTT Client: *   Solutions for real time microcontroller applications   * 
###RTT Client: ************************************************************ 
###RTT Client: *                                                          * 
###RTT Client: *       (c) 2012 - 2016  SEGGER Microcontroller GmbH       * 
###RTT Client: *                                                          * 
###RTT Client: *     www.segger.com     Support: support@segger.com       * 
###RTT Client: *                                                          * 
###RTT Client: ************************************************************ 
###RTT Client: *                                                          * 
###RTT Client: * SEGGER J-Link RTT Client   Compiled Feb 26 2019 17:01:46 * 
###RTT Client: *                                                          * 
###RTT Client: ************************************************************ 

###RTT Client: -----------------------------------------------
###RTT Client: Connecting to J-Link RTT Server via localhost:19021  Connected.

Clientを起動すると、次のように起動ログが流れます。

SEGGER J-Link V6.42f - Real time terminal output
J-Link OB-SAM3U128-V2-NordicSemi compiled Jan  7 2019 14:07:15 V1.0, SN=683890816
Process: JLinkExe
<t:          0>, main.c,  318, ----- BLE Mesh Light Switch Client Demo -----
<t:      13030>, main.c,  289, Initializing and adding models
<t:      17943>, mesh_app_utils.c,   65, Device UUID (raw): 41B13709D7D2D741A90A61BB51949874
<t:      17947>, mesh_app_utils.c,   70, Device UUID : 0937B141-D2D7-41D7-A90A-61BB51949874

light switch demo

プロビジョニング

AndroidでnRF Meshアプリを立ち上げます。 開発キットを両方とも起動します。

すると、次のような画面になります。

f:id:tomo-wait-for-it-yuki:20190304065007p:plain
nRF5 SDK for Mesh sample scanning

nRF5x Mesh Switchがclient、nRF5x Mesh Lightがserverになります。 Androidアプリケーションで、両方のデバイスIDENTIFY->PRIVISIONと順番にやると、PROVISIONが完了します。

f:id:tomo-wait-for-it-yuki:20190304065046p:plain
nRF5 SDK for Mesh sample network connected

設定

CONFIGURE->Element->Generic On Off Client / Serverを順にタッチしていき、App Keyを登録します。 また、Client側では、Publish Addressとして、Serverのunicast addressを設定します。 (私の場合は、Serverのアドレスは0x0004でした)

実機操作

これで、準備完了です。

ClientのButton1を押すと、ServerのLED1が点灯します。 ClientのButton2を押すと、ServerのLED1が消灯します。

Client側で接続しているRTTには、次のようなログが出力されます。

<t:   15536492>, main.c,  200, Button 0 pressed
<t:   15536494>, main.c,  227, Sending msg: ONOFF SET 1
<t:   15537259>, main.c,  147, Acknowledged transfer success.
<t:   15537262>, main.c,  173, OnOff server: 0x0004, Present OnOff: 0, Target OnOff: 1, Remaining Time: 100 ms
<t:   16007421>, main.c,  200, Button 1 pressed
<t:   16007424>, main.c,  227, Sending msg: ONOFF SET 0
<t:   16007913>, main.c,  147, Acknowledged transfer success.
<t:   16007916>, main.c,  173, OnOff server: 0x0004, Present OnOff: 1, Target OnOff: 0, Remaining Time: 100 ms