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:
Mon Mar 04 22:11:02 2019 +0000
Revision:
28:0e774865873d
Parent:
20:a9aab92d378b
Child:
29:6ff737b67e7d
The example program now report all sensors

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