How to Get Started With OpenThread

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.


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.
  • 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.


  • 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


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

git clone

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: Bcast: Mask:
inet6 addr: fe80::a00:27ff:fe8d:c04d/64 Scope:Link
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: Mask:
inet6 addr: ::1/128 Scope:Host
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: P-t-P: Mask:
inet6 addr: 2001:db8:1:ffff::1/128 Scope:Global
inet6 addr: 2001:db8:1::1/128 Scope:Global
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
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:


For example, translates to:


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.