IPDL - 13: 6LoWPAN Protocol Demonstration
XIAO nRF52840 — Thread + 6LoWPAN + UDP
Assume:
XIAO #1 = LEADER
XIAO #2 = CHILD
Leader COM26
Child COM27
UDP Port = 12345
Your actual COM ports can of course change.
1. LEADER — complete command sequence
Start with the Leader XIAO.
Step 1 — Clear old dataset
dataset clear
Expected:
Done
Step 2 — Create a NEW Thread network
dataset init new
Expected:
Done
This generates a new random Thread Operational Dataset containing things such as:
- Channel
- PAN ID
- Extended PAN ID
- Network Key
- Network Name
- Mesh-local prefix
- PSKc
OpenThread documents dataset init new specifically for creating a new dataset.
Step 3 — Display the dataset
Immediately do:
dataset
You should get something similar to:
Active Timestamp: 1
Channel: 21
Channel Mask: 0x07fff800
Ext PAN ID: xxxxxxxxxxxxxxxx
Mesh Local Prefix: fdxx:xxxx:xxxx:xxxx::/64
Network Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Network Name: OpenThread-xxxx
PAN ID: 0xxxxxxx
PSKc: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Security Policy: 0, onrcb
Done
Important: keep this information.
Step 4 — Commit the dataset
dataset commit active
Expected:
Done
This writes the Operational Dataset as the Active Operational Dataset.
Step 5 — Bring up IPv6
ifconfig up
Expected:
Done
Step 6 — Start Thread
thread start
Expected:
Done
Now check:
state
Initially it may show:
detached
Then after a short time the Leader should become:
leader
You can repeatedly use:
state
The normal target is:
leader
2. Get the Leader's complete dataset
This is the most important command for creating the Child.
On the Leader:
dataset active -x
You will get a long hexadecimal string, for example:
0e080000000000010000000300001035060004001fffe00208xxxxxxxxxxxxxxxx...
Copy the entire line.
OpenThread specifically supports dataset active -x for obtaining a hex-encoded Active Operational Dataset that can then be applied to another device with dataset set active.
3. Check Leader IPv6 addresses
Run:
ipaddr
You may see something like:
fdxx:xxxx:xxxx:xxxx:0:ff:fe00:xxxx
fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
fe80:....
For our UDP test, we'll normally use the Thread mesh-local IPv6 address, beginning with:
fd...
For example:
fd00:abcd:1234:5678:xxxx:xxxx:xxxx:xxxx
Don't use the fe80:: address for this simple test.
4. Test that Leader is working
You can check:
thread state
or simply:
state
You can also check:
ipaddr
And:
netdata show
For a simple two-node experiment, the important result is:
state
leader
5. CHILD — complete command sequence
Now move to the second XIAO.
First clear whatever old network information it has.
dataset clear
Then:
ifconfig down
Then:
thread stop
If the board wasn't running Thread, that's okay.
6. Give the Child the Leader's dataset
This is where your previous procedure needs to be slightly changed.
DO NOT do this on the Child:
dataset init new
because that creates a new network.
Instead, take the hexadecimal string obtained from:
dataset active -x
on the Leader.
Then on the Child:
dataset set active YOUR_LEADER_DATASET_HEX
For example:
dataset set active 0e080000000000010000000300001035060004001fffe00208xxxxxxxxxxxxxxxx...
Expected:
Done
This is the documented way of putting the same Active Operational Dataset onto a new device.
7. Start the Child's Thread interface
On Child:
ifconfig up
Then:
thread start
Expected:
Done
Wait a few seconds.
Then:
state
Expected:
child
You might briefly see:
detached
before:
child
That is normal during attachment.
8. Check Child IPv6 addresses
On Child:
ipaddr
You should get something like:
fdxx:xxxx:xxxx:xxxx:0:ff:fe00:xxxx
fdxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
fe80:....
Again, note the fd... address.
For example:
fd00:abcd:1234:5678:1111:2222:3333:4444
We'll call that:
CHILD_IP
9. Verify Leader ↔ Child connectivity
Now go back to the Leader.
Take the Child's fd... address.
Run:
ping CHILD_IP
For example:
ping fd00:abcd:1234:5678:1111:2222:3333:4444
Expected:
16 bytes from fd00:abcd:1234:5678:1111:2222:3333:4444:
icmp_seq=1 hlim=64 time=10ms
1 packets transmitted, 1 packets received.
Packet loss = 0.0%.
That proves:
Leader
│
│ IPv6
│
▼
Thread / 6LoWPAN
│
▼
Child
10. Now configure UDP
This is where your screenshot becomes particularly useful.
Let's make:
Leader = UDP SERVER
Child = UDP CLIENT
Port = 12345
11. LEADER — UDP server
On the Leader:
udp open
Expected:
Done
Then:
udp bind :: 12345
Expected:
Done
This means:
IPv6 address = ::
UDP port = 12345
The :: means the unspecified IPv6 address, allowing the socket to accept traffic on the available IPv6 addresses. This is the standard OpenThread CLI UDP procedure.
You now have: LEADER UDP socket- port 12345
12. CHILD — UDP client
On Child:
udp open
Expected:
Done
You don't actually have to bind the Child for a simple send test.
Now take the Leader's IPv6 address.
For example:
fd00:abcd:1234:5678:aaaa:bbbb:cccc:dddd
Then:
udp send fd00:abcd:1234:5678:aaaa:bbbb:cccc:dddd 12345 Hello_Leader
Expected:
Done
OpenThread's official UDP example follows exactly this pattern: udp open, optionally udp bind, then udp send <IPv6> <port> <message>.
13. What should happen?
On the Leader, you should see something similar to:
Received UDP message
depending on the particular OpenThread CLI build.
Conceptually:
THREAD NETWORK
┌─────────────────────────┐
XIAO #2 XIAO #1
CHILD LEADER
│ │
│ │
│ IPv6 / UDP │
│──────────────────────>│
│ │
│ "Hello_Leader" │
│ │
COM27 COM26
UDP destination port: 12345
14. Reverse direction — Leader → Child
If you want the Leader to send a message back to the Child, bind the Child.
On Child:
udp bind :: 12345
Then on Leader:
udp send CHILD_IP 12345 Hello_Child
For example:
udp send fd00:abcd:1234:5678:1111:2222:3333:4444 12345 Hello_Child
Now you have bidirectional UDP:
CHILD ────────────────► LEADER
Hello_Leader
CHILD ◄──────────────── LEADER
Hello_Child
15. The complete cheat sheet
LEADER
Run these in this order:
dataset clear
dataset init new
dataset
dataset commit active
ifconfig up
thread start
state
ipaddr
dataset active -x
Then test the Child:
ping CHILD_IP
Then UDP server:
udp open
udp bind :: 12345
CHILD
Use the Leader's dataset:
dataset clear
ifconfig down
thread stop
Then:
dataset set active LEADER_DATASET_HEX
Then:
ifconfig up
thread start
Check:
state
ipaddr
Expected:
child
Then UDP:
udp open
Send to Leader:
udp send LEADER_IP 12345 Hello_Leader
16. Full two-way UDP setup
LEADER
dataset clear
dataset init new
dataset
dataset commit active
ifconfig up
thread start
state
ipaddr
dataset active -x
Copy the dataset.
Then:
udp open
udp bind :: 12345
CHILD
dataset clear
ifconfig down
thread stop
dataset set active LEADER_DATASET_HEX
ifconfig up
thread start
state
ipaddr
udp open
Then:
udp send LEADER_IP 12345 Hello_Leader
For reverse communication, on Child:
udp bind :: 12345
Then on Leader:
udp send CHILD_IP 12345 Hello_Child
17. Useful diagnostic commands
| Purpose | Command |
|---|---|
| Show current Thread state | state
|
| Show IPv6 addresses | ipaddr
|
| Show current dataset | dataset
|
| Get dataset as hex | dataset active -x
|
| Create new network | dataset init new
|
| Clear dataset | dataset clear
|
| Commit dataset | dataset commit active
|
| Bring IPv6 up | ifconfig up
|
| Bring IPv6 down | ifconfig down
|
| Start Thread | thread start
|
| Stop Thread | thread stop
|
| Show Thread neighbors | neighbor table
|
| Show Thread network data | netdata show
|
| Test IPv6 connectivity | ping <IPv6>
|
| Open UDP socket | udp open
|
| Bind UDP socket | udp bind :: 12345
|
| Send UDP | udp send <IPv6> 12345 <message>
|
| Close UDP | udp close
|
| UDP help | udp help
|
| Thread help | thread help
|
| Dataset help | dataset help
|
The current OpenThread CLI reference lists these dataset and UDP operations, including dataset clear, dataset commit active, dataset init, udp open, udp bind, udp send, and udp close.