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:
Sat Mar 09 00:46:54 2019 +0000
Revision:
30:15743b79c6cb
Parent:
29:6ff737b67e7d
Child:
32:2871fbeb627d
Update to Mbed OS 5.11.5 and latest ISM43362 driver

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 11:8df4529f060d 38 #define SENSORS_POLL_INTERVAL 1.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 11:8df4529f060d 97 void led_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 11:8df4529f060d 109 void led_post_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
screamer 29:6ff737b67e7d 110 printf("*** POST received. Payload: %s \n", res_led->get_value().c_str());
screamer 12:1f1a50e973db 111 led = atoi(res_led->get_value().c_str());
screamer 11:8df4529f060d 112 }
adustm 1:e86b1cffc402 113
screamer 11:8df4529f060d 114 /**
screamer 13:42b49a0caade 115 * Button function triggered by the physical button press.
screamer 11:8df4529f060d 116 */
screamer 11:8df4529f060d 117 void button_press() {
screamer 12:1f1a50e973db 118 int v = res_button->get_value_int() + 1;
screamer 12:1f1a50e973db 119 res_button->set_value(v);
screamer 29:6ff737b67e7d 120 printf("*** Button clicked %d times \n", v);
adustm 1:e86b1cffc402 121 }
adustm 1:e86b1cffc402 122
adustm 4:cf7342047b4d 123 /**
adustm 4:cf7342047b4d 124 * Notification callback handler
adustm 4:cf7342047b4d 125 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 126 * @param status The delivery status of the notification
adustm 4:cf7342047b4d 127 */
adustm 4:cf7342047b4d 128 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
screamer 29:6ff737b67e7d 129 printf("*** Button notification, status %s (%d) \n", MbedCloudClientResource::delivery_status_to_string(status), status);
adustm 4:cf7342047b4d 130 }
adustm 1:e86b1cffc402 131
adustm 4:cf7342047b4d 132 /**
adustm 4:cf7342047b4d 133 * Registration callback handler
adustm 4:cf7342047b4d 134 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
adustm 4:cf7342047b4d 135 */
adustm 4:cf7342047b4d 136 void registered(const ConnectorClientEndpointInfo *endpoint) {
screamer 17:fc98adcf835a 137 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
screamer 10:b27c962b3c3f 138 endpointInfo = endpoint;
adustm 4:cf7342047b4d 139 }
adustm 1:e86b1cffc402 140
screamer 10:b27c962b3c3f 141 /**
screamer 10:b27c962b3c3f 142 * Initialize sensors
screamer 10:b27c962b3c3f 143 */
screamer 10:b27c962b3c3f 144 void sensors_init() {
screamer 29:6ff737b67e7d 145 uint8_t id1, id2, id3, id4;
screamer 10:b27c962b3c3f 146
screamer 29:6ff737b67e7d 147 printf ("\nSensors configuration:\n");
screamer 10:b27c962b3c3f 148 // Initialize sensors
screamer 12:1f1a50e973db 149 sen_hum_temp.init(NULL);
screamer 12:1f1a50e973db 150 sen_press_temp.init(NULL);
screamer 12:1f1a50e973db 151 sen_acc_gyro.init(NULL);
screamer 12:1f1a50e973db 152 sen_mag.init(NULL);
screamer 28:0e774865873d 153 sen_distance.init_sensor(VL53L0X_DEFAULT_ADDRESS);
screamer 10:b27c962b3c3f 154
screamer 10:b27c962b3c3f 155 /// Call sensors enable routines
screamer 12:1f1a50e973db 156 sen_hum_temp.enable();
screamer 12:1f1a50e973db 157 sen_press_temp.enable();
screamer 12:1f1a50e973db 158 sen_acc_gyro.enable_x();
screamer 12:1f1a50e973db 159 sen_acc_gyro.enable_g();
screamer 10:b27c962b3c3f 160
screamer 29:6ff737b67e7d 161 sen_hum_temp.read_id(&id1);
screamer 29:6ff737b67e7d 162 sen_press_temp.read_id(&id2);
screamer 29:6ff737b67e7d 163 sen_mag.read_id(&id3);
screamer 29:6ff737b67e7d 164 sen_acc_gyro.read_id(&id4);
screamer 10:b27c962b3c3f 165
screamer 29:6ff737b67e7d 166 printf("HTS221 humidity & temperature = 0x%X\n", id1);
screamer 29:6ff737b67e7d 167 printf("LPS22HB pressure & temperature = 0x%X\n", id2);
screamer 29:6ff737b67e7d 168 printf("LIS3MDL magnetometer = 0x%X\n", id3);
screamer 29:6ff737b67e7d 169 printf("LSM6DSL accelerometer & gyroscope = 0x%X\n", id4);
screamer 10:b27c962b3c3f 170
screamer 17:fc98adcf835a 171 printf("\n"); ;
screamer 10:b27c962b3c3f 172 }
screamer 10:b27c962b3c3f 173
screamer 10:b27c962b3c3f 174 /**
screamer 10:b27c962b3c3f 175 * Update sensors and report their values.
screamer 10:b27c962b3c3f 176 * This function is called periodically.
screamer 10:b27c962b3c3f 177 */
screamer 10:b27c962b3c3f 178 void sensors_update() {
screamer 28:0e774865873d 179 float t1_val, t2_val, t3_val, h_val, p_val, v_val = 0.0;
screamer 28:0e774865873d 180 int32_t m_axes[3], a_axes[3], g_axes[3];
screamer 28:0e774865873d 181 uint32_t d_val, vl_res;
screamer 10:b27c962b3c3f 182
screamer 28:0e774865873d 183 printf(" \n");
screamer 10:b27c962b3c3f 184
screamer 28:0e774865873d 185 sen_hum_temp.get_humidity(&h_val);
screamer 28:0e774865873d 186 sen_hum_temp.get_temperature(&t1_val);
screamer 28:0e774865873d 187 sen_press_temp.get_pressure(&p_val);
screamer 28:0e774865873d 188 sen_press_temp.get_temperature(&t2_val);
screamer 28:0e774865873d 189 sen_mag.get_m_axes(m_axes);
screamer 28:0e774865873d 190 sen_acc_gyro.get_x_axes(a_axes);
screamer 28:0e774865873d 191 sen_acc_gyro.get_g_axes(g_axes);
screamer 28:0e774865873d 192 vl_res = sen_distance.get_distance(&d_val);
screamer 28:0e774865873d 193 t3_val = adc_temp.read()*100;
screamer 28:0e774865873d 194 v_val = adc_vref.read();
screamer 28:0e774865873d 195
screamer 28:0e774865873d 196 printf("ADC temp: %5.4f C, vref: %5.4f V \n", t3_val, v_val);
screamer 28:0e774865873d 197 printf("HTS221 temp: %7.2f C, humidity: %7.2f %% \n", t1_val, h_val);
screamer 28:0e774865873d 198 printf("LPS22HB temp: %7.2f C, pressure: %7.2f mbar \n", t2_val, p_val);
screamer 28:0e774865873d 199 printf("LIS3MDL mag: %7ld x, %7ld y, %7ld z [mgauss] \n", m_axes[0], m_axes[1], m_axes[2]);
screamer 28:0e774865873d 200 printf("LSM6DSL acc: %7ld x, %7ld y, %7ld z [mg] \n", a_axes[0], a_axes[1], a_axes[2]);
screamer 28:0e774865873d 201 printf("LSM6DSL gyro: %7ld x, %7ld y, %7ld z [mdps] \n", g_axes[0], g_axes[1], g_axes[2]);
screamer 28:0e774865873d 202 if (vl_res == VL53L0X_ERROR_NONE) {
screamer 28:0e774865873d 203 printf("VL53L0X dist: %7ld [mm]\n", d_val);
screamer 28:0e774865873d 204 } else {
screamer 28:0e774865873d 205 printf("VL53L0X dist: -- \n");
screamer 10:b27c962b3c3f 206 }
screamer 10:b27c962b3c3f 207
screamer 28:0e774865873d 208 printf("\r\033[8A");
screamer 28:0e774865873d 209
screamer 13:42b49a0caade 210 if (endpointInfo) {
screamer 28:0e774865873d 211 res_humidity->set_value(h_val);
screamer 28:0e774865873d 212 res_temperature->set_value(t1_val);
screamer 13:42b49a0caade 213 #ifdef SEND_ALL_SENSORS
screamer 28:0e774865873d 214 res_pressure->set_value(p_val);
screamer 28:0e774865873d 215 res_temperature2->set_value(t2_val);
screamer 28:0e774865873d 216 res_magnometer_x->set_value((float)m_axes[0]);
screamer 28:0e774865873d 217 res_magnometer_y->set_value((float)m_axes[1]);
screamer 28:0e774865873d 218 res_magnometer_z->set_value((float)m_axes[2]);
screamer 28:0e774865873d 219 res_accelerometer_x->set_value((float)a_axes[0]);
screamer 28:0e774865873d 220 res_accelerometer_y->set_value((float)a_axes[1]);
screamer 28:0e774865873d 221 res_accelerometer_z->set_value((float)a_axes[2]);
screamer 28:0e774865873d 222 res_gyroscope_x->set_value((float)g_axes[0]);
screamer 28:0e774865873d 223 res_gyroscope_y->set_value((float)g_axes[1]);
screamer 28:0e774865873d 224 res_gyroscope_z->set_value((float)g_axes[2]);
screamer 28:0e774865873d 225 res_distance->set_value((float)d_val);
screamer 28:0e774865873d 226 res_adc_temp->set_value(t3_val);
screamer 28:0e774865873d 227 res_adc_voltage->set_value(v_val);
screamer 13:42b49a0caade 228 #endif /* SEND_ALL_SENSORS */
screamer 28:0e774865873d 229 }
screamer 10:b27c962b3c3f 230 }
screamer 10:b27c962b3c3f 231
adustm 4:cf7342047b4d 232 int main(void) {
screamer 17:fc98adcf835a 233 printf("\nStarting Simple Pelion Device Management Client example\n");
adustm 4:cf7342047b4d 234
screamer 29:6ff737b67e7d 235 int storage_status = fs.mount(&sd);
screamer 29:6ff737b67e7d 236 if (storage_status != 0) {
screamer 29:6ff737b67e7d 237 printf("Storage mounting failed.\n");
screamer 29:6ff737b67e7d 238 }
screamer 30:15743b79c6cb 239 #if USE_BUTTON == 1
screamer 30:15743b79c6cb 240 // If the User button is pressed ons start, then format storage.
screamer 29:6ff737b67e7d 241 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE);
screamer 29:6ff737b67e7d 242 if (btn_pressed) {
screamer 29:6ff737b67e7d 243 printf("User button is pushed on start...\n");
screamer 29:6ff737b67e7d 244 }
screamer 30:15743b79c6cb 245 #else
screamer 30:15743b79c6cb 246 bool btn_pressed = FALSE;
screamer 30:15743b79c6cb 247 #endif /* USE_BUTTON */
screamer 30:15743b79c6cb 248
screamer 29:6ff737b67e7d 249 if (storage_status || btn_pressed) {
screamer 29:6ff737b67e7d 250 printf("Formatting the storage...\n");
screamer 30:15743b79c6cb 251 int storage_status = StorageHelper::format(&fs, &sd);
screamer 10:b27c962b3c3f 252 if (storage_status != 0) {
screamer 13:42b49a0caade 253 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status);
screamer 10:b27c962b3c3f 254 }
screamer 28:0e774865873d 255 } else {
screamer 28:0e774865873d 256 printf("You can hold the user button during boot to format the storage and change the device identity.\n");
screamer 10:b27c962b3c3f 257 }
screamer 10:b27c962b3c3f 258
screamer 10:b27c962b3c3f 259 sensors_init();
screamer 10:b27c962b3c3f 260
adustm 4:cf7342047b4d 261 // Connect to the internet (DHCP is expected to be on)
screamer 13:42b49a0caade 262 printf("Connecting to the network using Wifi...\n");
MarceloSalazar 9:265744785d33 263 net = NetworkInterface::get_default_instance();
adustm 4:cf7342047b4d 264
screamer 10:b27c962b3c3f 265 nsapi_error_t net_status = -1;
screamer 10:b27c962b3c3f 266 for (int tries = 0; tries < 3; tries++) {
screamer 10:b27c962b3c3f 267 net_status = net->connect();
screamer 10:b27c962b3c3f 268 if (net_status == NSAPI_ERROR_OK) {
screamer 10:b27c962b3c3f 269 break;
screamer 10:b27c962b3c3f 270 } else {
screamer 13:42b49a0caade 271 printf("Unable to connect to network. Retrying...\n");
screamer 10:b27c962b3c3f 272 }
screamer 10:b27c962b3c3f 273 }
MarceloSalazar 9:265744785d33 274
screamer 10:b27c962b3c3f 275 if (net_status != NSAPI_ERROR_OK) {
screamer 13:42b49a0caade 276 printf("ERROR: Connecting to the network failed (%d)!\n", net_status);
adustm 1:e86b1cffc402 277 return -1;
adustm 1:e86b1cffc402 278 }
adustm 1:e86b1cffc402 279
MarceloSalazar 9:265744785d33 280 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
adustm 1:e86b1cffc402 281
screamer 17:fc98adcf835a 282 printf("Initializing Pelion Device Management Client...\n");
screamer 17:fc98adcf835a 283
MarceloSalazar 9:265744785d33 284 // SimpleMbedCloudClient handles registering over LwM2M to Pelion DM
MarceloSalazar 9:265744785d33 285 SimpleMbedCloudClient client(net, bd, &fs);
adustm 4:cf7342047b4d 286 int client_status = client.init();
adustm 4:cf7342047b4d 287 if (client_status != 0) {
screamer 13:42b49a0caade 288 printf("ERROR: Pelion Client initialization failed (%d)\n", client_status);
adustm 1:e86b1cffc402 289 return -1;
adustm 1:e86b1cffc402 290 }
adustm 1:e86b1cffc402 291
adustm 4:cf7342047b4d 292 // Creating resources, which can be written or read from the cloud
screamer 12:1f1a50e973db 293 res_button = client.create_resource("3200/0/5501", "button_count");
screamer 12:1f1a50e973db 294 res_button->set_value(0);
screamer 12:1f1a50e973db 295 res_button->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 296 res_button->observable(true);
screamer 12:1f1a50e973db 297 res_button->attach_notification_callback(button_callback);
adustm 1:e86b1cffc402 298
screamer 10:b27c962b3c3f 299 // Sensor resources
screamer 12:1f1a50e973db 300 res_temperature = client.create_resource("3303/0/5700", "temperature");
screamer 12:1f1a50e973db 301 res_temperature->set_value(0);
screamer 12:1f1a50e973db 302 res_temperature->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 303 res_temperature->observable(true);
screamer 10:b27c962b3c3f 304
screamer 12:1f1a50e973db 305 res_humidity = client.create_resource("3304/0/5700", "humidity");
screamer 12:1f1a50e973db 306 res_humidity->set_value(0);
screamer 12:1f1a50e973db 307 res_humidity->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 308 res_humidity->observable(true);
screamer 10:b27c962b3c3f 309
screamer 13:42b49a0caade 310 #ifdef SEND_ALL_SENSORS
screamer 13:42b49a0caade 311 res_temperature2 = client.create_resource("3303/1/5700", "temperature");
screamer 13:42b49a0caade 312 res_temperature2->set_value(0);
screamer 13:42b49a0caade 313 res_temperature2->methods(M2MMethod::GET);
screamer 13:42b49a0caade 314 res_temperature2->observable(true);
screamer 13:42b49a0caade 315
screamer 28:0e774865873d 316 res_adc_temp = client.create_resource("3303/2/5700", "temperature");
screamer 28:0e774865873d 317 res_adc_temp->set_value(0);
screamer 28:0e774865873d 318 res_adc_temp->methods(M2MMethod::GET);
screamer 28:0e774865873d 319 res_adc_temp->observable(true);
screamer 28:0e774865873d 320
screamer 28:0e774865873d 321 res_accelerometer_x = client.create_resource("3313/0/5702", "accelerometer_x");
screamer 28:0e774865873d 322 res_accelerometer_x->set_value(0);
screamer 28:0e774865873d 323 res_accelerometer_x->methods(M2MMethod::GET);
screamer 28:0e774865873d 324 res_accelerometer_x->observable(true);
screamer 28:0e774865873d 325
screamer 28:0e774865873d 326 res_accelerometer_y = client.create_resource("3313/0/5703", "accelerometer_y");
screamer 28:0e774865873d 327 res_accelerometer_y->set_value(0);
screamer 28:0e774865873d 328 res_accelerometer_y->methods(M2MMethod::GET);
screamer 28:0e774865873d 329 res_accelerometer_y->observable(true);
screamer 28:0e774865873d 330
screamer 28:0e774865873d 331 res_accelerometer_z = client.create_resource("3313/0/5704", "accelerometer_z");
screamer 28:0e774865873d 332 res_accelerometer_z->set_value(0);
screamer 28:0e774865873d 333 res_accelerometer_z->methods(M2MMethod::GET);
screamer 28:0e774865873d 334 res_accelerometer_z->observable(true);
screamer 28:0e774865873d 335
screamer 28:0e774865873d 336 res_magnometer_x = client.create_resource("3314/0/5702", "magnometer_x");
screamer 28:0e774865873d 337 res_magnometer_x->set_value(0);
screamer 28:0e774865873d 338 res_magnometer_x->methods(M2MMethod::GET);
screamer 28:0e774865873d 339 res_magnometer_x->observable(true);
screamer 28:0e774865873d 340
screamer 28:0e774865873d 341 res_magnometer_y = client.create_resource("3314/0/5703", "magnometer_y");
screamer 28:0e774865873d 342 res_magnometer_y->set_value(0);
screamer 28:0e774865873d 343 res_magnometer_y->methods(M2MMethod::GET);
screamer 28:0e774865873d 344 res_magnometer_y->observable(true);
screamer 28:0e774865873d 345
screamer 28:0e774865873d 346 res_magnometer_z = client.create_resource("3314/0/5704", "magnometer_z");
screamer 28:0e774865873d 347 res_magnometer_z->set_value(0);
screamer 28:0e774865873d 348 res_magnometer_z->methods(M2MMethod::GET);
screamer 28:0e774865873d 349 res_magnometer_z->observable(true);
screamer 28:0e774865873d 350
screamer 28:0e774865873d 351 res_gyroscope_x = client.create_resource("3334/0/5702", "gyroscope_x");
screamer 13:42b49a0caade 352 res_gyroscope_x->set_value(0);
screamer 13:42b49a0caade 353 res_gyroscope_x->methods(M2MMethod::GET);
screamer 13:42b49a0caade 354 res_gyroscope_x->observable(true);
screamer 10:b27c962b3c3f 355
screamer 28:0e774865873d 356 res_gyroscope_y = client.create_resource("3334/0/5703", "gyroscope_y");
screamer 13:42b49a0caade 357 res_gyroscope_y->set_value(0);
screamer 13:42b49a0caade 358 res_gyroscope_y->methods(M2MMethod::GET);
screamer 13:42b49a0caade 359 res_gyroscope_y->observable(true);
screamer 13:42b49a0caade 360
screamer 28:0e774865873d 361 res_gyroscope_z = client.create_resource("3334/0/5704", "gyroscope_z");
screamer 13:42b49a0caade 362 res_gyroscope_z->set_value(0);
screamer 13:42b49a0caade 363 res_gyroscope_z->methods(M2MMethod::GET);
screamer 13:42b49a0caade 364 res_gyroscope_z->observable(true);
screamer 13:42b49a0caade 365
screamer 28:0e774865873d 366 res_adc_voltage = client.create_resource("3316/0/5700", "voltage");
screamer 28:0e774865873d 367 res_adc_voltage->set_value(0);
screamer 28:0e774865873d 368 res_adc_voltage->methods(M2MMethod::GET);
screamer 28:0e774865873d 369 res_adc_voltage->observable(true);
screamer 28:0e774865873d 370
screamer 28:0e774865873d 371 res_pressure = client.create_resource("3323/0/5700", "pressure");
screamer 28:0e774865873d 372 res_pressure->set_value(0);
screamer 28:0e774865873d 373 res_pressure->methods(M2MMethod::GET);
screamer 28:0e774865873d 374 res_pressure->observable(true);
screamer 28:0e774865873d 375
screamer 13:42b49a0caade 376 res_distance = client.create_resource("3330/0/5700", "distance");
screamer 28:0e774865873d 377 res_distance->set_value((float)999.9);
screamer 13:42b49a0caade 378 res_distance->methods(M2MMethod::GET);
screamer 13:42b49a0caade 379 res_distance->observable(true);
screamer 13:42b49a0caade 380
screamer 13:42b49a0caade 381 res_led = client.create_resource("3201/0/5853", "led_state");
screamer 13:42b49a0caade 382 res_led->set_value(1);
screamer 13:42b49a0caade 383 res_led->methods(M2MMethod::GET | M2MMethod::PUT);
screamer 13:42b49a0caade 384 res_led->attach_put_callback(led_put_callback);
screamer 13:42b49a0caade 385 #endif /* SEND_ALL_SENSORS */
screamer 11:8df4529f060d 386
MarceloSalazar 9:265744785d33 387 printf("Initialized Pelion Client. Registering...\n");
adustm 1:e86b1cffc402 388
adustm 4:cf7342047b4d 389 // Callback that fires when registering is complete
adustm 4:cf7342047b4d 390 client.on_registered(&registered);
adustm 1:e86b1cffc402 391
MarceloSalazar 9:265744785d33 392 // Register with Pelion DM
adustm 4:cf7342047b4d 393 client.register_and_connect();
adustm 1:e86b1cffc402 394
screamer 17:fc98adcf835a 395 int i = 600; // wait up 60 seconds before attaching sensors and button events
screamer 12:1f1a50e973db 396 while (i-- > 0 && !client.is_client_registered()) {
screamer 12:1f1a50e973db 397 wait_ms(100);
screamer 12:1f1a50e973db 398 }
screamer 12:1f1a50e973db 399
screamer 11:8df4529f060d 400 button.fall(eventQueue.event(&button_press));
screamer 10:b27c962b3c3f 401
screamer 15:a0430d40a918 402 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
adustm 4:cf7342047b4d 403 Ticker timer;
screamer 11:8df4529f060d 404 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL);
adustm 1:e86b1cffc402 405
adustm 4:cf7342047b4d 406 // You can easily run the eventQueue in a separate thread if required
adustm 4:cf7342047b4d 407 eventQueue.dispatch_forever();
adustm 1:e86b1cffc402 408 }
screamer 28:0e774865873d 409
MarceloSalazar 9:265744785d33 410 #endif