Garage Door Monitor and Opener

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Introduction

This system implements a simple garage door opener and environmental monitor. The hardware connects to the internet using Wi-Fi then on to the Pelion Device Management Platform which provides device monitoring and secure firmware updates over the air (FOTA). Pelion Device Management provides a flexible set of REST APIs which we will use to communicate to a web application running on an EC-2 instance in AWS. The web application will serve a web page where we can monitor and control our garage..

This project is intended to work on the DISCO-L475VG-IOT01A from ST Microelectronics It implements a simple actuator to drive a relay to simulate pushing the "open" button on older style garage doors which do not use a rolling code interface.

The system is designed to be mounted over the door so that the on board time of flight sensor can be used to detect if the door is open or closed.

The system also monitors temperature, humidity and barometric pressure.

https://os.mbed.com/media/uploads/JimCarver/garageopener.jpg

Hardware Requirements:

DISCO-L475G-IOT01A https://os.mbed.com/platforms/ST-Discovery-L475E-IOT01A/

Seeed Studio Grove Relay module https://www.seeedstudio.com/Grove-Relay.html

Seeed Studio Grove cable, I used this one: https://www.seeedstudio.com/Grove-4-pin-Male-Jumper-to-Grove-4-pin-Conversion-Cable-5-PCs-per-Pack.html

Connect to the PMOD connector like this:

https://os.mbed.com/media/uploads/JimCarver/opener.jpg

This shows how I installed so that the time of flight sensor can detect when the door is open

https://os.mbed.com/media/uploads/JimCarver/opener1.jpg https://os.mbed.com/media/uploads/JimCarver/opener2.jpg

To use the project:

You will also need a Pelion developers account.

I suggest you first use the Pelion quick state to become familiar with Pelion Device Management. https://os.mbed.com/guides/connect-device-to-pelion/1/?board=ST-Discovery-L475E-IOT01A

Web Interface

For my web interface I am running node-red under Ubuntu in an EC2 instance on AWS. This can run for 12 month within the constraints of their free tier. Here is a tutorial: https://nodered.org/docs/getting-started/aws

You will also need to install several node-red add ons:

sudo npm install -g node-red-dashboard

sudo npm install -g node-red-contrib-mbed-cloud

sudo npm istall -g node-red-contrib-moment

After starting node-red import the contents of GarageFlow.txt from the project, pin the flow into the page.

To enable your web app to access your Pelion account you need an API key.

First you will neet to use your Pelion account to create an API key.

https://os.mbed.com/media/uploads/JimCarver/api_portal.jpg

Now we need to apply that API key to your Node-Red flow.

https://os.mbed.com/media/uploads/JimCarver/api_node-red.jpg

Committer:
screamer
Date:
Tue Mar 26 15:56:37 2019 +0000
Revision:
32:2871fbeb627d
Parent:
30:15743b79c6cb
Child:
33:cfd9430e7d1e
Report float values for accelerometer, magnometer and gyroscope

Who changed what in which revision?

UserRevisionLine numberNew contents of line
adustm 1:e86b1cffc402 1 // ----------------------------------------------------------------------------
adustm 4:cf7342047b4d 2 // Copyright 2016-2018 ARM Ltd.
adustm 1:e86b1cffc402 3 //
adustm 1:e86b1cffc402 4 // SPDX-License-Identifier: Apache-2.0
adustm 1:e86b1cffc402 5 //
adustm 1:e86b1cffc402 6 // Licensed under the Apache License, Version 2.0 (the "License");
adustm 1:e86b1cffc402 7 // you may not use this file except in compliance with the License.
adustm 1:e86b1cffc402 8 // You may obtain a copy of the License at
adustm 1:e86b1cffc402 9 //
adustm 1:e86b1cffc402 10 // http://www.apache.org/licenses/LICENSE-2.0
adustm 1:e86b1cffc402 11 //
adustm 1:e86b1cffc402 12 // Unless required by applicable law or agreed to in writing, software
adustm 1:e86b1cffc402 13 // distributed under the License is distributed on an "AS IS" BASIS,
adustm 1:e86b1cffc402 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
adustm 1:e86b1cffc402 15 // See the License for the specific language governing permissions and
adustm 1:e86b1cffc402 16 // limitations under the License.
adustm 1:e86b1cffc402 17 // ----------------------------------------------------------------------------
screamer 28:0e774865873d 18
MarceloSalazar 9:265744785d33 19 #ifndef MBED_TEST_MODE
screamer 28:0e774865873d 20
adustm 1:e86b1cffc402 21 #include "mbed.h"
adustm 1:e86b1cffc402 22 #include "simple-mbed-cloud-client.h"
screamer 10:b27c962b3c3f 23 #include "LittleFileSystem.h"
screamer 10:b27c962b3c3f 24 #include "HTS221Sensor.h"
screamer 10:b27c962b3c3f 25 #include "LPS22HBSensor.h"
screamer 10:b27c962b3c3f 26 #include "LSM6DSLSensor.h"
screamer 10:b27c962b3c3f 27 #include "lis3mdl_class.h"
screamer 28:0e774865873d 28 #include "VL53L0X.h"
screamer 10:b27c962b3c3f 29
screamer 10:b27c962b3c3f 30 static DevI2C devI2c(PB_11,PB_10);
screamer 12:1f1a50e973db 31 static HTS221Sensor sen_hum_temp(&devI2c);
screamer 12:1f1a50e973db 32 static LPS22HBSensor sen_press_temp(&devI2c);
screamer 12:1f1a50e973db 33 static LSM6DSLSensor sen_acc_gyro(&devI2c,LSM6DSL_ACC_GYRO_I2C_ADDRESS_LOW,PD_11); // low address
screamer 12:1f1a50e973db 34 static LIS3MDL sen_mag(&devI2c);
screamer 28:0e774865873d 35 static DigitalOut shutdown_pin(PC_6);
screamer 28:0e774865873d 36 static VL53L0X sen_distance(&devI2c, &shutdown_pin, PC_7);
screamer 10:b27c962b3c3f 37
screamer 32:2871fbeb627d 38 #define SENSORS_POLL_INTERVAL 3.0
screamer 28:0e774865873d 39 #define SEND_ALL_SENSORS
adustm 1:e86b1cffc402 40
adustm 4:cf7342047b4d 41 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
adustm 4:cf7342047b4d 42 // 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
adustm 4:cf7342047b4d 43 EventQueue eventQueue;
adustm 1:e86b1cffc402 44
screamer 20:a9aab92d378b 45 // Default network interface object. Don't forget to change the WiFi SSID/password in mbed_app.json if you're using WiFi.
MarceloSalazar 9:265744785d33 46 NetworkInterface *net;
adustm 6:e0e1e1b93099 47
MarceloSalazar 9:265744785d33 48 // Default block device
MarceloSalazar 9:265744785d33 49 BlockDevice* bd = BlockDevice::get_default_instance();
screamer 10:b27c962b3c3f 50 SlicingBlockDevice sd(bd, 0, 2*1024*1024);
screamer 29:6ff737b67e7d 51 LittleFileSystem fs("fs");
adustm 4:cf7342047b4d 52
screamer 15:a0430d40a918 53 // Default User button for GET example
screamer 15:a0430d40a918 54 InterruptIn button(BUTTON1);
screamer 15:a0430d40a918 55 // Default LED to use for PUT/POST example
screamer 11:8df4529f060d 56 DigitalOut led(LED1);
screamer 11:8df4529f060d 57
MarceloSalazar 9:265744785d33 58 // Declaring pointers for access to Pelion Client resources outside of main()
screamer 12:1f1a50e973db 59 MbedCloudClientResource *res_button;
screamer 12:1f1a50e973db 60 MbedCloudClientResource *res_led;
adustm 1:e86b1cffc402 61
screamer 28:0e774865873d 62 #ifdef SEND_ALL_SENSORS
screamer 28:0e774865873d 63 // Temperature reading from microcontroller
screamer 28:0e774865873d 64 AnalogIn adc_temp(ADC_TEMP);
screamer 28:0e774865873d 65 // Voltage reference reading from microcontroller
screamer 28:0e774865873d 66 AnalogIn adc_vref(ADC_VREF);
screamer 28:0e774865873d 67 #endif
screamer 28:0e774865873d 68
screamer 12:1f1a50e973db 69 // Additional resources for sensor readings
screamer 12:1f1a50e973db 70 MbedCloudClientResource *res_humidity;
screamer 12:1f1a50e973db 71 MbedCloudClientResource *res_temperature;
screamer 13:42b49a0caade 72 #ifdef SEND_ALL_SENSORS
screamer 12:1f1a50e973db 73 MbedCloudClientResource *res_pressure;
screamer 12:1f1a50e973db 74 MbedCloudClientResource *res_temperature2;
screamer 28:0e774865873d 75 MbedCloudClientResource *res_magnometer_x;
screamer 28:0e774865873d 76 MbedCloudClientResource *res_magnometer_y;
screamer 28:0e774865873d 77 MbedCloudClientResource *res_magnometer_z;
screamer 28:0e774865873d 78 MbedCloudClientResource *res_accelerometer_x;
screamer 28:0e774865873d 79 MbedCloudClientResource *res_accelerometer_y;
screamer 28:0e774865873d 80 MbedCloudClientResource *res_accelerometer_z;
screamer 13:42b49a0caade 81 MbedCloudClientResource *res_gyroscope_x;
screamer 13:42b49a0caade 82 MbedCloudClientResource *res_gyroscope_y;
screamer 13:42b49a0caade 83 MbedCloudClientResource *res_gyroscope_z;
screamer 12:1f1a50e973db 84 MbedCloudClientResource *res_distance;
screamer 28:0e774865873d 85 MbedCloudClientResource *res_adc_temp;
screamer 28:0e774865873d 86 MbedCloudClientResource *res_adc_voltage;
screamer 13:42b49a0caade 87 #endif /* SEND_ALL_SENSORS */
adustm 1:e86b1cffc402 88
screamer 10:b27c962b3c3f 89 // When the device is registered, this variable will be used to access various useful information, like device ID etc.
screamer 10:b27c962b3c3f 90 static const ConnectorClientEndpointInfo* endpointInfo;
adustm 1:e86b1cffc402 91
screamer 10:b27c962b3c3f 92 /**
adustm 4:cf7342047b4d 93 * PUT handler
adustm 4:cf7342047b4d 94 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 95 * @param newValue Updated value for the resource
adustm 4:cf7342047b4d 96 */
screamer 32:2871fbeb627d 97 void put_callback(MbedCloudClientResource *resource, m2m::String newValue) {
screamer 29:6ff737b67e7d 98 printf("*** PUT received, new value: %s \n", newValue.c_str());
screamer 11:8df4529f060d 99 led = atoi(newValue.c_str());
adustm 1:e86b1cffc402 100 }
adustm 1:e86b1cffc402 101
adustm 4:cf7342047b4d 102 /**
adustm 4:cf7342047b4d 103 * POST handler
adustm 4:cf7342047b4d 104 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 105 * @param buffer If a body was passed to the POST function, this contains the data.
adustm 4:cf7342047b4d 106 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
adustm 4:cf7342047b4d 107 * @param size Size of the body
adustm 4:cf7342047b4d 108 */
screamer 32:2871fbeb627d 109 void post_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
screamer 32:2871fbeb627d 110 printf("*** POST received (length %u). Payload: ", size);
screamer 32:2871fbeb627d 111 for (size_t ix = 0; ix < size; ix++) {
screamer 32:2871fbeb627d 112 printf("%02x ", buffer[ix]);
screamer 32:2871fbeb627d 113 }
screamer 32:2871fbeb627d 114 printf("\n");
screamer 11:8df4529f060d 115 }
adustm 1:e86b1cffc402 116
screamer 11:8df4529f060d 117 /**
screamer 13:42b49a0caade 118 * Button function triggered by the physical button press.
screamer 11:8df4529f060d 119 */
screamer 11:8df4529f060d 120 void button_press() {
screamer 12:1f1a50e973db 121 int v = res_button->get_value_int() + 1;
screamer 12:1f1a50e973db 122 res_button->set_value(v);
screamer 29:6ff737b67e7d 123 printf("*** Button clicked %d times \n", v);
adustm 1:e86b1cffc402 124 }
adustm 1:e86b1cffc402 125
adustm 4:cf7342047b4d 126 /**
adustm 4:cf7342047b4d 127 * Notification callback handler
adustm 4:cf7342047b4d 128 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 129 * @param status The delivery status of the notification
adustm 4:cf7342047b4d 130 */
adustm 4:cf7342047b4d 131 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
screamer 29:6ff737b67e7d 132 printf("*** Button notification, status %s (%d) \n", MbedCloudClientResource::delivery_status_to_string(status), status);
adustm 4:cf7342047b4d 133 }
adustm 1:e86b1cffc402 134
adustm 4:cf7342047b4d 135 /**
adustm 4:cf7342047b4d 136 * Registration callback handler
adustm 4:cf7342047b4d 137 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
adustm 4:cf7342047b4d 138 */
adustm 4:cf7342047b4d 139 void registered(const ConnectorClientEndpointInfo *endpoint) {
screamer 17:fc98adcf835a 140 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
screamer 10:b27c962b3c3f 141 endpointInfo = endpoint;
adustm 4:cf7342047b4d 142 }
adustm 1:e86b1cffc402 143
screamer 10:b27c962b3c3f 144 /**
screamer 10:b27c962b3c3f 145 * Initialize sensors
screamer 10:b27c962b3c3f 146 */
screamer 10:b27c962b3c3f 147 void sensors_init() {
screamer 29:6ff737b67e7d 148 uint8_t id1, id2, id3, id4;
screamer 10:b27c962b3c3f 149
screamer 29:6ff737b67e7d 150 printf ("\nSensors configuration:\n");
screamer 10:b27c962b3c3f 151 // Initialize sensors
screamer 12:1f1a50e973db 152 sen_hum_temp.init(NULL);
screamer 12:1f1a50e973db 153 sen_press_temp.init(NULL);
screamer 12:1f1a50e973db 154 sen_acc_gyro.init(NULL);
screamer 12:1f1a50e973db 155 sen_mag.init(NULL);
screamer 28:0e774865873d 156 sen_distance.init_sensor(VL53L0X_DEFAULT_ADDRESS);
screamer 10:b27c962b3c3f 157
screamer 10:b27c962b3c3f 158 /// Call sensors enable routines
screamer 12:1f1a50e973db 159 sen_hum_temp.enable();
screamer 12:1f1a50e973db 160 sen_press_temp.enable();
screamer 12:1f1a50e973db 161 sen_acc_gyro.enable_x();
screamer 12:1f1a50e973db 162 sen_acc_gyro.enable_g();
screamer 10:b27c962b3c3f 163
screamer 29:6ff737b67e7d 164 sen_hum_temp.read_id(&id1);
screamer 29:6ff737b67e7d 165 sen_press_temp.read_id(&id2);
screamer 29:6ff737b67e7d 166 sen_mag.read_id(&id3);
screamer 29:6ff737b67e7d 167 sen_acc_gyro.read_id(&id4);
screamer 10:b27c962b3c3f 168
screamer 29:6ff737b67e7d 169 printf("HTS221 humidity & temperature = 0x%X\n", id1);
screamer 29:6ff737b67e7d 170 printf("LPS22HB pressure & temperature = 0x%X\n", id2);
screamer 29:6ff737b67e7d 171 printf("LIS3MDL magnetometer = 0x%X\n", id3);
screamer 29:6ff737b67e7d 172 printf("LSM6DSL accelerometer & gyroscope = 0x%X\n", id4);
screamer 10:b27c962b3c3f 173
screamer 17:fc98adcf835a 174 printf("\n"); ;
screamer 10:b27c962b3c3f 175 }
screamer 10:b27c962b3c3f 176
screamer 10:b27c962b3c3f 177 /**
screamer 10:b27c962b3c3f 178 * Update sensors and report their values.
screamer 10:b27c962b3c3f 179 * This function is called periodically.
screamer 10:b27c962b3c3f 180 */
screamer 10:b27c962b3c3f 181 void sensors_update() {
screamer 32:2871fbeb627d 182 float temp1_value, temp2_value, temp3_value, humid_value, pressure_value, volt_value = 0.0;
screamer 28:0e774865873d 183 int32_t m_axes[3], a_axes[3], g_axes[3];
screamer 32:2871fbeb627d 184 uint32_t distance_value, distance_reading;
screamer 10:b27c962b3c3f 185
screamer 32:2871fbeb627d 186 sen_hum_temp.get_humidity(&humid_value);
screamer 32:2871fbeb627d 187 sen_hum_temp.get_temperature(&temp1_value);
screamer 32:2871fbeb627d 188 sen_press_temp.get_pressure(&pressure_value);
screamer 32:2871fbeb627d 189 sen_press_temp.get_temperature(&temp2_value);
screamer 28:0e774865873d 190 sen_mag.get_m_axes(m_axes);
screamer 28:0e774865873d 191 sen_acc_gyro.get_x_axes(a_axes);
screamer 28:0e774865873d 192 sen_acc_gyro.get_g_axes(g_axes);
screamer 32:2871fbeb627d 193 distance_reading = sen_distance.get_distance(&distance_value);
screamer 32:2871fbeb627d 194 temp3_value = adc_temp.read()*100;
screamer 32:2871fbeb627d 195 volt_value = adc_vref.read();
screamer 32:2871fbeb627d 196
screamer 32:2871fbeb627d 197 float mag_x = (double)m_axes[0] / 1000.0, mag_y = (double)m_axes[1] / 1000.0, mag_z = (double)m_axes[2] / 1000.0;
screamer 32:2871fbeb627d 198 float acc_x = (double)a_axes[0] / 1000.0, acc_y = (double)a_axes[1] / 1000.0, acc_z = (double)a_axes[2] / 1000.0;
screamer 32:2871fbeb627d 199 float gyro_x = (double)g_axes[0] / 1000.0, gyro_y = (double)g_axes[1] / 1000.0, gyro_z = (double)g_axes[2] / 1000.0;
screamer 28:0e774865873d 200
screamer 32:2871fbeb627d 201 printf(" \n");
screamer 32:2871fbeb627d 202 printf("ADC temp: %5.4f C, vref: %5.4f V \n", temp3_value, volt_value);
screamer 32:2871fbeb627d 203 printf("HTS221 temp: %7.3f C, humidity: %7.2f %% \n", temp1_value, humid_value);
screamer 32:2871fbeb627d 204 printf("LPS22HB temp: %7.3f C, pressure: %7.2f mbar \n", temp2_value, pressure_value);
screamer 32:2871fbeb627d 205 printf("LIS3MDL mag: %7.3f x, %7.3f y, %7.3f z [gauss] \n", mag_x, mag_y, mag_z);
screamer 32:2871fbeb627d 206 printf("LSM6DSL acc: %7.3f x, %7.3f y, %7.3f z [g] \n", acc_x, acc_y, acc_z);
screamer 32:2871fbeb627d 207 printf("LSM6DSL gyro: %7.3f x, %7.3f y, %7.3f z [dps] \n", gyro_x, gyro_y, gyro_z);
screamer 32:2871fbeb627d 208 if (distance_reading == VL53L0X_ERROR_NONE) {
screamer 32:2871fbeb627d 209 printf("VL53L0X dist: %7ld mm\n", distance_value);
screamer 28:0e774865873d 210 } else {
screamer 28:0e774865873d 211 printf("VL53L0X dist: -- \n");
screamer 32:2871fbeb627d 212 distance_value = 999;
screamer 10:b27c962b3c3f 213 }
screamer 10:b27c962b3c3f 214
screamer 28:0e774865873d 215 printf("\r\033[8A");
screamer 28:0e774865873d 216
screamer 13:42b49a0caade 217 if (endpointInfo) {
screamer 32:2871fbeb627d 218 res_humidity->set_value(humid_value);
screamer 32:2871fbeb627d 219 res_temperature->set_value(temp1_value);
screamer 13:42b49a0caade 220 #ifdef SEND_ALL_SENSORS
screamer 32:2871fbeb627d 221 res_pressure->set_value(pressure_value);
screamer 32:2871fbeb627d 222 res_temperature2->set_value(temp2_value);
screamer 32:2871fbeb627d 223 res_magnometer_x->set_value(mag_x);
screamer 32:2871fbeb627d 224 res_magnometer_y->set_value(mag_y);
screamer 32:2871fbeb627d 225 res_magnometer_z->set_value(mag_z);
screamer 32:2871fbeb627d 226 res_accelerometer_x->set_value(acc_x);
screamer 32:2871fbeb627d 227 res_accelerometer_y->set_value(acc_y);
screamer 32:2871fbeb627d 228 res_accelerometer_z->set_value(acc_z);
screamer 32:2871fbeb627d 229 res_gyroscope_x->set_value(gyro_x);
screamer 32:2871fbeb627d 230 res_gyroscope_y->set_value(gyro_y);
screamer 32:2871fbeb627d 231 res_gyroscope_z->set_value(gyro_z);
screamer 32:2871fbeb627d 232 res_distance->set_value((int)distance_value);
screamer 32:2871fbeb627d 233 res_adc_temp->set_value(temp3_value);
screamer 32:2871fbeb627d 234 res_adc_voltage->set_value(volt_value);
screamer 13:42b49a0caade 235 #endif /* SEND_ALL_SENSORS */
screamer 28:0e774865873d 236 }
screamer 10:b27c962b3c3f 237 }
screamer 10:b27c962b3c3f 238
adustm 4:cf7342047b4d 239 int main(void) {
screamer 17:fc98adcf835a 240 printf("\nStarting Simple Pelion Device Management Client example\n");
adustm 4:cf7342047b4d 241
screamer 29:6ff737b67e7d 242 int storage_status = fs.mount(&sd);
screamer 29:6ff737b67e7d 243 if (storage_status != 0) {
screamer 29:6ff737b67e7d 244 printf("Storage mounting failed.\n");
screamer 29:6ff737b67e7d 245 }
screamer 30:15743b79c6cb 246 #if USE_BUTTON == 1
screamer 30:15743b79c6cb 247 // If the User button is pressed ons start, then format storage.
screamer 29:6ff737b67e7d 248 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE);
screamer 29:6ff737b67e7d 249 if (btn_pressed) {
screamer 29:6ff737b67e7d 250 printf("User button is pushed on start...\n");
screamer 29:6ff737b67e7d 251 }
screamer 30:15743b79c6cb 252 #else
screamer 30:15743b79c6cb 253 bool btn_pressed = FALSE;
screamer 30:15743b79c6cb 254 #endif /* USE_BUTTON */
screamer 30:15743b79c6cb 255
screamer 29:6ff737b67e7d 256 if (storage_status || btn_pressed) {
screamer 29:6ff737b67e7d 257 printf("Formatting the storage...\n");
screamer 30:15743b79c6cb 258 int storage_status = StorageHelper::format(&fs, &sd);
screamer 10:b27c962b3c3f 259 if (storage_status != 0) {
screamer 13:42b49a0caade 260 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status);
screamer 10:b27c962b3c3f 261 }
screamer 28:0e774865873d 262 } else {
screamer 28:0e774865873d 263 printf("You can hold the user button during boot to format the storage and change the device identity.\n");
screamer 10:b27c962b3c3f 264 }
screamer 10:b27c962b3c3f 265
screamer 10:b27c962b3c3f 266 sensors_init();
screamer 10:b27c962b3c3f 267
adustm 4:cf7342047b4d 268 // Connect to the internet (DHCP is expected to be on)
screamer 13:42b49a0caade 269 printf("Connecting to the network using Wifi...\n");
MarceloSalazar 9:265744785d33 270 net = NetworkInterface::get_default_instance();
adustm 4:cf7342047b4d 271
screamer 10:b27c962b3c3f 272 nsapi_error_t net_status = -1;
screamer 10:b27c962b3c3f 273 for (int tries = 0; tries < 3; tries++) {
screamer 10:b27c962b3c3f 274 net_status = net->connect();
screamer 10:b27c962b3c3f 275 if (net_status == NSAPI_ERROR_OK) {
screamer 10:b27c962b3c3f 276 break;
screamer 10:b27c962b3c3f 277 } else {
screamer 13:42b49a0caade 278 printf("Unable to connect to network. Retrying...\n");
screamer 10:b27c962b3c3f 279 }
screamer 10:b27c962b3c3f 280 }
MarceloSalazar 9:265744785d33 281
screamer 10:b27c962b3c3f 282 if (net_status != NSAPI_ERROR_OK) {
screamer 13:42b49a0caade 283 printf("ERROR: Connecting to the network failed (%d)!\n", net_status);
adustm 1:e86b1cffc402 284 return -1;
adustm 1:e86b1cffc402 285 }
adustm 1:e86b1cffc402 286
MarceloSalazar 9:265744785d33 287 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
adustm 1:e86b1cffc402 288
screamer 17:fc98adcf835a 289 printf("Initializing Pelion Device Management Client...\n");
screamer 17:fc98adcf835a 290
MarceloSalazar 9:265744785d33 291 // SimpleMbedCloudClient handles registering over LwM2M to Pelion DM
MarceloSalazar 9:265744785d33 292 SimpleMbedCloudClient client(net, bd, &fs);
adustm 4:cf7342047b4d 293 int client_status = client.init();
adustm 4:cf7342047b4d 294 if (client_status != 0) {
screamer 13:42b49a0caade 295 printf("ERROR: Pelion Client initialization failed (%d)\n", client_status);
adustm 1:e86b1cffc402 296 return -1;
adustm 1:e86b1cffc402 297 }
adustm 1:e86b1cffc402 298
adustm 4:cf7342047b4d 299 // Creating resources, which can be written or read from the cloud
screamer 32:2871fbeb627d 300 res_button = client.create_resource("3200/0/5501", "Button Count");
screamer 12:1f1a50e973db 301 res_button->set_value(0);
screamer 12:1f1a50e973db 302 res_button->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 303 res_button->observable(true);
screamer 12:1f1a50e973db 304 res_button->attach_notification_callback(button_callback);
adustm 1:e86b1cffc402 305
screamer 10:b27c962b3c3f 306 // Sensor resources
screamer 32:2871fbeb627d 307 res_temperature = client.create_resource("3303/0/5700", "Temperature HTS221 (C)");
screamer 12:1f1a50e973db 308 res_temperature->set_value(0);
screamer 12:1f1a50e973db 309 res_temperature->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 310 res_temperature->observable(true);
screamer 10:b27c962b3c3f 311
screamer 32:2871fbeb627d 312 res_humidity = client.create_resource("3304/0/5700", "Humidity");
screamer 12:1f1a50e973db 313 res_humidity->set_value(0);
screamer 12:1f1a50e973db 314 res_humidity->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 315 res_humidity->observable(true);
screamer 10:b27c962b3c3f 316
screamer 13:42b49a0caade 317 #ifdef SEND_ALL_SENSORS
screamer 32:2871fbeb627d 318 res_temperature2 = client.create_resource("3303/1/5700", "Temperature LPS22HB (C)");
screamer 13:42b49a0caade 319 res_temperature2->set_value(0);
screamer 13:42b49a0caade 320 res_temperature2->methods(M2MMethod::GET);
screamer 13:42b49a0caade 321 res_temperature2->observable(true);
screamer 13:42b49a0caade 322
screamer 32:2871fbeb627d 323 res_adc_temp = client.create_resource("3303/2/5700", "Temperature ADC (C)");
screamer 28:0e774865873d 324 res_adc_temp->set_value(0);
screamer 28:0e774865873d 325 res_adc_temp->methods(M2MMethod::GET);
screamer 28:0e774865873d 326 res_adc_temp->observable(true);
screamer 28:0e774865873d 327
screamer 32:2871fbeb627d 328 res_accelerometer_x = client.create_resource("3313/0/5702", "Accelerometer X");
screamer 28:0e774865873d 329 res_accelerometer_x->set_value(0);
screamer 28:0e774865873d 330 res_accelerometer_x->methods(M2MMethod::GET);
screamer 28:0e774865873d 331 res_accelerometer_x->observable(true);
screamer 28:0e774865873d 332
screamer 32:2871fbeb627d 333 res_accelerometer_y = client.create_resource("3313/0/5703", "Accelerometer Y");
screamer 28:0e774865873d 334 res_accelerometer_y->set_value(0);
screamer 28:0e774865873d 335 res_accelerometer_y->methods(M2MMethod::GET);
screamer 28:0e774865873d 336 res_accelerometer_y->observable(true);
screamer 28:0e774865873d 337
screamer 32:2871fbeb627d 338 res_accelerometer_z = client.create_resource("3313/0/5704", "Accelerometer Z");
screamer 28:0e774865873d 339 res_accelerometer_z->set_value(0);
screamer 28:0e774865873d 340 res_accelerometer_z->methods(M2MMethod::GET);
screamer 28:0e774865873d 341 res_accelerometer_z->observable(true);
screamer 28:0e774865873d 342
screamer 32:2871fbeb627d 343 res_magnometer_x = client.create_resource("3314/0/5702", "Magnometer X");
screamer 28:0e774865873d 344 res_magnometer_x->set_value(0);
screamer 28:0e774865873d 345 res_magnometer_x->methods(M2MMethod::GET);
screamer 28:0e774865873d 346 res_magnometer_x->observable(true);
screamer 28:0e774865873d 347
screamer 32:2871fbeb627d 348 res_magnometer_y = client.create_resource("3314/0/5703", "Magnometer Y");
screamer 28:0e774865873d 349 res_magnometer_y->set_value(0);
screamer 28:0e774865873d 350 res_magnometer_y->methods(M2MMethod::GET);
screamer 28:0e774865873d 351 res_magnometer_y->observable(true);
screamer 28:0e774865873d 352
screamer 32:2871fbeb627d 353 res_magnometer_z = client.create_resource("3314/0/5704", "Magnometer Z");
screamer 28:0e774865873d 354 res_magnometer_z->set_value(0);
screamer 28:0e774865873d 355 res_magnometer_z->methods(M2MMethod::GET);
screamer 28:0e774865873d 356 res_magnometer_z->observable(true);
screamer 28:0e774865873d 357
screamer 32:2871fbeb627d 358 res_gyroscope_x = client.create_resource("3334/0/5702", "Gyroscope X");
screamer 13:42b49a0caade 359 res_gyroscope_x->set_value(0);
screamer 13:42b49a0caade 360 res_gyroscope_x->methods(M2MMethod::GET);
screamer 13:42b49a0caade 361 res_gyroscope_x->observable(true);
screamer 10:b27c962b3c3f 362
screamer 32:2871fbeb627d 363 res_gyroscope_y = client.create_resource("3334/0/5703", "Gyroscope Y");
screamer 13:42b49a0caade 364 res_gyroscope_y->set_value(0);
screamer 13:42b49a0caade 365 res_gyroscope_y->methods(M2MMethod::GET);
screamer 13:42b49a0caade 366 res_gyroscope_y->observable(true);
screamer 13:42b49a0caade 367
screamer 32:2871fbeb627d 368 res_gyroscope_z = client.create_resource("3334/0/5704", "Gyroscope Z");
screamer 13:42b49a0caade 369 res_gyroscope_z->set_value(0);
screamer 13:42b49a0caade 370 res_gyroscope_z->methods(M2MMethod::GET);
screamer 13:42b49a0caade 371 res_gyroscope_z->observable(true);
screamer 13:42b49a0caade 372
screamer 32:2871fbeb627d 373 res_adc_voltage = client.create_resource("3316/0/5700", "Voltage");
screamer 28:0e774865873d 374 res_adc_voltage->set_value(0);
screamer 28:0e774865873d 375 res_adc_voltage->methods(M2MMethod::GET);
screamer 28:0e774865873d 376 res_adc_voltage->observable(true);
screamer 28:0e774865873d 377
screamer 32:2871fbeb627d 378 res_pressure = client.create_resource("3323/0/5700", "Pressure");
screamer 28:0e774865873d 379 res_pressure->set_value(0);
screamer 28:0e774865873d 380 res_pressure->methods(M2MMethod::GET);
screamer 28:0e774865873d 381 res_pressure->observable(true);
screamer 28:0e774865873d 382
screamer 32:2871fbeb627d 383 res_distance = client.create_resource("3330/0/5700", "Distance");
screamer 28:0e774865873d 384 res_distance->set_value((float)999.9);
screamer 13:42b49a0caade 385 res_distance->methods(M2MMethod::GET);
screamer 13:42b49a0caade 386 res_distance->observable(true);
screamer 13:42b49a0caade 387
screamer 32:2871fbeb627d 388 res_led = client.create_resource("3201/0/5853", "LED State");
screamer 13:42b49a0caade 389 res_led->set_value(1);
screamer 13:42b49a0caade 390 res_led->methods(M2MMethod::GET | M2MMethod::PUT);
screamer 32:2871fbeb627d 391 res_led->attach_put_callback(put_callback);
screamer 13:42b49a0caade 392 #endif /* SEND_ALL_SENSORS */
screamer 11:8df4529f060d 393
MarceloSalazar 9:265744785d33 394 printf("Initialized Pelion Client. Registering...\n");
adustm 1:e86b1cffc402 395
adustm 4:cf7342047b4d 396 // Callback that fires when registering is complete
adustm 4:cf7342047b4d 397 client.on_registered(&registered);
adustm 1:e86b1cffc402 398
MarceloSalazar 9:265744785d33 399 // Register with Pelion DM
adustm 4:cf7342047b4d 400 client.register_and_connect();
adustm 1:e86b1cffc402 401
screamer 17:fc98adcf835a 402 int i = 600; // wait up 60 seconds before attaching sensors and button events
screamer 12:1f1a50e973db 403 while (i-- > 0 && !client.is_client_registered()) {
screamer 12:1f1a50e973db 404 wait_ms(100);
screamer 12:1f1a50e973db 405 }
screamer 12:1f1a50e973db 406
screamer 11:8df4529f060d 407 button.fall(eventQueue.event(&button_press));
screamer 10:b27c962b3c3f 408
screamer 15:a0430d40a918 409 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
adustm 4:cf7342047b4d 410 Ticker timer;
screamer 11:8df4529f060d 411 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL);
adustm 1:e86b1cffc402 412
adustm 4:cf7342047b4d 413 // You can easily run the eventQueue in a separate thread if required
adustm 4:cf7342047b4d 414 eventQueue.dispatch_forever();
adustm 1:e86b1cffc402 415 }
screamer 28:0e774865873d 416
MarceloSalazar 9:265744785d33 417 #endif