Jim Carver / Mbed OS GarageDoorOpener

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Committer:
JimCarver
Date:
Thu Dec 05 19:03:48 2019 +0000
Revision:
37:ec1124e5ec1f
Parent:
35:cbbafa9c3e15
Bug fix

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 // ----------------------------------------------------------------------------
MarceloSalazar 9:265744785d33 18 #ifndef MBED_TEST_MODE
screamer 28:0e774865873d 19
adustm 1:e86b1cffc402 20 #include "mbed.h"
adustm 1:e86b1cffc402 21 #include "simple-mbed-cloud-client.h"
screamer 10:b27c962b3c3f 22 #include "LittleFileSystem.h"
screamer 33:cfd9430e7d1e 23
screamer 33:cfd9430e7d1e 24 // Default network interface object. Don't forget to change the WiFi SSID/password in mbed_app.json if you're using WiFi.
screamer 33:cfd9430e7d1e 25 NetworkInterface *net;
screamer 33:cfd9430e7d1e 26
screamer 33:cfd9430e7d1e 27 // Default block device available on the target board
screamer 33:cfd9430e7d1e 28 BlockDevice* bd = BlockDevice::get_default_instance();
screamer 33:cfd9430e7d1e 29 SlicingBlockDevice sd(bd, 0, 2*1024*1024);
screamer 33:cfd9430e7d1e 30
screamer 33:cfd9430e7d1e 31 #if COMPONENT_SD || COMPONENT_NUSD
screamer 33:cfd9430e7d1e 32 // Use FATFileSystem for SD card type blockdevices
screamer 33:cfd9430e7d1e 33 FATFileSystem fs("fs");
screamer 33:cfd9430e7d1e 34 #else
screamer 33:cfd9430e7d1e 35 // Use LittleFileSystem for non-SD block devices to enable wear leveling and other functions
screamer 33:cfd9430e7d1e 36 LittleFileSystem fs("fs");
screamer 33:cfd9430e7d1e 37 #endif
screamer 33:cfd9430e7d1e 38
screamer 33:cfd9430e7d1e 39 // Default User button for GET example and for resetting the storage
screamer 33:cfd9430e7d1e 40 InterruptIn button(BUTTON1);
screamer 33:cfd9430e7d1e 41 // Default LED to use for PUT/POST example
JimCarver 35:cbbafa9c3e15 42 DigitalOut DoorActivate(PD_3, 0);
screamer 33:cfd9430e7d1e 43
screamer 33:cfd9430e7d1e 44 // How often to fetch sensor data (in seconds)
JimCarver 35:cbbafa9c3e15 45 #define SENSORS_POLL_INTERVAL 15.0
JimCarver 35:cbbafa9c3e15 46 int dflag = 1;
screamer 33:cfd9430e7d1e 47 // Sensors related includes and initialization
screamer 10:b27c962b3c3f 48 #include "HTS221Sensor.h"
screamer 10:b27c962b3c3f 49 #include "LPS22HBSensor.h"
screamer 28:0e774865873d 50 #include "VL53L0X.h"
screamer 10:b27c962b3c3f 51
screamer 10:b27c962b3c3f 52 static DevI2C devI2c(PB_11,PB_10);
screamer 12:1f1a50e973db 53 static HTS221Sensor sen_hum_temp(&devI2c);
screamer 12:1f1a50e973db 54 static LPS22HBSensor sen_press_temp(&devI2c);
JimCarver 35:cbbafa9c3e15 55
screamer 28:0e774865873d 56 static DigitalOut shutdown_pin(PC_6);
screamer 28:0e774865873d 57 static VL53L0X sen_distance(&devI2c, &shutdown_pin, PC_7);
screamer 11:8df4529f060d 58
MarceloSalazar 9:265744785d33 59 // Declaring pointers for access to Pelion Client resources outside of main()
screamer 12:1f1a50e973db 60 MbedCloudClientResource *res_button;
JimCarver 35:cbbafa9c3e15 61 MbedCloudClientResource *DoorControl;
JimCarver 35:cbbafa9c3e15 62
adustm 1:e86b1cffc402 63
screamer 33:cfd9430e7d1e 64 // Additional resources for sensor readings
JimCarver 35:cbbafa9c3e15 65
screamer 12:1f1a50e973db 66 MbedCloudClientResource *res_humidity;
screamer 12:1f1a50e973db 67 MbedCloudClientResource *res_temperature;
screamer 12:1f1a50e973db 68 MbedCloudClientResource *res_pressure;
screamer 12:1f1a50e973db 69 MbedCloudClientResource *res_distance;
JimCarver 35:cbbafa9c3e15 70
JimCarver 35:cbbafa9c3e15 71 // define your personal password
JimCarver 35:cbbafa9c3e15 72 #define DoorPassword "MyPassword"
adustm 1:e86b1cffc402 73
JimCarver 35:cbbafa9c3e15 74 char DoorCode[32];
JimCarver 35:cbbafa9c3e15 75 DigitalOut ConnectTrue(LED1);
JimCarver 35:cbbafa9c3e15 76 DigitalOut CodeError(LED2);
JimCarver 35:cbbafa9c3e15 77 int ErrorCount = 0;
JimCarver 35:cbbafa9c3e15 78 int ErrorLockoutTime = 0;
JimCarver 35:cbbafa9c3e15 79
screamer 33:cfd9430e7d1e 80 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
screamer 33:cfd9430e7d1e 81 // This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed
screamer 33:cfd9430e7d1e 82 EventQueue eventQueue;
screamer 33:cfd9430e7d1e 83
screamer 10:b27c962b3c3f 84 // When the device is registered, this variable will be used to access various useful information, like device ID etc.
screamer 10:b27c962b3c3f 85 static const ConnectorClientEndpointInfo* endpointInfo;
adustm 1:e86b1cffc402 86
screamer 10:b27c962b3c3f 87 /**
adustm 4:cf7342047b4d 88 * PUT handler
adustm 4:cf7342047b4d 89 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 90 * @param newValue Updated value for the resource
adustm 4:cf7342047b4d 91 */
screamer 32:2871fbeb627d 92 void put_callback(MbedCloudClientResource *resource, m2m::String newValue) {
JimCarver 35:cbbafa9c3e15 93
JimCarver 35:cbbafa9c3e15 94 if(ErrorLockoutTime != 0) { /* Ignore password attempts while locked */
JimCarver 35:cbbafa9c3e15 95 printf("Password Lockout!\r\n");
JimCarver 35:cbbafa9c3e15 96 return;
JimCarver 35:cbbafa9c3e15 97 }
screamer 29:6ff737b67e7d 98 printf("*** PUT received, new value: %s \n", newValue.c_str());
JimCarver 35:cbbafa9c3e15 99 strcpy(DoorCode, newValue.c_str());
JimCarver 35:cbbafa9c3e15 100 printf("%s\r\n", DoorCode);
JimCarver 35:cbbafa9c3e15 101 if(!strcmp(DoorCode, DoorPassword )) {
JimCarver 37:ec1124e5ec1f 102 DoorActivate = 1; /* Activate relay for 1500ms */
JimCarver 35:cbbafa9c3e15 103 wait_ms(1500);
JimCarver 35:cbbafa9c3e15 104 DoorActivate = 0;
JimCarver 35:cbbafa9c3e15 105 DoorCode[0] = NULL;
JimCarver 35:cbbafa9c3e15 106 // clear password error data
JimCarver 35:cbbafa9c3e15 107 ErrorCount = 0;
JimCarver 35:cbbafa9c3e15 108 ErrorLockoutTime = 0;
JimCarver 35:cbbafa9c3e15 109 } else { /* bad password attempt */
JimCarver 35:cbbafa9c3e15 110 DoorCode[0] = NULL;
JimCarver 35:cbbafa9c3e15 111 ErrorCount++;
JimCarver 35:cbbafa9c3e15 112 if(ErrorCount >= 3) { /* If password submitted is wring lockout the remote control on the third error */
JimCarver 35:cbbafa9c3e15 113 ErrorLockoutTime = (ErrorCount - 2) * 2; /* Double the lockout time after every failed password */
JimCarver 35:cbbafa9c3e15 114 CodeError = 1; /* Indicate lockout on LED */
JimCarver 35:cbbafa9c3e15 115 printf("PasswordLocked %d Minutes\r\n", ErrorLockoutTime);
JimCarver 35:cbbafa9c3e15 116 }
JimCarver 35:cbbafa9c3e15 117 }
JimCarver 35:cbbafa9c3e15 118
JimCarver 35:cbbafa9c3e15 119
adustm 1:e86b1cffc402 120 }
adustm 1:e86b1cffc402 121
JimCarver 35:cbbafa9c3e15 122
adustm 1:e86b1cffc402 123
screamer 11:8df4529f060d 124 /**
screamer 13:42b49a0caade 125 * Button function triggered by the physical button press.
screamer 11:8df4529f060d 126 */
screamer 11:8df4529f060d 127 void button_press() {
screamer 12:1f1a50e973db 128 int v = res_button->get_value_int() + 1;
screamer 12:1f1a50e973db 129 res_button->set_value(v);
screamer 29:6ff737b67e7d 130 printf("*** Button clicked %d times \n", v);
adustm 1:e86b1cffc402 131 }
adustm 1:e86b1cffc402 132
adustm 4:cf7342047b4d 133 /**
adustm 4:cf7342047b4d 134 * Notification callback handler
adustm 4:cf7342047b4d 135 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 136 * @param status The delivery status of the notification
adustm 4:cf7342047b4d 137 */
adustm 4:cf7342047b4d 138 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
screamer 29:6ff737b67e7d 139 printf("*** Button notification, status %s (%d) \n", MbedCloudClientResource::delivery_status_to_string(status), status);
adustm 4:cf7342047b4d 140 }
adustm 1:e86b1cffc402 141
adustm 4:cf7342047b4d 142 /**
adustm 4:cf7342047b4d 143 * Registration callback handler
adustm 4:cf7342047b4d 144 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
adustm 4:cf7342047b4d 145 */
adustm 4:cf7342047b4d 146 void registered(const ConnectorClientEndpointInfo *endpoint) {
screamer 17:fc98adcf835a 147 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
screamer 10:b27c962b3c3f 148 endpointInfo = endpoint;
adustm 4:cf7342047b4d 149 }
adustm 1:e86b1cffc402 150
screamer 10:b27c962b3c3f 151 /**
screamer 10:b27c962b3c3f 152 * Initialize sensors
screamer 10:b27c962b3c3f 153 */
screamer 10:b27c962b3c3f 154 void sensors_init() {
JimCarver 35:cbbafa9c3e15 155 uint8_t id1, id2;
screamer 10:b27c962b3c3f 156
screamer 29:6ff737b67e7d 157 printf ("\nSensors configuration:\n");
screamer 10:b27c962b3c3f 158 // Initialize sensors
screamer 12:1f1a50e973db 159 sen_hum_temp.init(NULL);
screamer 12:1f1a50e973db 160 sen_press_temp.init(NULL);
screamer 28:0e774865873d 161 sen_distance.init_sensor(VL53L0X_DEFAULT_ADDRESS);
screamer 10:b27c962b3c3f 162
screamer 10:b27c962b3c3f 163 /// Call sensors enable routines
screamer 12:1f1a50e973db 164 sen_hum_temp.enable();
screamer 12:1f1a50e973db 165 sen_press_temp.enable();
JimCarver 35:cbbafa9c3e15 166
screamer 10:b27c962b3c3f 167
screamer 29:6ff737b67e7d 168 sen_hum_temp.read_id(&id1);
screamer 29:6ff737b67e7d 169 sen_press_temp.read_id(&id2);
screamer 10:b27c962b3c3f 170
screamer 29:6ff737b67e7d 171 printf("HTS221 humidity & temperature = 0x%X\n", id1);
screamer 29:6ff737b67e7d 172 printf("LPS22HB pressure & temperature = 0x%X\n", id2);
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() {
JimCarver 37:ec1124e5ec1f 182 float temp1_value, humid_value, pressure_value;
screamer 32:2871fbeb627d 183 uint32_t distance_value, distance_reading;
screamer 10:b27c962b3c3f 184
JimCarver 35:cbbafa9c3e15 185 if(!dflag++) { /* Only update the sensors once a minute */
JimCarver 35:cbbafa9c3e15 186 sen_hum_temp.get_humidity(&humid_value);
JimCarver 35:cbbafa9c3e15 187 sen_hum_temp.get_temperature(&temp1_value);
JimCarver 35:cbbafa9c3e15 188 sen_press_temp.get_pressure(&pressure_value);
screamer 32:2871fbeb627d 189 res_humidity->set_value(humid_value);
screamer 32:2871fbeb627d 190 res_temperature->set_value(temp1_value);
screamer 32:2871fbeb627d 191 res_pressure->set_value(pressure_value);
JimCarver 35:cbbafa9c3e15 192 if(ErrorLockoutTime != 0) {
JimCarver 35:cbbafa9c3e15 193 ErrorLockoutTime--;
JimCarver 35:cbbafa9c3e15 194 if(ErrorLockoutTime == 0) {
JimCarver 35:cbbafa9c3e15 195 printf("Unlocked\r\n");
JimCarver 35:cbbafa9c3e15 196 CodeError = 0;
JimCarver 35:cbbafa9c3e15 197 }
JimCarver 35:cbbafa9c3e15 198 }
JimCarver 35:cbbafa9c3e15 199 }
JimCarver 35:cbbafa9c3e15 200 if(dflag > 3) dflag = 0;
JimCarver 35:cbbafa9c3e15 201 distance_reading = sen_distance.get_distance(&distance_value);
JimCarver 35:cbbafa9c3e15 202
JimCarver 35:cbbafa9c3e15 203
JimCarver 35:cbbafa9c3e15 204 if (distance_reading == VL53L0X_ERROR_NONE) {
JimCarver 35:cbbafa9c3e15 205 // printf("VL53L0X dist: %7ld mm\n", distance_value);
screamer 32:2871fbeb627d 206 res_distance->set_value((int)distance_value);
JimCarver 35:cbbafa9c3e15 207 } else {
JimCarver 35:cbbafa9c3e15 208 // printf("VL53L0X dist: -- \n");
JimCarver 35:cbbafa9c3e15 209 distance_value = 1999;
JimCarver 35:cbbafa9c3e15 210 res_distance->set_value((int)distance_value);
screamer 28:0e774865873d 211 }
screamer 10:b27c962b3c3f 212 }
screamer 10:b27c962b3c3f 213
adustm 4:cf7342047b4d 214 int main(void) {
screamer 17:fc98adcf835a 215 printf("\nStarting Simple Pelion Device Management Client example\n");
JimCarver 35:cbbafa9c3e15 216 ConnectTrue = 0;
JimCarver 35:cbbafa9c3e15 217 CodeError = 0;
JimCarver 35:cbbafa9c3e15 218 DoorActivate = 0;
screamer 29:6ff737b67e7d 219 int storage_status = fs.mount(&sd);
screamer 29:6ff737b67e7d 220 if (storage_status != 0) {
screamer 29:6ff737b67e7d 221 printf("Storage mounting failed.\n");
screamer 29:6ff737b67e7d 222 }
screamer 30:15743b79c6cb 223 // If the User button is pressed ons start, then format storage.
screamer 29:6ff737b67e7d 224 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE);
screamer 29:6ff737b67e7d 225 if (btn_pressed) {
screamer 29:6ff737b67e7d 226 printf("User button is pushed on start...\n");
screamer 29:6ff737b67e7d 227 }
screamer 30:15743b79c6cb 228
screamer 29:6ff737b67e7d 229 if (storage_status || btn_pressed) {
screamer 29:6ff737b67e7d 230 printf("Formatting the storage...\n");
screamer 30:15743b79c6cb 231 int storage_status = StorageHelper::format(&fs, &sd);
screamer 10:b27c962b3c3f 232 if (storage_status != 0) {
screamer 13:42b49a0caade 233 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status);
screamer 10:b27c962b3c3f 234 }
screamer 28:0e774865873d 235 } else {
screamer 28:0e774865873d 236 printf("You can hold the user button during boot to format the storage and change the device identity.\n");
screamer 10:b27c962b3c3f 237 }
screamer 10:b27c962b3c3f 238
screamer 10:b27c962b3c3f 239 sensors_init();
screamer 10:b27c962b3c3f 240
adustm 4:cf7342047b4d 241 // Connect to the internet (DHCP is expected to be on)
screamer 13:42b49a0caade 242 printf("Connecting to the network using Wifi...\n");
MarceloSalazar 9:265744785d33 243 net = NetworkInterface::get_default_instance();
adustm 4:cf7342047b4d 244
screamer 10:b27c962b3c3f 245 nsapi_error_t net_status = -1;
screamer 10:b27c962b3c3f 246 for (int tries = 0; tries < 3; tries++) {
screamer 10:b27c962b3c3f 247 net_status = net->connect();
screamer 10:b27c962b3c3f 248 if (net_status == NSAPI_ERROR_OK) {
screamer 10:b27c962b3c3f 249 break;
screamer 10:b27c962b3c3f 250 } else {
screamer 13:42b49a0caade 251 printf("Unable to connect to network. Retrying...\n");
screamer 10:b27c962b3c3f 252 }
screamer 10:b27c962b3c3f 253 }
MarceloSalazar 9:265744785d33 254
screamer 10:b27c962b3c3f 255 if (net_status != NSAPI_ERROR_OK) {
screamer 13:42b49a0caade 256 printf("ERROR: Connecting to the network failed (%d)!\n", net_status);
adustm 1:e86b1cffc402 257 return -1;
adustm 1:e86b1cffc402 258 }
adustm 1:e86b1cffc402 259
MarceloSalazar 9:265744785d33 260 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
adustm 1:e86b1cffc402 261
screamer 17:fc98adcf835a 262 printf("Initializing Pelion Device Management Client...\n");
screamer 17:fc98adcf835a 263
MarceloSalazar 9:265744785d33 264 // SimpleMbedCloudClient handles registering over LwM2M to Pelion DM
MarceloSalazar 9:265744785d33 265 SimpleMbedCloudClient client(net, bd, &fs);
adustm 4:cf7342047b4d 266 int client_status = client.init();
adustm 4:cf7342047b4d 267 if (client_status != 0) {
screamer 13:42b49a0caade 268 printf("ERROR: Pelion Client initialization failed (%d)\n", client_status);
adustm 1:e86b1cffc402 269 return -1;
adustm 1:e86b1cffc402 270 }
adustm 1:e86b1cffc402 271
adustm 4:cf7342047b4d 272 // Creating resources, which can be written or read from the cloud
screamer 32:2871fbeb627d 273 res_button = client.create_resource("3200/0/5501", "Button Count");
screamer 12:1f1a50e973db 274 res_button->set_value(0);
screamer 12:1f1a50e973db 275 res_button->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 276 res_button->observable(true);
JimCarver 35:cbbafa9c3e15 277 //res_button->max_age(6000);
screamer 12:1f1a50e973db 278 res_button->attach_notification_callback(button_callback);
adustm 1:e86b1cffc402 279
JimCarver 35:cbbafa9c3e15 280 DoorControl = client.create_resource("3201/0/5853", "Door Control");
JimCarver 35:cbbafa9c3e15 281 DoorControl->set_value(1);
JimCarver 35:cbbafa9c3e15 282 DoorControl->methods(M2MMethod::GET | M2MMethod::PUT);
JimCarver 35:cbbafa9c3e15 283 DoorControl->attach_put_callback(put_callback);
screamer 33:cfd9430e7d1e 284
screamer 10:b27c962b3c3f 285 // Sensor resources
screamer 32:2871fbeb627d 286 res_temperature = client.create_resource("3303/0/5700", "Temperature HTS221 (C)");
screamer 12:1f1a50e973db 287 res_temperature->set_value(0);
screamer 12:1f1a50e973db 288 res_temperature->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 289 res_temperature->observable(true);
screamer 10:b27c962b3c3f 290
screamer 32:2871fbeb627d 291 res_humidity = client.create_resource("3304/0/5700", "Humidity");
screamer 12:1f1a50e973db 292 res_humidity->set_value(0);
screamer 12:1f1a50e973db 293 res_humidity->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 294 res_humidity->observable(true);
screamer 10:b27c962b3c3f 295
screamer 32:2871fbeb627d 296 res_pressure = client.create_resource("3323/0/5700", "Pressure");
screamer 28:0e774865873d 297 res_pressure->set_value(0);
screamer 28:0e774865873d 298 res_pressure->methods(M2MMethod::GET);
screamer 28:0e774865873d 299 res_pressure->observable(true);
screamer 28:0e774865873d 300
screamer 32:2871fbeb627d 301 res_distance = client.create_resource("3330/0/5700", "Distance");
screamer 28:0e774865873d 302 res_distance->set_value((float)999.9);
screamer 13:42b49a0caade 303 res_distance->methods(M2MMethod::GET);
screamer 13:42b49a0caade 304 res_distance->observable(true);
screamer 11:8df4529f060d 305
MarceloSalazar 9:265744785d33 306 printf("Initialized Pelion Client. Registering...\n");
adustm 1:e86b1cffc402 307
adustm 4:cf7342047b4d 308 // Callback that fires when registering is complete
adustm 4:cf7342047b4d 309 client.on_registered(&registered);
adustm 1:e86b1cffc402 310
MarceloSalazar 9:265744785d33 311 // Register with Pelion DM
adustm 4:cf7342047b4d 312 client.register_and_connect();
adustm 1:e86b1cffc402 313
JimCarver 35:cbbafa9c3e15 314 int i = 6000; // wait up 600 seconds before attaching sensors and button events
screamer 12:1f1a50e973db 315 while (i-- > 0 && !client.is_client_registered()) {
screamer 12:1f1a50e973db 316 wait_ms(100);
screamer 12:1f1a50e973db 317 }
JimCarver 35:cbbafa9c3e15 318 ConnectTrue = 1;
screamer 11:8df4529f060d 319 button.fall(eventQueue.event(&button_press));
JimCarver 35:cbbafa9c3e15 320 res_button->set_value(0);
JimCarver 35:cbbafa9c3e15 321 sensors_update();
screamer 15:a0430d40a918 322 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
adustm 4:cf7342047b4d 323 Ticker timer;
screamer 11:8df4529f060d 324 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL);
adustm 1:e86b1cffc402 325
adustm 4:cf7342047b4d 326 // You can easily run the eventQueue in a separate thread if required
adustm 4:cf7342047b4d 327 eventQueue.dispatch_forever();
adustm 1:e86b1cffc402 328 }
screamer 28:0e774865873d 329
MarceloSalazar 9:265744785d33 330 #endif