Introduction
In this episode, we’ll implement direct CoAP communication between two STM32WB-based Thread nodes using OpenThread. CoAP (Constrained Application Protocol) is a lightweight, UDP-based protocol. It is ideal for resource-constrained devices. It is also a core part of Thread’s application layer.
Understanding the Role of CoAP in Thread
CoAP works similarly to HTTP but is designed for low-power networks. Devices use CoAP to expose resources (e.g., `/led`, `/temperature`) that others can query or control using standard methods like GET, POST, PUT, and DELETE.
Design Overview
We’ll implement a basic system where:
- Device A sends a CoAP POST request to toggle an LED on Device B.
- Device B exposes the resource
/ledand processes the command.
Setting Up the Server on Device B
Device B acts as a CoAP server and listens for POST requests on the /led resource:
void HandleLedRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo) {
// Toggle LED here
BSP_LED_Toggle(LED2);
// Optional: send an ACK
otCoapSendEmptyAck(otInstance, aMessage, aMessageInfo);
}
void InitCoapServer() {
otCoapResource resource = {
.mUriPath = "led",
.mHandler = HandleLedRequest,
.mContext = NULL,
.mNext = NULL
};
otCoapAddResource(otInstance, &resource);
}
Sending a POST Request from Device A
Device A will send a CoAP POST to Device B’s mesh-local address:
void SendToggleCommand(const otIp6Address *peerAddr) {
otMessage *message = otCoapNewMessage(otInstance, NULL);
otCoapMessageInit(message, OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
otCoapMessageAppendUriPathOptions(message, "led");
otMessageInfo msgInfo = {0};
msgInfo.mPeerAddr = *peerAddr;
msgInfo.mPeerPort = OT_DEFAULT_COAP_PORT;
otCoapSendRequest(otInstance, message, &msgInfo, NULL, NULL);
}
Getting the Peer Address
You can retrieve Device B’s mesh-local address during commissioning or via multicast service discovery using the `/.well-known/core` path.
Handling the Response
Though optional, Device B can respond with an acknowledgment or a CoAP payload indicating success. This can be used by Device A to confirm the LED was toggled successfully.
Debugging and Logs
- Ensure both devices are on the same Thread network.
- Use RTT or UART logs to print received requests and responses.
- Make sure the CoAP port is open and the resource path matches exactly.
Conclusion
By the end of this episode, you now have two Thread devices communicating using CoAP. This is a foundational use case in smart home and industrial IoT. In the next episode, we’ll expand this concept by adding a simple sensor readout and display over CoAP between nodes.

Leave a comment