nRF52840 DKで遊ぼう③~Bluetooth Mesh Serial example~
はじめに
nRF5 SDK for MeshのSerial exampleを試します。
|> nRF5-SDK-for-Mesh/examples/serial
PyACI
本アプリケーションをテストするためには、Pythonのインタラクティブアプリケーションが必要です。 下記の手順に沿って、インストールします。
# nRF5-SDK-for-Mesh/scripts/interactive_pyaci $ pip3 install -r requirements.txt
次のようなコマンドで、インタラクティブシェルを起動します。
$ sudo python3 interactive_pyaci.py -d /dev/ttyACM0 To control your device, use d[x], where x is the device index. Devices are indexed based on the order of the COM ports specified by the -d option. The first device, d[0], can also be accessed using device. Type d[x]. and hit tab to see the available methods. Python 3.5.2 (default, Nov 12 2018, 13:43:14) Type 'copyright', 'credits' or 'license' for more information IPython 7.3.0 -- An enhanced Interactive Python. Type '?' for help. In [1]:
Serial exampleのビルドとFlash
nRF5 SDK for Meshを丸ごとビルドしてあるため、ビルド済みのバイナリを使います。
# nRF5-SDK-for-Mesh/build/examples/serial nrfjprog -f nrf52 --program serial_nrf52840_xxAA_s140_6.1.0.hex nrfjprog --reset -f nrf52
動作確認
と、ここまでは良かったのですが、イマイチ使い方が良く分かりません。 これで、pythonのインタラクティブシェルからBluetooth Meshが使えるはずですが…?
loopback
ということで、単純なループバックから試していきます。
今、開発キットは、/dev/ttyACM0
として見えています。
$ sudo python3 interactive_pyaci.py -d /dev/ttyACM0 --no-logfile ... In [1]: d[0].send(cmd.Echo("hello world")) 2019-03-07 13:01:04,976 - INFO - ttyACM0: {event: DeviceEchoRsp, data: {'data': bytearray(b'hello world')}}
無事、開発キットからエコーが返ってきました。
Sending mesh packets
ここからは開発キットが2台必要です。Serial exampleを2台ともに書き込み、USBを念のため再接続しておきます。
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1
インタラクティブシェルでは、d[0], d[1]として、それぞれアクセス可能です。
In [1]: d[0].send(cmd.Echo("hello world")) 2019-03-07 13:08:56,964 - INFO - ttyACM0: {event: DeviceEchoRsp, data: {'data': bytearray(b'hello world')}} In [2]: d[1].send(cmd.Echo("hello world")) 2019-03-07 13:09:01,203 - INFO - ttyACM1: {event: DeviceEchoRsp, data: {'data': bytearray(b'hello world')}}
まずは、開発キットを初期化します。pythonで書けるので、次のようにできます。
In [3]: for dev in d: dev.quick_setup() 2019-03-07 13:12:19,267 - INFO - ttyACM1: SubnetAdd: {'subnet_handle': 0} 2019-03-07 13:12:19,268 - INFO - ttyACM0: SubnetAdd: {'subnet_handle': 0} 2019-03-07 13:12:19,277 - INFO - ttyACM0: AppkeyAdd: {'appkey_handle': 0} 2019-03-07 13:12:19,278 - INFO - ttyACM1: AppkeyAdd: {'appkey_handle': 0} 2019-03-07 13:12:19,287 - INFO - ttyACM1: Success 2019-03-07 13:12:19,288 - INFO - ttyACM0: Success
アドレスのpublicationを開始します。
In [4]: d[0].send(cmd.AddrPublicationAdd(d[1].local_unicast_address_start)) 2019-03-07 13:24:21,392 - INFO - ttyACM0: AddrPublicationAdd: {'address_handle': 0} In [5]: d[1].send(cmd.AddrPublicationAdd(d[0].local_unicast_address_start)) 2019-03-07 13:24:32,687 - INFO - ttyACM1: AddrPublicationAdd: {'address_handle': 0}
ここで、address_handle
は後程使うため、変数に格納しておきます。
In [6]: publish_handle = 0 In [7]: appkey_handle = 0
PacketSend()
で使うための変数を定義します。
In [8]: ttl = 1 In [9]: segmented = 0 In [10]: mic_size = 0 In [11]: friendship_credentials_flag = 0
お互いにデータを送り合ってみます。まず、ttyACM0に繋がっているデバイスから、ttyACM1へパケットを送信します。
In [12]: d[0].send(cmd.PacketSend(appkey_handle, d[0].local_unicast_address_start, publish_handle, ttl, segmented, mic_size, friendship_credentials_flag, "Hello World")) 2019-03-07 13:29:22,257 - INFO - ttyACM0: PacketSend: {'token': 1} 2019-03-07 13:29:22,269 - INFO - ttyACM0: {event: MeshTxComplete, data: {'token': 1}} 2019-03-07 13:29:22,270 - INFO - ttyACM1: {event: MeshMessageReceivedUnicast, data: {'src': 1, 'dst': 2, 'adv_addr': bytearray(b'\xf1\x9b\\\xd9\xc4\xcd'), 'adv_addr_type': 1, 'rssi': -27, 'data': bytearray(b'Hello World'), 'subnet_handle': 0, 'actual_length': 11, 'ttl': 1, 'appkey_handle': 0}}
次は、逆方向にパケットを送信します。
In [13]: d[1].send(cmd.PacketSend(appkey_handle, d[1].local_unicast_address_start, publish_handle, ttl, segmented, mic_size, friendship_credentials_flag, "Hi there")) 2019-03-07 13:31:16,541 - INFO - ttyACM1: PacketSend: {'token': 1} 2019-03-07 13:31:16,542 - INFO - ttyACM1: {event: MeshTxComplete, data: {'token': 1}} 2019-03-07 13:31:16,543 - INFO - ttyACM0: {event: MeshMessageReceivedUnicast, data: {'src': 2, 'dst': 1, 'adv_addr': bytearray(b')\na\xbbQ\xd4'), 'adv_addr_type': 1, 'rssi': -25, 'data': bytearray(b'Hi there'), 'subnet_handle': 0, 'actual_length': 8, 'ttl': 1, 'appkey_handle': 0}}
他にもインタラクティブにProvisioningしたり、pub/subできるようです。 だいたい勘所はわかったので、ここまでにします。