Pelion Device Management example over 15.4 Thread for Thunderboard Sense 2 board

Dependencies:   ICM20648 BMP280 Si1133 Si7210 AMS_CCS811_gas_sensor SI7021

DEPRECATED

This example application is not maintained and not recommended. It uses an old version of Mbed OS, Pelion DM, and Arm toolchain. It doesn't work with Mbed Studio.

Please use: https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-pelion/

This example is known to work great on the following platforms:

Follow the Quick-Start instructions: https://cloud.mbed.com/quick-start

Thunderboard Sense 2

Example functionality

This example showcases the following device functionality:

  • Read onboard sensors, and report them as Pelion LWM2M resources:
    • Barometric Pressure and Temperature (BMP280)
    • Relative Humidity and Temperature (Si7021)
    • Air quality - CO2 and tVOC (CCS811)
    • Light intensity and UV level (Si1133)
    • Hall effect and Temperature (Si7210)
    • Accelerometer and Gyroscope (ICM20648)
  • It also exposes the RGB LEDs for triggering flashes in a specific color
  • On user button click, increment Pelion LWM2M button resource.

/media/uploads/screamer/pelion_st_humidity_reading.png?v=2

15.4 Thread setup

This example program requires that a Thread Border Router is available. A Border Router is a network gateway between a wireless 6LoWPAN mesh network and a backhaul network. It controls and relays traffic between the two networks. In a typical setup, a 6LoWPAN border router is connected to another router in the backhaul network (over Ethernet or a serial line) which in turn forwards traffic to/from the internet or a private company LAN, for instance.

https://raw.githubusercontent.com/ARMmbed/nanostack-border-router/f8bf21aac12c9926afba252187e2adf2525bf1eb/images/br_role.png

Instructions how to set up a Thread Border Router

Use this example with Mbed CLI

1. Import the application into your desktop:

mbed import https://os.mbed.com/teams/SiliconLabs/code/pelion-example-tbsense2

cd pelion-example-tbsense2

2. Install the CLOUD_SDK_API_KEY

mbed config -G CLOUD_SDK_API_KEY <PELION_DM_API_KEY>

For instructions on how to generate your API key, please see the documentation.

3. Initialize firmware credentials (done once per repository). You can use the following command:

mbed dm init -d "<your company name in Pelion DM>" --model-name "<product model identifier>" -q --force

If above command do not work for your Mbed CLI, please consider upgrading Mbed CLI to version 1.8.x or above.

4. Compile and program:

mbed compile -t <toolchain> -m TB_SENSE_2

(supported toolchains : GCC_ARM / ARM / IAR)

5. You can connect on a virtual terminal/COM port to the platform using:

mbed sterm -b 115200

This should give you an output similar to:

[BOOT] Mbed Bootloader
[BOOT] ARM: 00000000000000000000
[BOOT] OEM: 00000000000000000000
[BOOT] Layout: 0 90AC
[BOOT] Active firmware integrity check:
[BOOT] SHA256: 615A11A7F03B1F048573E2CB51D8C9A5DD4E6F17A7F8E79C4B64E3241FF78974
[BOOT] Version: 1553594998
[BOOT] Slot 0 is empty
[BOOT] Active firmware up-to-date
[BOOT] Application's start address: 0x10400
[BOOT] Application's jump address: 0x10FBD
[BOOT] Application's stack address: 0x20040000
[BOOT] Forwarding to application...


Starting Simple Pelion Device Management Client example
You can hold the user button during boot to format the storage and change the device identity.
Connecting to the network using 802.15.4...
Connected to the network successfully. IP address: 2001:****:****:****:****:****:****:73bc
Initializing Pelion Device Management Client...
Si7021 Electronic Serial Number:                0         15b5ffff, firmware rev 20
Registered to Pelion Device Management. Endpoint Name: 0169b91a********************01a0
                                                                 
BMP280 temp:     32.750 C,   pressure: 1030.750 [mbar]            
Si7021 temp:     27.529 C,   humidity:   24.842 %                 
Si7210 temp:     34.484 C,   field:      -0.076 [mT]              
Si1133 light:  1258.574 lux, UV level:    0.031                       
CCS811 CO2:           0 ppm, VoC:             0 ppb                   
ICM20648 acc:    -0.093 x,  -0.057 y,     0.969 z [mg]            
ICM20648 gyro:   -1.503 x,   0.122 y,    -0.771 z [mdps]          
    
Committer:
screamer
Date:
Mon Mar 25 22:47:24 2019 +0000
Revision:
1:cf0bd0446785
Parent:
0:3853978178c0
Child:
2:8d3f3f35f089
Application improvements for simplicity.
Unify all sensors initialization under sensors_init().
Move all timers to a single sensors_update() routine.
Introduce console output to enable local monitoring.
Macro SENSORS_POLL_INTERVAL defines the sensors poll rate.
Macro SEND_ALL_SENSORS can be used to limit the number of resources sent/reported.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:3853978178c0 1 // Includes and declarations for Pelion DM Client to work
screamer 0:3853978178c0 2 #include "simple-mbed-cloud-client.h"
screamer 0:3853978178c0 3 #include "BlockDevice.h"
screamer 0:3853978178c0 4 #include "LittleFileSystem.h"
screamer 0:3853978178c0 5 #include "NetworkInterface.h"
screamer 0:3853978178c0 6 #include "mbed_trace.h"
screamer 0:3853978178c0 7 #include "Nanostack.h"
screamer 0:3853978178c0 8 #include "ns_file_system.h"
screamer 0:3853978178c0 9
screamer 1:cf0bd0446785 10 // Thunderboard Sense 2 connects over 802.15.4 by default. Since the mesh stack is a bit iffy.
screamer 1:cf0bd0446785 11 // We'll register a 'network down' handler to act as a kind of watchdog for the Pelion DM Client.
screamer 0:3853978178c0 12 NetworkInterface *net = NetworkInterface::get_default_instance();
screamer 0:3853978178c0 13
screamer 1:cf0bd0446785 14 // Thunderboard Sense 2 has a 1M external flash, which is being shared between upgrade storage and LittleFS.
screamer 1:cf0bd0446785 15 // LittleFS is instantiated at the start of storage, until the start address for upgrade storage.
screamer 0:3853978178c0 16 // Currently, this split is at 256/768 for FS/upgrade.
screamer 0:3853978178c0 17 BlockDevice* bd = BlockDevice::get_default_instance();
screamer 0:3853978178c0 18 SlicingBlockDevice sd(bd, 0, MBED_CONF_UPDATE_CLIENT_STORAGE_ADDRESS);
screamer 0:3853978178c0 19 LittleFileSystem fs("fs", &sd);
screamer 0:3853978178c0 20
screamer 1:cf0bd0446785 21 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
screamer 1:cf0bd0446785 22 // This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed.
screamer 0:3853978178c0 23 EventQueue eventQueue;
screamer 0:3853978178c0 24
screamer 1:cf0bd0446785 25 InterruptIn button(BTN0);
screamer 0:3853978178c0 26
screamer 0:3853978178c0 27 //------------------------------------------------------------------------------
screamer 0:3853978178c0 28 // Includes and declarations for our sensor array
screamer 0:3853978178c0 29 #include "BMP280.h"
screamer 0:3853978178c0 30 #include "Si1133.h"
screamer 0:3853978178c0 31 #include "SI7021.h"
screamer 0:3853978178c0 32 #include "AMS_CCS811.h"
screamer 0:3853978178c0 33
screamer 0:3853978178c0 34 // Define measurement intervals in seconds
screamer 1:cf0bd0446785 35 #define SENSORS_POLL_INTERVAL 1.0
screamer 1:cf0bd0446785 36 #define SEND_ALL_SENSORS
screamer 0:3853978178c0 37
screamer 0:3853978178c0 38 /* Turn on power supply to ENV sensor suite */
screamer 0:3853978178c0 39 DigitalOut env_en(PF9, 1);
screamer 0:3853978178c0 40 /* Turn on power to CCS811 sensor */
screamer 0:3853978178c0 41 DigitalOut ccs_en(PF14, 1);
screamer 0:3853978178c0 42
screamer 0:3853978178c0 43 BMP280 barometer(PC4, PC5);
screamer 0:3853978178c0 44 Si1133 light_sensor(PC4, PC5);
screamer 0:3853978178c0 45 SI7021 rht_sensor(PC4, PC5, SI7021::SI7021_ADDRESS, 400000);
screamer 0:3853978178c0 46
screamer 0:3853978178c0 47 InterruptIn ccs_int(PF13);
screamer 0:3853978178c0 48 I2C ccs_i2c(PB6, PB7);
screamer 0:3853978178c0 49 AMS_CCS811 aqs(&ccs_i2c, PF15);
screamer 0:3853978178c0 50
screamer 1:cf0bd0446785 51 // Declaring pointers for access to Pelion Client resources outside of main()
screamer 1:cf0bd0446785 52 MbedCloudClientResource *res_button;
screamer 1:cf0bd0446785 53 MbedCloudClientResource *res_led;
screamer 0:3853978178c0 54
screamer 1:cf0bd0446785 55 #ifdef SEND_ALL_SENSORS
screamer 1:cf0bd0446785 56 MbedCloudClientResource *res_light;
screamer 1:cf0bd0446785 57 MbedCloudClientResource *res_barometer;
screamer 1:cf0bd0446785 58 MbedCloudClientResource *res_temperature;
screamer 1:cf0bd0446785 59 MbedCloudClientResource *res_humidity;
screamer 1:cf0bd0446785 60 MbedCloudClientResource *res_co2;
screamer 1:cf0bd0446785 61 MbedCloudClientResource *res_tvoc;
screamer 1:cf0bd0446785 62 #endif /* SEND_ALL_SENSORS */
screamer 0:3853978178c0 63
screamer 1:cf0bd0446785 64 // When the device is registered, this variable will be used to access various useful information, like device ID etc.
screamer 1:cf0bd0446785 65 static const ConnectorClientEndpointInfo* endpointInfo;
screamer 0:3853978178c0 66
screamer 0:3853978178c0 67
screamer 0:3853978178c0 68 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
screamer 0:3853978178c0 69 static int num_count = 0;
screamer 0:3853978178c0 70 static int event = 0;
screamer 0:3853978178c0 71
screamer 0:3853978178c0 72 static DigitalOut led_ch_red(PD11, 1);
screamer 0:3853978178c0 73 static DigitalOut led_ch_green(PD12, 1);
screamer 0:3853978178c0 74 static DigitalOut led_ch_blue(PD13, 1);
screamer 0:3853978178c0 75
screamer 0:3853978178c0 76 static DigitalOut led_com_0(PI0, 0);
screamer 0:3853978178c0 77 static DigitalOut led_com_1(PI1, 0);
screamer 0:3853978178c0 78 static DigitalOut led_com_2(PI2, 0);
screamer 0:3853978178c0 79 static DigitalOut led_com_3(PI3, 0);
screamer 0:3853978178c0 80
screamer 0:3853978178c0 81 static DigitalOut led_rgb_en(PJ14, 0);
screamer 0:3853978178c0 82
screamer 0:3853978178c0 83 if (buffer != NULL) {
screamer 1:cf0bd0446785 84 printf("POST received. POST data: %s\n", buffer);
screamer 0:3853978178c0 85
screamer 0:3853978178c0 86 if (event > 0) {
screamer 1:cf0bd0446785 87 printf("Not blinking since previous blink still in progress\n");
screamer 0:3853978178c0 88 return;
screamer 0:3853978178c0 89 }
screamer 0:3853978178c0 90 num_count = 0;
screamer 0:3853978178c0 91 for (size_t i = 0, num_arg = 0; i < 20 || buffer[i] == 0; i++) {
screamer 0:3853978178c0 92 if (buffer[i] == ':') {
screamer 0:3853978178c0 93 num_arg++;
screamer 0:3853978178c0 94 continue;
screamer 0:3853978178c0 95 }
screamer 0:3853978178c0 96
screamer 0:3853978178c0 97 if (buffer[i] >= '0' && buffer[i] <= '9') {
screamer 0:3853978178c0 98 switch (num_arg) {
screamer 0:3853978178c0 99 case 0:
screamer 1:cf0bd0446785 100 if (buffer[i] == '1') {
screamer 1:cf0bd0446785 101 led_ch_red = 1;
screamer 1:cf0bd0446785 102 } else {
screamer 1:cf0bd0446785 103 led_ch_red = 0;
screamer 1:cf0bd0446785 104 }
screamer 1:cf0bd0446785 105 break;
screamer 0:3853978178c0 106 case 1:
screamer 1:cf0bd0446785 107 if (buffer[i] == '1') {
screamer 1:cf0bd0446785 108 led_ch_green = 1;
screamer 1:cf0bd0446785 109 } else {
screamer 1:cf0bd0446785 110 led_ch_green = 0;
screamer 1:cf0bd0446785 111 }
screamer 1:cf0bd0446785 112 break;
screamer 0:3853978178c0 113 case 2:
screamer 1:cf0bd0446785 114 if (buffer[i] == '1') {
screamer 1:cf0bd0446785 115 led_ch_blue = 1;
screamer 1:cf0bd0446785 116 } else {
screamer 1:cf0bd0446785 117 led_ch_blue = 0;
screamer 1:cf0bd0446785 118 }
screamer 1:cf0bd0446785 119 break;
screamer 0:3853978178c0 120 case 3:
screamer 1:cf0bd0446785 121 num_count = ((buffer[i] - 0x30) * 2) - 1;
screamer 1:cf0bd0446785 122 printf("blinking %d\n", num_count);
screamer 1:cf0bd0446785 123 break;
screamer 0:3853978178c0 124 default:
screamer 1:cf0bd0446785 125 break;
screamer 0:3853978178c0 126 }
screamer 0:3853978178c0 127 } else {
screamer 0:3853978178c0 128 //garbage...
screamer 0:3853978178c0 129 continue;
screamer 0:3853978178c0 130 }
screamer 0:3853978178c0 131 if (num_count > 0) {
screamer 0:3853978178c0 132 break;
screamer 0:3853978178c0 133 }
screamer 0:3853978178c0 134 }
screamer 0:3853978178c0 135
screamer 0:3853978178c0 136 if (num_count > 0) {
screamer 0:3853978178c0 137 led_rgb_en = 1;
screamer 0:3853978178c0 138 led_com_0 = 1;
screamer 0:3853978178c0 139 led_com_1 = 1;
screamer 0:3853978178c0 140 event = eventQueue.call_in(1000, blink_callback, resource, (const uint8_t *)NULL, 0);
screamer 0:3853978178c0 141 if (event == 0) {
screamer 0:3853978178c0 142 led_rgb_en = 0;
screamer 0:3853978178c0 143 num_count = 0;
screamer 0:3853978178c0 144 }
screamer 0:3853978178c0 145 }
screamer 0:3853978178c0 146 } else {
screamer 0:3853978178c0 147 num_count--;
screamer 0:3853978178c0 148 led_com_0 = (num_count & 1);
screamer 0:3853978178c0 149 led_com_1 = (num_count & 1);
screamer 0:3853978178c0 150
screamer 0:3853978178c0 151 if (num_count == 0) {
screamer 0:3853978178c0 152 led_rgb_en = 0;
screamer 0:3853978178c0 153 event = 0;
screamer 0:3853978178c0 154 } else {
screamer 0:3853978178c0 155 event = eventQueue.call_in(1000, blink_callback, resource, (const uint8_t *)NULL, 0);
screamer 0:3853978178c0 156 if (event == 0) {
screamer 0:3853978178c0 157 led_rgb_en = 0;
screamer 0:3853978178c0 158 num_count = 0;
screamer 0:3853978178c0 159 }
screamer 0:3853978178c0 160 }
screamer 0:3853978178c0 161 }
screamer 0:3853978178c0 162 }
screamer 0:3853978178c0 163
screamer 1:cf0bd0446785 164 /**
screamer 1:cf0bd0446785 165 * Button function triggered by the physical button press.
screamer 1:cf0bd0446785 166 */
screamer 1:cf0bd0446785 167 void button_press() {
screamer 1:cf0bd0446785 168 int v = res_button->get_value_int() + 1;
screamer 1:cf0bd0446785 169 res_button->set_value(v);
screamer 1:cf0bd0446785 170 printf("*** Button clicked %d times \n", v);
screamer 1:cf0bd0446785 171 }
screamer 1:cf0bd0446785 172
screamer 1:cf0bd0446785 173 /**
screamer 1:cf0bd0446785 174 * Notification callback handler
screamer 1:cf0bd0446785 175 * @param resource The resource that triggered the callback
screamer 1:cf0bd0446785 176 * @param status The delivery status of the notification
screamer 1:cf0bd0446785 177 */
screamer 1:cf0bd0446785 178 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
screamer 1:cf0bd0446785 179 printf("*** Button notification, status %s (%d) \n", MbedCloudClientResource::delivery_status_to_string(status), status);
screamer 1:cf0bd0446785 180 }
screamer 1:cf0bd0446785 181
screamer 1:cf0bd0446785 182 /**
screamer 1:cf0bd0446785 183 * Registration callback handler
screamer 1:cf0bd0446785 184 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
screamer 1:cf0bd0446785 185 */
screamer 1:cf0bd0446785 186 void registered(const ConnectorClientEndpointInfo *endpoint) {
screamer 1:cf0bd0446785 187 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
screamer 1:cf0bd0446785 188 endpointInfo = endpoint;
screamer 1:cf0bd0446785 189 }
screamer 1:cf0bd0446785 190
screamer 1:cf0bd0446785 191 /**
screamer 1:cf0bd0446785 192 * Initialize sensors
screamer 1:cf0bd0446785 193 */
screamer 1:cf0bd0446785 194 void sensors_init() {
screamer 1:cf0bd0446785 195 barometer.initialize();
screamer 1:cf0bd0446785 196
screamer 1:cf0bd0446785 197 light_sensor.open();
screamer 1:cf0bd0446785 198
screamer 1:cf0bd0446785 199 SI7021::SI7021_status_t result = rht_sensor.SI7021_SoftReset();
screamer 1:cf0bd0446785 200 if (result == SI7021::SI7021_SUCCESS) {
screamer 1:cf0bd0446785 201 wait_ms(15);
screamer 1:cf0bd0446785 202 SI7021::SI7021_vector_data_t result_data;
screamer 1:cf0bd0446785 203 result = rht_sensor.SI7021_Conf(SI7021::SI7021_RESOLUTION_RH_11_TEMP_11,
screamer 1:cf0bd0446785 204 SI7021::SI7021_HTRE_DISABLED);
screamer 1:cf0bd0446785 205 result = rht_sensor.SI7021_GetElectronicSerialNumber(&result_data);
screamer 1:cf0bd0446785 206 result = rht_sensor.SI7021_GetFirmwareRevision(&result_data);
screamer 1:cf0bd0446785 207 printf("Si7021 Electronic Serial Number: %16x %16x, firmware rev %02x\n",
screamer 1:cf0bd0446785 208 result_data.ElectronicSerialNumber_MSB,
screamer 1:cf0bd0446785 209 result_data.ElectronicSerialNumber_LSB,
screamer 1:cf0bd0446785 210 result_data.FirmwareRevision);
screamer 1:cf0bd0446785 211 }
screamer 1:cf0bd0446785 212
screamer 1:cf0bd0446785 213 if(!aqs.init()) {
screamer 1:cf0bd0446785 214 printf("CCS811: Failed init()\n");
screamer 1:cf0bd0446785 215 } else {
screamer 1:cf0bd0446785 216 if(!aqs.mode(AMS_CCS811::SIXTY_SECOND)) {
screamer 1:cf0bd0446785 217 printf("CCS811: Failed to set mode\n");
screamer 1:cf0bd0446785 218 }
screamer 1:cf0bd0446785 219 // aqs.enable_interupt(true);
screamer 1:cf0bd0446785 220 }
screamer 1:cf0bd0446785 221 }
screamer 1:cf0bd0446785 222
screamer 1:cf0bd0446785 223 /**
screamer 1:cf0bd0446785 224 * Update sensors and report their values.
screamer 1:cf0bd0446785 225 * This function is called periodically.
screamer 1:cf0bd0446785 226 */
screamer 1:cf0bd0446785 227 void sensors_update() {
screamer 1:cf0bd0446785 228 static size_t CCS811_samples = 0;
screamer 1:cf0bd0446785 229 SI7021::SI7021_status_t rht_reading, humidity_reading, temp_reading;
screamer 1:cf0bd0446785 230 SI7021::SI7021_vector_data_t humidity_data, temp_data;
screamer 1:cf0bd0446785 231
screamer 1:cf0bd0446785 232 float val_barometer = barometer.getPressure();
screamer 1:cf0bd0446785 233
screamer 1:cf0bd0446785 234 float light_level, uv_index;
screamer 1:cf0bd0446785 235 bool light_reading = light_sensor.get_light_and_uv(&light_level, &uv_index);
screamer 1:cf0bd0446785 236
screamer 1:cf0bd0446785 237 rht_reading = rht_sensor.SI7021_TriggerHumidity(SI7021::SI7021_NO_HOLD_MASTER_MODE);
screamer 1:cf0bd0446785 238 if (rht_reading == SI7021::SI7021_SUCCESS) {
screamer 1:cf0bd0446785 239 wait_ms(30);
screamer 1:cf0bd0446785 240 humidity_reading = rht_sensor.SI7021_ReadHumidity(&humidity_data);
screamer 1:cf0bd0446785 241 temp_reading = rht_sensor.SI7021_ReadTemperatureFromRH(&temp_data);
screamer 1:cf0bd0446785 242 aqs.env_data(humidity_data.RelativeHumidity, temp_data.Temperature);
screamer 1:cf0bd0446785 243 }
screamer 1:cf0bd0446785 244
screamer 1:cf0bd0446785 245 aqs.has_new_data();
screamer 1:cf0bd0446785 246 int co2 = aqs.co2_read();
screamer 1:cf0bd0446785 247 int tvoc = aqs.tvoc_read();
screamer 1:cf0bd0446785 248
screamer 1:cf0bd0446785 249 printf(" \n");
screamer 1:cf0bd0446785 250 printf("Si1133 light: %7.2f lux, UV level: %7.2f \n", light_level, uv_index);
screamer 1:cf0bd0446785 251 printf("SI7021 temp: %7.2f C, humidity: %7.2f %% \n", temp_data.Temperature, humidity_data.RelativeHumidity);
screamer 1:cf0bd0446785 252 printf("CCS811 CO2: %7d ppm, TVOC: %7d ppm \n", co2, tvoc);
screamer 1:cf0bd0446785 253 printf("BMP280 pressure: %7.2f hPa \n", val_barometer);
screamer 1:cf0bd0446785 254
screamer 1:cf0bd0446785 255 printf("\r\033[5A");
screamer 1:cf0bd0446785 256
screamer 1:cf0bd0446785 257 if (endpointInfo) {
screamer 1:cf0bd0446785 258 #ifdef SEND_ALL_SENSORS
screamer 1:cf0bd0446785 259 res_barometer->set_value(val_barometer);
screamer 1:cf0bd0446785 260 if (light_reading) {
screamer 1:cf0bd0446785 261 res_light->set_value(light_level);
screamer 1:cf0bd0446785 262 }
screamer 1:cf0bd0446785 263 if (humidity_reading == SI7021::SI7021_SUCCESS) {
screamer 1:cf0bd0446785 264 res_humidity->set_value(humidity_data.RelativeHumidity);
screamer 1:cf0bd0446785 265 }
screamer 1:cf0bd0446785 266 if (temp_reading == SI7021::SI7021_SUCCESS) {
screamer 1:cf0bd0446785 267 res_temperature->set_value(temp_data.Temperature);
screamer 1:cf0bd0446785 268 }
screamer 1:cf0bd0446785 269 res_co2->set_value(co2);
screamer 1:cf0bd0446785 270 res_tvoc->set_value(tvoc);
screamer 1:cf0bd0446785 271 #endif /* SEND_ALL_SENSORS */
screamer 1:cf0bd0446785 272 }
screamer 1:cf0bd0446785 273 }
screamer 1:cf0bd0446785 274
screamer 0:3853978178c0 275 int main() {
screamer 1:cf0bd0446785 276 printf("\nStarting Simple Pelion Device Management Client example\n");
screamer 1:cf0bd0446785 277
screamer 1:cf0bd0446785 278 int storage_status = fs.mount(&sd);
screamer 1:cf0bd0446785 279 if (storage_status != 0) {
screamer 1:cf0bd0446785 280 printf("Storage mounting failed.\n");
screamer 1:cf0bd0446785 281 }
screamer 1:cf0bd0446785 282
screamer 1:cf0bd0446785 283 #if USE_BUTTON == 1
screamer 0:3853978178c0 284 // If the User button is pressed ons start, then format storage.
screamer 1:cf0bd0446785 285 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE);
screamer 1:cf0bd0446785 286 if (btn_pressed) {
screamer 1:cf0bd0446785 287 printf("User button is pushed on start...\n");
screamer 1:cf0bd0446785 288 }
screamer 1:cf0bd0446785 289 #else
screamer 1:cf0bd0446785 290 bool btn_pressed = FALSE;
screamer 1:cf0bd0446785 291 #endif /* USE_BUTTON */
screamer 1:cf0bd0446785 292
screamer 1:cf0bd0446785 293 if (storage_status || btn_pressed) {
screamer 1:cf0bd0446785 294 printf("Formatting the storage...\n");
screamer 1:cf0bd0446785 295 int storage_status = StorageHelper::format(&fs, &sd);
screamer 0:3853978178c0 296 if (storage_status != 0) {
screamer 0:3853978178c0 297 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status);
screamer 0:3853978178c0 298 }
screamer 0:3853978178c0 299 } else {
screamer 0:3853978178c0 300 printf("You can hold the user button during boot to format the storage and change the device identity.\n");
screamer 0:3853978178c0 301 }
screamer 0:3853978178c0 302
screamer 0:3853978178c0 303 Nanostack::get_instance(); // ensure Nanostack is initialised
screamer 0:3853978178c0 304 ns_file_system_set_root_path("/fs/");
screamer 0:3853978178c0 305
screamer 1:cf0bd0446785 306 // Connect to the internet (DHCP is expected to be on)
screamer 1:cf0bd0446785 307 printf("Connecting to the network using 802.15.4...\n");
screamer 1:cf0bd0446785 308
screamer 1:cf0bd0446785 309 nsapi_error_t net_status = -1;
screamer 1:cf0bd0446785 310 for (int tries = 0; tries < 3; tries++) {
screamer 1:cf0bd0446785 311 net_status = net->connect();
screamer 1:cf0bd0446785 312 if (net_status == NSAPI_ERROR_OK) {
screamer 1:cf0bd0446785 313 break;
screamer 1:cf0bd0446785 314 } else {
screamer 1:cf0bd0446785 315 printf("Unable to connect to network. Retrying...\n");
screamer 1:cf0bd0446785 316 }
screamer 1:cf0bd0446785 317 }
screamer 1:cf0bd0446785 318
screamer 1:cf0bd0446785 319 if (net_status != NSAPI_ERROR_OK) {
screamer 1:cf0bd0446785 320 printf("ERROR: Connecting to the network failed (%d)!\n", net_status);
screamer 1:cf0bd0446785 321 return -1;
screamer 1:cf0bd0446785 322 }
screamer 1:cf0bd0446785 323
screamer 1:cf0bd0446785 324 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
screamer 1:cf0bd0446785 325
screamer 1:cf0bd0446785 326 printf("Initializing Pelion Device Management Client...\n");
screamer 0:3853978178c0 327
screamer 0:3853978178c0 328 /* Initialize Simple Pelion DM Client */
screamer 0:3853978178c0 329 SimpleMbedCloudClient client(net, &sd, &fs);
screamer 1:cf0bd0446785 330 int client_status = client.init();
screamer 1:cf0bd0446785 331 if (client_status != 0) {
screamer 1:cf0bd0446785 332 printf("ERROR: Pelion Client initialization failed (%d)\n", client_status);
screamer 1:cf0bd0446785 333 return -1;
screamer 1:cf0bd0446785 334 }
screamer 0:3853978178c0 335
screamer 0:3853978178c0 336 /* Create resources */
screamer 1:cf0bd0446785 337 res_led = client.create_resource("3201/0/5853", "LED blinking (R:G:B:cnt)");
screamer 1:cf0bd0446785 338 res_led->observable(false);
screamer 1:cf0bd0446785 339 res_led->set_value("0:0:0:0");
screamer 1:cf0bd0446785 340 res_led->attach_post_callback(blink_callback);
screamer 1:cf0bd0446785 341 res_led->methods(M2MMethod::POST);
screamer 0:3853978178c0 342
screamer 1:cf0bd0446785 343 res_button = client.create_resource("3200/0/5501", "button_count");
screamer 1:cf0bd0446785 344 res_button->set_value(0);
screamer 1:cf0bd0446785 345 res_button->methods(M2MMethod::GET);
screamer 1:cf0bd0446785 346 res_button->observable(true);
screamer 1:cf0bd0446785 347 res_button->attach_notification_callback(button_callback);
screamer 0:3853978178c0 348
screamer 1:cf0bd0446785 349 #ifdef SEND_ALL_SENSORS
screamer 1:cf0bd0446785 350 res_light = client.create_resource("3301/0/5853", "LightIntensity (lux)");
screamer 1:cf0bd0446785 351 res_light->set_value(0);
screamer 1:cf0bd0446785 352 res_light->observable(true);
screamer 1:cf0bd0446785 353 res_light->methods(M2MMethod::GET);
screamer 1:cf0bd0446785 354
screamer 1:cf0bd0446785 355 res_temperature = client.create_resource("3303/0/5853", "Temperature (C)");
screamer 1:cf0bd0446785 356 res_temperature->set_value(0);
screamer 1:cf0bd0446785 357 res_temperature->observable(true);
screamer 1:cf0bd0446785 358 res_temperature->methods(M2MMethod::GET);
screamer 0:3853978178c0 359
screamer 1:cf0bd0446785 360 res_humidity = client.create_resource("3304/0/5853", "Humidity (%)");
screamer 1:cf0bd0446785 361 res_humidity->set_value(0);
screamer 1:cf0bd0446785 362 res_humidity->observable(true);
screamer 1:cf0bd0446785 363 res_humidity->methods(M2MMethod::GET);
screamer 0:3853978178c0 364
screamer 1:cf0bd0446785 365 res_barometer = client.create_resource("3323/0/5853", "Barometric pressure (hPa)");
screamer 1:cf0bd0446785 366 res_barometer->set_value(0);
screamer 1:cf0bd0446785 367 res_barometer->observable(true);
screamer 1:cf0bd0446785 368 res_barometer->methods(M2MMethod::GET);
screamer 0:3853978178c0 369
screamer 1:cf0bd0446785 370 res_co2 = client.create_resource("33255/0/5853", "CO2 (ppm)");
screamer 1:cf0bd0446785 371 res_co2->set_value(0);
screamer 1:cf0bd0446785 372 res_co2->observable(true);
screamer 1:cf0bd0446785 373 res_co2->methods(M2MMethod::GET);
screamer 0:3853978178c0 374
screamer 1:cf0bd0446785 375 res_tvoc = client.create_resource("33256/0/5853", "VOC (ppm)");
screamer 1:cf0bd0446785 376 res_tvoc->set_value(0);
screamer 1:cf0bd0446785 377 res_tvoc->observable(true);
screamer 1:cf0bd0446785 378 res_tvoc->methods(M2MMethod::GET);
screamer 1:cf0bd0446785 379 #endif /* SEND_ALL_SENSORS */
screamer 0:3853978178c0 380
screamer 1:cf0bd0446785 381 sensors_init();
screamer 1:cf0bd0446785 382
screamer 1:cf0bd0446785 383 // Callback that fires when registering is complete
screamer 1:cf0bd0446785 384 client.on_registered(&registered);
screamer 0:3853978178c0 385
screamer 0:3853978178c0 386 /* Register the device */
screamer 0:3853978178c0 387 client.register_and_connect();
screamer 0:3853978178c0 388
screamer 1:cf0bd0446785 389 button.fall(eventQueue.event(&button_press));
screamer 0:3853978178c0 390
screamer 1:cf0bd0446785 391 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
screamer 1:cf0bd0446785 392 Ticker timer;
screamer 1:cf0bd0446785 393 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL);
screamer 0:3853978178c0 394
screamer 0:3853978178c0 395 eventQueue.dispatch_forever();
screamer 1:cf0bd0446785 396 }