Showing posts with label COAP. Show all posts
Showing posts with label COAP. Show all posts

Thursday, July 1, 2021

How to build OpenThread Sleepy MTD CoAP temperature sensor using Simplicity Studio v5 and BRD4161A

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);
 


 2.4.3 Add timer related defines/variables/callback function and add timer start in app_init in app.c.

#define MEASUREMENT_INTERVAL_MS      5000
static sl_sleeptimer_timer_handle_t measurement_timer;



static void measurement_callback(sl_sleeptimer_timer_handle_t *handle, void *data)
{
  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);
}



void app_init(void)
{
... 
otCliOutputFormat("app_init: Setup periodic measurement timer \r\n");
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.

 


 

Thursday, February 9, 2017

How to add a COAP resource to read ADC input from DIO23 in Contiki cc26xx-web-demo on CC2650 LaunchPad.

To add a COAP resource to read ADC input from DIO23 in Contiki cc26xx-web-demo on CC2650 LaunchPad, you have to add the following code with "+" into your cc26xx-web-demo.c, cc26xx-web-demo.h, coap-server.c, and res-sensors.c.

1. /examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c
@@ -55,9 +55,15 @@
 #include
 #include
 #include
+
+#include "ti-lib.h"
+#include "driverlib/aux_adc.h"
+#include "driverlib/aux_wuc.h"
+

 /*---------------------------------------------------------------------------*/
 PROCESS_NAME(cetic_6lbr_client_process);
 PROCESS(cc26xx_web_demo_process, "CC26XX Web Demo");
+PROCESS(adc_process, "ADC process");
 /*---------------------------------------------------------------------------*/
 /*
  * Update sensor readings in a staggered fashion every SENSOR_READING_PERIOD
@@ -84,6 +90,9 @@ static struct uip_icmp6_echo_reply_notification echo_reply_notification;
 static struct etimer echo_request_timer;
 int def_rt_rssi = 0;
 #endif
+
+uint16_t singleSample;
+

 /*---------------------------------------------------------------------------*/
 process_event_t cc26xx_web_demo_publish_event;
 process_event_t cc26xx_web_demo_config_loaded_event;
@@ -110,6 +119,9 @@ DEMO_SENSOR(batmon_temp, CC26XX_WEB_DEMO_SENSOR_BATMON_TEMP,
 DEMO_SENSOR(batmon_volt, CC26XX_WEB_DEMO_SENSOR_BATMON_VOLT,
             "Battery Volt", "battery-volt", "batmon_volt",
             CC26XX_WEB_DEMO_UNIT_VOLT);
+DEMO_SENSOR(adc_dio23, CC26XX_WEB_DEMO_SENSOR_ADC_DIO23,
+            "ADC DIO23", "adc-dio23", "adc_dio23",
+            CC26XX_WEB_DEMO_UNIT_VOLT);

 /* Sensortag sensors */
 #if BOARD_SENSORTAG
@@ -464,6 +476,14 @@ get_batmon_reading(void *data)
     }
   }

+  if(adc_dio23_reading.publish) {
+    if(1) {
+      buf = adc_dio23_reading.converted;
+      memset(buf, 0, CC26XX_WEB_DEMO_CONVERTED_LEN);
+      snprintf(buf, CC26XX_WEB_DEMO_CONVERTED_LEN, "%d", singleSample);
+    }
+  }
+

   ctimer_set(&batmon_timer, next, get_batmon_reading, NULL);
 }
 /*---------------------------------------------------------------------------*/
@@ -825,6 +845,7 @@ init_sensors(void)

   list_add(sensor_list, &batmon_temp_reading);
   list_add(sensor_list, &batmon_volt_reading);
+  list_add(sensor_list, &adc_dio23_reading);
   SENSORS_ACTIVATE(batmon_sensor);

 #if BOARD_SENSORTAG
@@ -864,6 +885,7 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data)

   /* Start all other (enabled) processes first */
   process_start(&httpd_simple_process, NULL);
+  process_start(&adc_process, NULL);
 #if CC26XX_WEB_DEMO_COAP_SERVER
   process_start(&coap_server_process, NULL);
 #endif
@@ -966,6 +988,56 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data)

   PROCESS_END();
 }
+
+PROCESS_THREAD(adc_process, ev, data)
+{
+  PROCESS_BEGIN();
+  static struct etimer et_adc;
+  while(1)
+  {
+         etimer_set(&et_adc, CLOCK_SECOND*5);
+         PROCESS_WAIT_EVENT();
+         if(etimer_expired(&et_adc)) {
+               //intialisation of ADC
+               ti_lib_aon_wuc_aux_wakeup_event(AONWUC_AUX_WAKEUP);
+               while(!(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON))
+               { }
+
+               // Enable clock for ADC digital and analog interface (not currently enabled in driver)
+               // Enable clocks
+               ti_lib_aux_wuc_clock_enable(AUX_WUC_ADI_CLOCK | AUX_WUC_ANAIF_CLOCK | AUX_WUC_SMPH_CLOCK);
+               while(ti_lib_aux_wuc_clock_status(AUX_WUC_ADI_CLOCK | AUX_WUC_ANAIF_CLOCK | AUX_WUC_SMPH_CLOCK) != AUX_WUC_CLOCK_READY)
+               { }
+               //printf("clock selected\r\n");
+
+               // Connect AUX IO7 (DIO23, but also DP2 on XDS110) as analog input.
+               AUXADCSelectInput(ADC_COMPB_IN_AUXIO7);
+               //printf("input selected\r\n");
+
+               // Set up ADC range
+               // AUXADC_REF_FIXED = nominally 4.3 V
+               AUXADCEnableSync(AUXADC_REF_FIXED,  AUXADC_SAMPLE_TIME_2P7_US, AUXADC_TRIGGER_MANUAL);
+               //printf("init adc --- OK\r\n");
+
+               //Trigger ADC converting
+               AUXADCGenManualTrigger();
+               //printf("trigger --- OK\r\n");
+
+               //reading adc value
+               singleSample = AUXADCReadFifo();
+
+               printf("%d mv on ADC\r\n",singleSample);
+
+               //shut the adc down
+               AUXADCDisable();
+               //printf("disable --- OK\r\n");
+               get_batmon_reading(NULL);
+
+               etimer_reset(&et_adc);
+               }
+  }
+  PROCESS_END();
+}

 

2./examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h
@@ -146,6 +146,7 @@
 #define CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_X    12
 #define CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_Y    13
 #define CC26XX_WEB_DEMO_SENSOR_MPU_GYRO_Z    14
+#define CC26XX_WEB_DEMO_SENSOR_ADC_DIO23     15
 /*---------------------------------------------------------------------------*/
 extern process_event_t cc26xx_web_demo_publish_event;
 extern process_event_t cc26xx_web_demo_config_loaded_event;

3. /examples/cc26xx/cc26xx-web-demo/coap-server.c
@@ -50,6 +50,7 @@ extern resource_t res_leds;

 extern resource_t res_batmon_temp;
 extern resource_t res_batmon_volt;
+extern resource_t res_adc_dio23;

 extern resource_t res_device_sw;
 extern resource_t res_device_hw;
@@ -133,6 +134,7 @@ PROCESS_THREAD(coap_server_process, ev, data)

   rest_activate_resource(&res_batmon_temp, "sen/batmon/temp");
   rest_activate_resource(&res_batmon_volt, "sen/batmon/voltage");
+  rest_activate_resource(&res_adc_dio23, "adc/dio23");

   rest_activate_resource(&res_device_hw, "dev/mdl/hw");
   rest_activate_resource(&res_device_sw, "dev/mdl/sw");

4. examples/cc26xx/cc26xx-web-demo/resources/res-sensors.c
@@ -111,12 +111,24 @@ res_get_handler_batmon_volt(void *request, void *response, uint8_t *buffer,
                       buffer, preferred_size, offset);
 }
 /*---------------------------------------------------------------------------*/
+static void
+res_get_handler_adc_dio23(void *request, void *response, uint8_t *buffer,
+                            uint16_t preferred_size, int32_t *offset)
+{
+  res_get_handler_all(CC26XX_WEB_DEMO_SENSOR_ADC_DIO23, request, response,
+                      buffer, preferred_size, offset);
+}
+/*---------------------------------------------------------------------------*/

 RESOURCE(res_batmon_temp, "title=\"Battery Temp\";rt=\"C\"",
          res_get_handler_batmon_temp, NULL, NULL, NULL);
 /*---------------------------------------------------------------------------*/
 RESOURCE(res_batmon_volt, "title=\"Battery Voltage\";rt=\"mV\"",
          res_get_handler_batmon_volt, NULL, NULL, NULL);
 /*---------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+RESOURCE(res_adc_dio23, "title=\"ADC DIO23\";rt=\"mV\"",
+         res_get_handler_adc_dio23, NULL, NULL, NULL);
+/*---------------------------------------------------------------------------*/

 #if BOARD_SENSORTAG
 /*---------------------------------------------------------------------------*/
 /* MPU resources and handler: Accelerometer and Gyro */

Build cc26xx-web-demo for CC2650 LaunchPad by "make TARGET=srf06-cc26xx BOARD=launchpad/cc2650 cc26xx-web-demo.bin" and download cc26xx-web-demo.bin to your CC2650 LaunchPad. Let it join 6lbr and you should see resource adc/dio23 on COAP interface. You can press Get button to get the ADC reading from DIO23. Try to connect different voltage (0-3.6V) to test.