The following steps show you how to build an OpenThread Sleepy MTD CoAP temperature sensor using Simplicity Studio v5 and BRD4161A
1. Start Simplicity Studio v5 and connect EFR32MG12 BRD4161A. Form Launcher tab, select sleepy-demo-mtd (I use OpenThread SDK 1.2.0.0 when I test this) to create the project.
2. We will add temperature reading (from Si7021) related codes in this step.
2.1 In Simplicity IDE tab, open sleepy-demo-mtd.slcp to make sure you enable "Relative Humidity and Temperature sensor" and set proper I2C pins.
2.2 You also need to check sl_board_control_config.h and make sure SL_BOARD_ENABLE_SENSOR_RHT is defined as "1" and SL_BOARD_ENABLE_SENSOR_RHT_PORT/SL_BOARD_ENABLE_SENSOR_RHT_PIN are defined to correct port/pin which is PB10 on BRD4161A.
2.3 Set "sl_i2cspm_t *i2cspm_sensor = sl_i2cspm_inst0;" in sl_sensor_select.c.
2.4 Create periodic event to read temperature from humidity/temperature sensor Si7021.
2.4.1 Add the following header files for humidity/temperature reading and timer event.
#include "sl_i2cspm_instances.h"
#include "sl_si70xx.h"
#include "sl_sleeptimer.h"
#include <stdio.h>
#include <string.h>
2.4.2 Add the following lines in app_init in app.c to initialize Si7021 humidity/temperature sensor.
otCliOutputFormat("app_init: sl_si70xx_init\r\n");
sl_si70xx_init(sl_i2cspm_inst0, SI7021_ADDR);
static sl_sleeptimer_timer_handle_t measurement_timer;
{
otCliOutputFormat("measurement_callback\r\n");
sl_si70xx_measure_rh_and_temp(sl_i2cspm_inst0, SI7021_ADDR, &rh_data, &temp_data);
memset(str_buf,0,64);
sprintf(str_buf,"rh=%f, temperature=%f\r\n",((float)rh_data/1000.0),((float)temp_data/1000.0));
otCliOutputFormat(str_buf);
}
{
sl_sleeptimer_start_periodic_timer_ms(&measurement_timer, MEASUREMENT_INTERVAL_MS, measurement_callback, NULL, 0, 0);
...
3. Change related network settings in setNetworkConfiguration function (in sleepy-mtd.c) so the device can join matched OpenThread Border Router network (refer to here to setup OpenThread Border Router).
4. Implement CoAP related codes.
4.1 Add the following header files in app.c
#include <openthread/coap.h>
#include "utils/code_utils.h"
4.2 Add CoAP related defines and variables.
#define TEMPERATURE_STATE_URI "temp/celcius"
otCoapResource mResource_TEMPERATURE_STATE;
const char mTEMPERATUREStateUriPath[]=TEMPERATURE_STATE_URI;
4.3 Implement CoAP processing callback
static void temperature_state_coapHandler(void *aContext, otMessage *aMessage,
const otMessageInfo *aMessageInfo)
{
otCliOutputFormat("sleepy-demo-mtd temperature_state_coapHandler\r\n");
otError error = OT_ERROR_NONE;
otMessage *responseMessage;
otCoapCode responseCode = OT_COAP_CODE_CHANGED;
otCoapCode messageCode = otCoapMessageGetCode(aMessage);
otCoapType messageType = otCoapMessageGetType(aMessage);
responseMessage = otCoapNewMessage((otInstance*)aContext, NULL);
otEXPECT_ACTION(responseMessage != NULL, error = OT_ERROR_NO_BUFS);
otCoapMessageInitResponse(responseMessage, aMessage, OT_COAP_TYPE_ACKNOWLEDGMENT, responseCode);
otCoapMessageSetToken(responseMessage, otCoapMessageGetToken(aMessage),
otCoapMessageGetTokenLength(aMessage));
otCoapMessageSetPayloadMarker(responseMessage);
if(OT_COAP_CODE_GET == messageCode)
{
memset(str_buf,0,64);
sprintf(str_buf,"%f",((float)temp_data/1000.0));
otCliOutputFormat("\r\nsleepy-demo-mtd coap get\r\n");
otCliOutputFormat(str_buf);
error = otMessageAppend(responseMessage, str_buf,
strlen((const char*)str_buf));
otEXPECT(OT_ERROR_NONE == error);
error = otCoapSendResponse((otInstance*)aContext, responseMessage,
aMessageInfo);
otEXPECT(OT_ERROR_NONE == error);
}
exit:
if (error != OT_ERROR_NONE && responseMessage != NULL)
{
otMessageFree(responseMessage);
}
}
4.4 Add CoAP start codes in app_init.
otCoapStart(otGetInstance(),OT_DEFAULT_COAP_PORT);
mResource_TEMPERATURE_STATE.mUriPath = mTEMPERATUREStateUriPath;
mResource_TEMPERATURE_STATE.mContext = otGetInstance();
mResource_TEMPERATURE_STATE.mHandler = &temperature_state_coapHandler;
strncpy(mTEMPERATUREStateUriPath, TEMPERATURE_STATE_URI, sizeof(TEMPERATURE_STATE_URI));
otCoapAddResource(otGetInstance(),&mResource_TEMPERATURE_STATE);
5. Build and download sleepy-demo-mtd.hex into your BRD4161A.
6.Reset BRD4161A to join OpenThread Border Router and use CLI command "ipaddr" to output IPv6 address of Sleepy End Device.
7.Now, you can run coap-client (install libCoAP) on Raspberry Pi OTBR to get temperature reading through CoAP server running on BRD4161A Sleepy End Device.