Learn how to play with the new OpenThread implementation on multiple nRF52840 development boards.

Thread is a cool new stack based on the 802.15.4 specification. It’s a direct attack on the inconvenient market dominance that Zigbee has on the embedded mesh networking world.

The un-cool part is the fact that there aren’t very clear ways to get started. When I was researching the latest short and long distance options for IoT I found myself intrigued with the OpenThread implementation of the Thread network protocol.

After several frustrating search engine expeditions, forum crawls, and discussion board hunt no basic information exists about how Thread works or how you can easily integrate it.

If you don’t have the extra cash to invest in a Thread Group membership, here are some easy ways for hackers and product engineers can get started.

Important Concepts

Here are a few important concepts that are important to understand before getting started.

Note: lots of the underlying functionality is actually based on the 802.15.4 protocol. Thus many of my questions ended up being answered by searching a level deeper for information about 802.15.4 itself.

Physical Devices

Border router — connects your Thread network to the internet. Typically it’s a piece of hardware that has a 802.15.4 compatible radio running the Thread stack. Additionally, it may have a ethernet port, LTE module or wifi to get to the outside world.

Router — is an active node in a thread mesh. If there is no direct connection to the border router, a router forwards packets along the network until the find the internet. Routers are typically plugged in to the wall and require to be up and running at all times.

End node — end nodes are also known a sleepy nodes. These nodes wake up, transmit data, possibly pull data and then go back to sleep. These nodes can operate years on the same battery because of their low duty cycles (<1%)

Network Terminology

PAN — a PAN is a way of sub-dividing devices into smaller network groups. It’s controlled by a 4 byte identifier (which calculates to 4,294,967,296 unique PANs!) called the PANID. A PAN is a MAC layer definition rather than a physical one. Think of it as a subnet for an IPV4 network.

Network Key — this is a 32 byte long unique code that will allow devices access to your private network. Very similar to a Wifi password you may enter into your computer when connecting to a new network.

Network Name — this is the name of the network in which to connect to. Akin to a WIFI SSID.

Channel — thread utilizes a standard 802.15.4 channel bandwidth of 5MHz. There are 16 channels in total. Typically the system stays on one channel but can switch channels as directed by the lead router.

Commands

Not-so-usefully, many of the Thread examples have many important parameters built-in. So, when you acutally go to implement your own design you may be finding yourself searching though the example code to see how exactly things work. With some trial and error these are, by far, the most important commands that I have used:

nRF52840 CLI

Self explanatory if you used, `ping` on a Windows computer or Mac. It is an essential tool to ensure you are properly connected to the outside world.

ping

Disable router mode. Only connects as an end node. (By default the Nordic CLI firmware connects as a router.)

routermode disable

Setting the network key is immensely important and is the main protection of your network.

masterkey 00112233445566778899aabbccddeeff

Setting the channel to one of the 16 channels. This physically distributes and devices the devices. A device on channel 18 cannot speak to a device on channel 20. Devices on the same channel can only communicate with each other.

channel 11

Setting the extended PANID. This ID is used in special cases and is not always transmitted. More info on this here.

extpanid dead00beef00cafe

Setting the PANID.

panid 0x1234

Setting the network name

networkname OpenThread

Setting the interface to up

ifconfig up

Enabling thread. Both this and ifconfig up has to be run in order to connect to other devices.

thread start

A deeper dive into all the CLI commands can be found here.

Wpantund

Just like the above, this sets the network key on an NCP

wpanctl set Network:Key — data <network key>

Set the channel

wpanctl set NCP:Channel <channel>

Sets the PANID so the devices can communicate.

wpanctl setprop Network:PANID <panid>

Re/creates a network based on the above settings.

wpanctl attach

Example

This is a quick end-to-end example that is using the Nordic nRF52840 CLI example located in the Thread SDK and my Basic Border Router example.

Note: This plugin is useful for automatically installing VirtualBox Guest Additions. I highly recommend you install it.

vagrant plugin install vagrant-vbguest

Let’s get started:

1. Clone the Basic Border Router repository if you haven’t already

2. First, change the serial number for your nRF52840 Development Kit in the `Vagrantfile`. It’s located on line 51.

v.customize [“usbfilter”, “add”, “0”,

“ — target”, :id,

“ — name”, “J-Link”,

“ — manufacturer”, “SEGGER”,

“ — product”, “J-Link”,

“ — serialnumber”, “000683767824”]

3. Plug your kit into USB.

4. Program using the NCP firmware as provided in the Nordic Thread SDK

cd nRF5_SDK_for_Thread_v0/examples/thread/experimental/ncp/pca10056/blank/armgcc

make flash ../../../hex/nrf52840_xxaa.hex

5. Run the `vagrant up` command

vagrant up

6. Log in to the vagrant box

vagrant ssh

7. Run the border router

cd /vagrant/

chmod 755 ./script/thread_border_router

sudo ./script/thread_border_router

8. In a separate shell window, you should see a few network interfaces show up once wpantund has initialized. Most important to note that both nat64 and wpan0 has been initialized.

vagrant@jessie:~$ /sbin/ifconfig

eth0 Link encap:Ethernet HWaddr 08:00:27:8d:c0:4d

inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0

inet6 addr: fe80::a00:27ff:fe8d:c04d/64 Scope:Link

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:5843 errors:0 dropped:0 overruns:0 frame:0

TX packets:5678 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:392092 (382.9 KiB) TX bytes:544621 (531.8 KiB) lo Link encap:Local Loopback

inet addr:127.0.0.1 Mask:255.0.0.0

inet6 addr: ::1/128 Scope:Host

UP LOOPBACK RUNNING MTU:65536 Metric:1

RX packets:18 errors:0 dropped:0 overruns:0 frame:0

TX packets:18 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:1647 (1.6 KiB) TX bytes:1647 (1.6 KiB) nat64 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

inet addr:192.168.255.1 P-t-P:192.168.255.1 Mask:255.255.255.255

inet6 addr: 2001:db8:1:ffff::1/128 Scope:Global

inet6 addr: 2001:db8:1::1/128 Scope:Global

UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1

RX packets:126 errors:0 dropped:0 overruns:0 frame:0

TX packets:126 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:500

RX bytes:5922 (5.7 KiB) TX bytes:8442 (8.2 KiB) wpan0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00

inet6 addr: fdde:ad00:beef:0:c6e4:f108:a9a6:737a/64 Scope:Global

inet6 addr: fdff:cafe:cafe:cafe:f43d:3e29:fcab:e233/64 Scope:Global

inet6 addr: fe80::f43d:3e29:fcab:e233/64 Scope:Link

UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1280 Metric:1

RX packets:126 errors:0 dropped:0 overruns:0 frame:0

TX packets:7 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:500

RX bytes:8442 (8.2 KiB) TX bytes:672 (672.0 B)

9. On a separate development kit, install the CLI example:

cd nRF5_SDK_for_Thread_v0/examples/thread/experimental/cli/pca10056/blank/armgcc

make flash ../../../hex/nrf52840_xxaa.hex

10. Connect to the CLI example using a terminal program. In my case i’m using CoolTerm. (11500 Baudrate) In the picture below, I’m disabling the router role so I know whether or not it’s connected to the network being generated by the Basic Border Router.

11. Ping the border router

ping 2001:db8:1:ffff::1 > 8 bytes from 2001:db8:1:ffff:0:0:0:1: icmp_seq=1 hlim=64 time=34ms

12. Ping Google’s DNS server

ping 2001:db8:1:ffff:0:0:808:808 > 8 bytes from 2001:db8:1:ffff:0:0:808:808: icmp_seq=2 hlim=57 time=43ms

Note: if you want to ping any other server besides Google you can rewrite the above IPV6 address using the hex value of the IPV4 address and this prefix:

2001:db8:1:ffff:0:0:

For example, 192.168.1.1 translates to:

2001:db8:1:ffff:0:0:c0a8:0101

Finishing Touches

Thread seems promising but there’s plenty more to come. For one thing, the Nordic OpenThread examples currently does not have out of the box DTLS support (i.e. encryption). That would be one requirement before I recommend anyone start sending customer data over the internet in a production setting.

Also the use of CoAP, though thoroughly not tested, may be troublesome due to the fact that UDP does not guarantee delivery!

Despite these drawbacks, i’m still excited to see where the technology goes. I’m especially excited because it’s getting integrated into the wifi systems that we use every day making it seamless to add Thread based products right onto your network.