IPDL - 13: 6LoWPAN Protocol Demonstration: Difference between revisions
Created page with "= XIAO nRF52840 — Thread + 6LoWPAN + UDP = Assume: <code> XIAO #1 = LEADER XIAO #2 = CHILD Leader COM26 Child COM27 UDP Port = 12345 </code> Your actual COM ports can of course change. == 1. LEADER — complete command sequence == Start with the '''Leader XIAO'''. === Step 1 — Clear old dataset === <code> dataset clear </code> Expected: <code> Done </code> === Step 2 — Create a NEW Thread network === <code> dataset init new </code> Expected: <code>..." |
|||
| Line 526: | Line 526: | ||
THREAD NETWORK | THREAD NETWORK | ||
┌─────────────────────────┐ | ┌─────────────────────────┐ | ||
XIAO #2 XIAO #1 | XIAO #2 XIAO #1 | ||
CHILD LEADER | CHILD LEADER | ||
Revision as of 06:05, 26 September 2026
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.
One important thing from your screenshot
Your screenshot shows the right general idea, but notice this on the right-hand XIAO:
ot dataset clear
ot dataset set channel 21
ot dataset channel 21
ot dataset commit active
ot ifconfig up
ot thread start
ot state
child
That worked because the board was able to attach using compatible network information.
For a clean teaching/demo procedure, however, I'd recommend we use:
LEADER:
dataset init new
↓
dataset active -x
↓
CHILD:
dataset set active <copied TLV>
↓
thread start
↓
child
This makes it crystal clear that both XIAOs are members of the same Thread network. OpenThread also notes that a device can attach using a partial dataset (the Network Key is sufficient, with channel information useful for avoiding channel scanning), but copying the complete Active Dataset is simpler and less error-prone for your lab demonstration.
So the complete architecture of the experiment is:
XIAO nRF52840 #1
LEADER
COM26
│
┌──────┴──────┐
│ Thread │
│ IPv6 │
│ 6LoWPAN │
│ UDP │
└──────┬──────┘
│
802.15.4
│
┌──────┴──────┐
│ Thread Mesh │
└──────┬──────┘
│
XIAO nRF52840 #2
CHILD
COM27
This is a very good 6LoWPAN/Thread practical, because you're actually demonstrating the chain:
IEEE 802.15.4 → Thread → 6LoWPAN → IPv6 → UDP → application message.