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:
Thu Mar 07 15:39:45 2019 +0000
Revision:
29:6ff737b67e7d
Parent:
28:0e774865873d
Child:
30:15743b79c6cb
Detect storage mount failure and reformat

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 29:6ff737b67e7d 239 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE);
screamer 29:6ff737b67e7d 240 if (btn_pressed) {
screamer 29:6ff737b67e7d 241 printf("User button is pushed on start...\n");
screamer 29:6ff737b67e7d 242 }
screamer 29:6ff737b67e7d 243 if (storage_status || btn_pressed) {
screamer 29:6ff737b67e7d 244 printf("Formatting the storage...\n");
screamer 29:6ff737b67e7d 245 sd.erase(0, sd.size());
screamer 29:6ff737b67e7d 246 storage_status = fs.reformat(&sd);
screamer 10:b27c962b3c3f 247 if (storage_status != 0) {
screamer 10:b27c962b3c3f 248 if (sd.erase(0, sd.size()) == 0) {
screamer 10:b27c962b3c3f 249 if (fs.format(&sd) == 0) {
screamer 10:b27c962b3c3f 250 storage_status = 0;
screamer 10:b27c962b3c3f 251 printf("The storage reformatted successfully.\n");
screamer 10:b27c962b3c3f 252 }
screamer 10:b27c962b3c3f 253 }
screamer 10:b27c962b3c3f 254 }
screamer 10:b27c962b3c3f 255 if (storage_status != 0) {
screamer 13:42b49a0caade 256 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status);
screamer 10:b27c962b3c3f 257 }
screamer 28:0e774865873d 258 } else {
screamer 28:0e774865873d 259 printf("You can hold the user button during boot to format the storage and change the device identity.\n");
screamer 10:b27c962b3c3f 260 }
screamer 10:b27c962b3c3f 261
screamer 10:b27c962b3c3f 262 sensors_init();
screamer 10:b27c962b3c3f 263
adustm 4:cf7342047b4d 264 // Connect to the internet (DHCP is expected to be on)
screamer 13:42b49a0caade 265 printf("Connecting to the network using Wifi...\n");
MarceloSalazar 9:265744785d33 266 net = NetworkInterface::get_default_instance();
adustm 4:cf7342047b4d 267
screamer 10:b27c962b3c3f 268 nsapi_error_t net_status = -1;
screamer 10:b27c962b3c3f 269 for (int tries = 0; tries < 3; tries++) {
screamer 10:b27c962b3c3f 270 net_status = net->connect();
screamer 10:b27c962b3c3f 271 if (net_status == NSAPI_ERROR_OK) {
screamer 10:b27c962b3c3f 272 break;
screamer 10:b27c962b3c3f 273 } else {
screamer 13:42b49a0caade 274 printf("Unable to connect to network. Retrying...\n");
screamer 10:b27c962b3c3f 275 }
screamer 10:b27c962b3c3f 276 }
MarceloSalazar 9:265744785d33 277
screamer 10:b27c962b3c3f 278 if (net_status != NSAPI_ERROR_OK) {
screamer 13:42b49a0caade 279 printf("ERROR: Connecting to the network failed (%d)!\n", net_status);
adustm 1:e86b1cffc402 280 return -1;
adustm 1:e86b1cffc402 281 }
adustm 1:e86b1cffc402 282
MarceloSalazar 9:265744785d33 283 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
adustm 1:e86b1cffc402 284
screamer 17:fc98adcf835a 285 printf("Initializing Pelion Device Management Client...\n");
screamer 17:fc98adcf835a 286
MarceloSalazar 9:265744785d33 287 // SimpleMbedCloudClient handles registering over LwM2M to Pelion DM
MarceloSalazar 9:265744785d33 288 SimpleMbedCloudClient client(net, bd, &fs);
adustm 4:cf7342047b4d 289 int client_status = client.init();
adustm 4:cf7342047b4d 290 if (client_status != 0) {
screamer 13:42b49a0caade 291 printf("ERROR: Pelion Client initialization failed (%d)\n", client_status);
adustm 1:e86b1cffc402 292 return -1;
adustm 1:e86b1cffc402 293 }
adustm 1:e86b1cffc402 294
adustm 4:cf7342047b4d 295 // Creating resources, which can be written or read from the cloud
screamer 12:1f1a50e973db 296 res_button = client.create_resource("3200/0/5501", "button_count");
screamer 12:1f1a50e973db 297 res_button->set_value(0);
screamer 12:1f1a50e973db 298 res_button->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 299 res_button->observable(true);
screamer 12:1f1a50e973db 300 res_button->attach_notification_callback(button_callback);
adustm 1:e86b1cffc402 301
screamer 10:b27c962b3c3f 302 // Sensor resources
screamer 12:1f1a50e973db 303 res_temperature = client.create_resource("3303/0/5700", "temperature");
screamer 12:1f1a50e973db 304 res_temperature->set_value(0);
screamer 12:1f1a50e973db 305 res_temperature->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 306 res_temperature->observable(true);
screamer 10:b27c962b3c3f 307
screamer 12:1f1a50e973db 308 res_humidity = client.create_resource("3304/0/5700", "humidity");
screamer 12:1f1a50e973db 309 res_humidity->set_value(0);
screamer 12:1f1a50e973db 310 res_humidity->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 311 res_humidity->observable(true);
screamer 10:b27c962b3c3f 312
screamer 13:42b49a0caade 313 #ifdef SEND_ALL_SENSORS
screamer 13:42b49a0caade 314 res_temperature2 = client.create_resource("3303/1/5700", "temperature");
screamer 13:42b49a0caade 315 res_temperature2->set_value(0);
screamer 13:42b49a0caade 316 res_temperature2->methods(M2MMethod::GET);
screamer 13:42b49a0caade 317 res_temperature2->observable(true);
screamer 13:42b49a0caade 318
screamer 28:0e774865873d 319 res_adc_temp = client.create_resource("3303/2/5700", "temperature");
screamer 28:0e774865873d 320 res_adc_temp->set_value(0);
screamer 28:0e774865873d 321 res_adc_temp->methods(M2MMethod::GET);
screamer 28:0e774865873d 322 res_adc_temp->observable(true);
screamer 28:0e774865873d 323
screamer 28:0e774865873d 324 res_accelerometer_x = client.create_resource("3313/0/5702", "accelerometer_x");
screamer 28:0e774865873d 325 res_accelerometer_x->set_value(0);
screamer 28:0e774865873d 326 res_accelerometer_x->methods(M2MMethod::GET);
screamer 28:0e774865873d 327 res_accelerometer_x->observable(true);
screamer 28:0e774865873d 328
screamer 28:0e774865873d 329 res_accelerometer_y = client.create_resource("3313/0/5703", "accelerometer_y");
screamer 28:0e774865873d 330 res_accelerometer_y->set_value(0);
screamer 28:0e774865873d 331 res_accelerometer_y->methods(M2MMethod::GET);
screamer 28:0e774865873d 332 res_accelerometer_y->observable(true);
screamer 28:0e774865873d 333
screamer 28:0e774865873d 334 res_accelerometer_z = client.create_resource("3313/0/5704", "accelerometer_z");
screamer 28:0e774865873d 335 res_accelerometer_z->set_value(0);
screamer 28:0e774865873d 336 res_accelerometer_z->methods(M2MMethod::GET);
screamer 28:0e774865873d 337 res_accelerometer_z->observable(true);
screamer 28:0e774865873d 338
screamer 28:0e774865873d 339 res_magnometer_x = client.create_resource("3314/0/5702", "magnometer_x");
screamer 28:0e774865873d 340 res_magnometer_x->set_value(0);
screamer 28:0e774865873d 341 res_magnometer_x->methods(M2MMethod::GET);
screamer 28:0e774865873d 342 res_magnometer_x->observable(true);
screamer 28:0e774865873d 343
screamer 28:0e774865873d 344 res_magnometer_y = client.create_resource("3314/0/5703", "magnometer_y");
screamer 28:0e774865873d 345 res_magnometer_y->set_value(0);
screamer 28:0e774865873d 346 res_magnometer_y->methods(M2MMethod::GET);
screamer 28:0e774865873d 347 res_magnometer_y->observable(true);
screamer 28:0e774865873d 348
screamer 28:0e774865873d 349 res_magnometer_z = client.create_resource("3314/0/5704", "magnometer_z");
screamer 28:0e774865873d 350 res_magnometer_z->set_value(0);
screamer 28:0e774865873d 351 res_magnometer_z->methods(M2MMethod::GET);
screamer 28:0e774865873d 352 res_magnometer_z->observable(true);
screamer 28:0e774865873d 353
screamer 28:0e774865873d 354 res_gyroscope_x = client.create_resource("3334/0/5702", "gyroscope_x");
screamer 13:42b49a0caade 355 res_gyroscope_x->set_value(0);
screamer 13:42b49a0caade 356 res_gyroscope_x->methods(M2MMethod::GET);
screamer 13:42b49a0caade 357 res_gyroscope_x->observable(true);
screamer 10:b27c962b3c3f 358
screamer 28:0e774865873d 359 res_gyroscope_y = client.create_resource("3334/0/5703", "gyroscope_y");
screamer 13:42b49a0caade 360 res_gyroscope_y->set_value(0);
screamer 13:42b49a0caade 361 res_gyroscope_y->methods(M2MMethod::GET);
screamer 13:42b49a0caade 362 res_gyroscope_y->observable(true);
screamer 13:42b49a0caade 363
screamer 28:0e774865873d 364 res_gyroscope_z = client.create_resource("3334/0/5704", "gyroscope_z");
screamer 13:42b49a0caade 365 res_gyroscope_z->set_value(0);
screamer 13:42b49a0caade 366 res_gyroscope_z->methods(M2MMethod::GET);
screamer 13:42b49a0caade 367 res_gyroscope_z->observable(true);
screamer 13:42b49a0caade 368
screamer 28:0e774865873d 369 res_adc_voltage = client.create_resource("3316/0/5700", "voltage");
screamer 28:0e774865873d 370 res_adc_voltage->set_value(0);
screamer 28:0e774865873d 371 res_adc_voltage->methods(M2MMethod::GET);
screamer 28:0e774865873d 372 res_adc_voltage->observable(true);
screamer 28:0e774865873d 373
screamer 28:0e774865873d 374 res_pressure = client.create_resource("3323/0/5700", "pressure");
screamer 28:0e774865873d 375 res_pressure->set_value(0);
screamer 28:0e774865873d 376 res_pressure->methods(M2MMethod::GET);
screamer 28:0e774865873d 377 res_pressure->observable(true);
screamer 28:0e774865873d 378
screamer 13:42b49a0caade 379 res_distance = client.create_resource("3330/0/5700", "distance");
screamer 28:0e774865873d 380 res_distance->set_value((float)999.9);
screamer 13:42b49a0caade 381 res_distance->methods(M2MMethod::GET);
screamer 13:42b49a0caade 382 res_distance->observable(true);
screamer 13:42b49a0caade 383
screamer 13:42b49a0caade 384 res_led = client.create_resource("3201/0/5853", "led_state");
screamer 13:42b49a0caade 385 res_led->set_value(1);
screamer 13:42b49a0caade 386 res_led->methods(M2MMethod::GET | M2MMethod::PUT);
screamer 13:42b49a0caade 387 res_led->attach_put_callback(led_put_callback);
screamer 13:42b49a0caade 388 #endif /* SEND_ALL_SENSORS */
screamer 11:8df4529f060d 389
MarceloSalazar 9:265744785d33 390 printf("Initialized Pelion Client. Registering...\n");
adustm 1:e86b1cffc402 391
adustm 4:cf7342047b4d 392 // Callback that fires when registering is complete
adustm 4:cf7342047b4d 393 client.on_registered(&registered);
adustm 1:e86b1cffc402 394
MarceloSalazar 9:265744785d33 395 // Register with Pelion DM
adustm 4:cf7342047b4d 396 client.register_and_connect();
adustm 1:e86b1cffc402 397
screamer 17:fc98adcf835a 398 int i = 600; // wait up 60 seconds before attaching sensors and button events
screamer 12:1f1a50e973db 399 while (i-- > 0 && !client.is_client_registered()) {
screamer 12:1f1a50e973db 400 wait_ms(100);
screamer 12:1f1a50e973db 401 }
screamer 12:1f1a50e973db 402
screamer 11:8df4529f060d 403 button.fall(eventQueue.event(&button_press));
screamer 10:b27c962b3c3f 404
screamer 15:a0430d40a918 405 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
adustm 4:cf7342047b4d 406 Ticker timer;
screamer 11:8df4529f060d 407 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL);
adustm 1:e86b1cffc402 408
adustm 4:cf7342047b4d 409 // You can easily run the eventQueue in a separate thread if required
adustm 4:cf7342047b4d 410 eventQueue.dispatch_forever();
adustm 1:e86b1cffc402 411 }
screamer 28:0e774865873d 412
MarceloSalazar 9:265744785d33 413 #endif