It is a simple IoT solution for plant life monitoring and maintenance, based on STM32NUCLEO boards and expansion modules. This branch is the post-eSAME development branch.

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 X_NUCLEO_IKS01A1 mbed

Fork of BLE_GreenYourLife_STM32 by Green Building Team

This branch is the main continuation of the original project. You can find it here.

Committer:
kaiserhaz
Date:
Mon Dec 05 14:56:00 2016 +0000
Revision:
7:bda318a72748
Parent:
6:35d615722597
Corrected some errors regarding commits. Damn this thing is messy.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kaiserhaz 0:7dce5e74ad91 1 /************************ STM32NUCLEO IOT Contest ******************************
kaiserhaz 0:7dce5e74ad91 2 *
kaiserhaz 0:7dce5e74ad91 3 * Green Building IoT Solution for
kaiserhaz 0:7dce5e74ad91 4 * Plant Life Monitoring And Maintenance
kaiserhaz 0:7dce5e74ad91 5 *
kaiserhaz 0:7dce5e74ad91 6 * Authored by
kaiserhaz 0:7dce5e74ad91 7 * Dien Hoa Truong
kaiserhaz 0:7dce5e74ad91 8 * Muhammad Haziq Bin Kamarul Azman
kaiserhaz 0:7dce5e74ad91 9 *
kaiserhaz 0:7dce5e74ad91 10 * main.cpp | Program main
kaiserhaz 0:7dce5e74ad91 11 *
kaiserhaz 0:7dce5e74ad91 12 ******************************************************************************/
kaiserhaz 0:7dce5e74ad91 13
kaiserhaz 0:7dce5e74ad91 14 /** Includes **/
kaiserhaz 0:7dce5e74ad91 15 #include "mbed.h" // ARM mbed library
kaiserhaz 0:7dce5e74ad91 16 #include "x_nucleo_iks01a1.h" // STM32NUCLEO board library
kaiserhaz 0:7dce5e74ad91 17 #include "ble/BLE.h" // Bluetooth LE library
kaiserhaz 0:7dce5e74ad91 18 #include "GreenBuildingService.h" // Green Building service library
kaiserhaz 0:7dce5e74ad91 19
kaiserhaz 0:7dce5e74ad91 20
kaiserhaz 0:7dce5e74ad91 21
kaiserhaz 0:7dce5e74ad91 22 /** Defines **/
kaiserhaz 2:326a19b95766 23 #define GB_SOIL_MOISTURE_MAX 70 // Soil moisture threshold value
kaiserhaz 5:9d68ed883e95 24 #define GB_USERS_CONNECTED_MAX 4 // Maximum connected users
kaiserhaz 5:9d68ed883e95 25 #define GB_PUMP_CYCLE_MAX 40 // Maximum pump cycle allowed
kaiserhaz 0:7dce5e74ad91 26
kaiserhaz 0:7dce5e74ad91 27
kaiserhaz 0:7dce5e74ad91 28
kaiserhaz 6:35d615722597 29 /** Declarations **/
kaiserhaz 0:7dce5e74ad91 30
kaiserhaz 0:7dce5e74ad91 31 // Board-specific
kaiserhaz 5:9d68ed883e95 32 PwmOut pumpPWM(PC_8); // PWM motor control out pin
kaiserhaz 0:7dce5e74ad91 33 DigitalOut led1(LED1, 1); // Debug pin instance
kaiserhaz 5:9d68ed883e95 34 AnalogIn moisture_sensor(PB_1); // Moisture sensor
kaiserhaz 0:7dce5e74ad91 35 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15); // Expansion board instance
kaiserhaz 5:9d68ed883e95 36 static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor; // Expansion board humidity sensor instance
kaiserhaz 5:9d68ed883e95 37 static TempSensor *temp_sensor = mems_expansion_board->ht_sensor; // Expansion board temperature sensor instance
kaiserhaz 0:7dce5e74ad91 38
kaiserhaz 0:7dce5e74ad91 39 // BLE-specific
kaiserhaz 0:7dce5e74ad91 40 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); // BLE device instance
kaiserhaz 0:7dce5e74ad91 41 const static char DEVICE_NAME[] = "GB-Sensor"; // Device name
kaiserhaz 5:9d68ed883e95 42 static const uint16_t uuid16_list[] = {GreenBuildingService::UUID_GREEN_BUILDING_SERVICE}; // UUID service list
kaiserhaz 0:7dce5e74ad91 43 GreenBuildingService *gbServicePtr; // Service pointer
kaiserhaz 5:9d68ed883e95 44 //Gap::Handle_t bleConnectionHandles[GB_USERS_CONNECTED_MAX]; // Connection handle tables
kaiserhaz 0:7dce5e74ad91 45
kaiserhaz 0:7dce5e74ad91 46 // Program-specific
kaiserhaz 0:7dce5e74ad91 47 float getMoistureValue();
kaiserhaz 0:7dce5e74ad91 48 float getHumidityValue();
kaiserhaz 0:7dce5e74ad91 49 float getTemperatureValue();
kaiserhaz 5:9d68ed883e95 50 void errorLoop(void);
kaiserhaz 5:9d68ed883e95 51 void activateFastSensorPoll();
kaiserhaz 5:9d68ed883e95 52 void deactivateFastSensorPoll();
kaiserhaz 5:9d68ed883e95 53 void pumpActivateCallback(void);
kaiserhaz 5:9d68ed883e95 54 void pumpDeactivateCallback(void);
kaiserhaz 0:7dce5e74ad91 55
kaiserhaz 5:9d68ed883e95 56 Ticker sanityTicker;
kaiserhaz 5:9d68ed883e95 57 Ticker sensorPollTicker;
kaiserhaz 5:9d68ed883e95 58 Ticker fastSensorPollTicker;
kaiserhaz 2:326a19b95766 59 Timeout pumpWaitTimeout;
kaiserhaz 5:9d68ed883e95 60
kaiserhaz 6:35d615722597 61 uint8_t pollWaitCount = 0;
kaiserhaz 5:9d68ed883e95 62 uint8_t pumpWaitTime = 3; // Pump waiting time
kaiserhaz 3:c460d60ffda6 63 uint8_t usersConnected;
kaiserhaz 5:9d68ed883e95 64 bool sensorPolling;
kaiserhaz 5:9d68ed883e95 65 bool fastSensorPolling;
kaiserhaz 5:9d68ed883e95 66 bool bleActive;
kaiserhaz 5:9d68ed883e95 67 bool pumpActive;
kaiserhaz 5:9d68ed883e95 68
kaiserhaz 0:7dce5e74ad91 69
kaiserhaz 0:7dce5e74ad91 70
kaiserhaz 0:7dce5e74ad91 71 /** Callbacks **/
kaiserhaz 0:7dce5e74ad91 72
kaiserhaz 0:7dce5e74ad91 73 // BLE-specific callback
kaiserhaz 0:7dce5e74ad91 74 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) // Callback for everytime the connection gets disconnected
kaiserhaz 0:7dce5e74ad91 75 {
kaiserhaz 0:7dce5e74ad91 76 ble.gap().startAdvertising(); // Restart advertising
kaiserhaz 3:c460d60ffda6 77 if((!pumpActive)||(!usersConnected))
kaiserhaz 2:326a19b95766 78 deactivateFastSensorPoll();
kaiserhaz 2:326a19b95766 79 bleActive = false;
kaiserhaz 3:c460d60ffda6 80 --usersConnected;
kaiserhaz 0:7dce5e74ad91 81 }
kaiserhaz 0:7dce5e74ad91 82
kaiserhaz 0:7dce5e74ad91 83 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) // Callback for everytime the connection is established
kaiserhaz 0:7dce5e74ad91 84 {
kaiserhaz 5:9d68ed883e95 85 if(usersConnected>GB_USERS_CONNECTED_MAX)
kaiserhaz 5:9d68ed883e95 86 ble.disconnect(params->handle, Gap::REMOTE_USER_TERMINATED_CONNECTION); // Disconnect automatically due to connection constraint
kaiserhaz 5:9d68ed883e95 87 else
kaiserhaz 5:9d68ed883e95 88 {
kaiserhaz 5:9d68ed883e95 89 activateFastSensorPoll();
kaiserhaz 5:9d68ed883e95 90 bleActive = true;
kaiserhaz 5:9d68ed883e95 91 ++usersConnected;
kaiserhaz 5:9d68ed883e95 92 }
kaiserhaz 0:7dce5e74ad91 93 }
kaiserhaz 0:7dce5e74ad91 94
kaiserhaz 0:7dce5e74ad91 95 void onBleInitError(BLE &ble, ble_error_t error)
kaiserhaz 0:7dce5e74ad91 96 {
kaiserhaz 0:7dce5e74ad91 97 errorLoop();
kaiserhaz 0:7dce5e74ad91 98 }
kaiserhaz 0:7dce5e74ad91 99
kaiserhaz 0:7dce5e74ad91 100 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
kaiserhaz 0:7dce5e74ad91 101 {
kaiserhaz 0:7dce5e74ad91 102 BLE& ble = params->ble;
kaiserhaz 0:7dce5e74ad91 103 ble_error_t error = params->error;
kaiserhaz 0:7dce5e74ad91 104
kaiserhaz 0:7dce5e74ad91 105 if (error != BLE_ERROR_NONE) { // Check to see init errors
kaiserhaz 0:7dce5e74ad91 106 onBleInitError(ble, error);
kaiserhaz 0:7dce5e74ad91 107 errorLoop();
kaiserhaz 0:7dce5e74ad91 108 }
kaiserhaz 0:7dce5e74ad91 109
kaiserhaz 0:7dce5e74ad91 110 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { // If this is not default instance (double instanciation?)
kaiserhaz 0:7dce5e74ad91 111 errorLoop();
kaiserhaz 0:7dce5e74ad91 112 }
kaiserhaz 0:7dce5e74ad91 113
kaiserhaz 0:7dce5e74ad91 114 ble.gap().onDisconnection(disconnectionCallback); // Register disconnection callback
kaiserhaz 0:7dce5e74ad91 115 ble.gap().onConnection(connectionCallback); // Register connection callback
kaiserhaz 0:7dce5e74ad91 116
kaiserhaz 0:7dce5e74ad91 117 gbServicePtr = new GreenBuildingService(ble); // Init service with initial value
kaiserhaz 0:7dce5e74ad91 118
kaiserhaz 0:7dce5e74ad91 119 /* Setup advertising. */
kaiserhaz 0:7dce5e74ad91 120 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
kaiserhaz 0:7dce5e74ad91 121 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
kaiserhaz 0:7dce5e74ad91 122 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,(uint8_t *)uuid16_list, sizeof(uuid16_list));
kaiserhaz 0:7dce5e74ad91 123 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
kaiserhaz 0:7dce5e74ad91 124 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
kaiserhaz 0:7dce5e74ad91 125 ble.gap().startAdvertising();
kaiserhaz 0:7dce5e74ad91 126 }
kaiserhaz 0:7dce5e74ad91 127
kaiserhaz 6:35d615722597 128 void sanityCallback(void)
kaiserhaz 6:35d615722597 129 {
kaiserhaz 6:35d615722597 130 led1 = !led1; // Blink LED1 to indicate system sanity
kaiserhaz 6:35d615722597 131 }
kaiserhaz 6:35d615722597 132
kaiserhaz 6:35d615722597 133 void sensorPollCallback(void)
kaiserhaz 6:35d615722597 134 {
kaiserhaz 6:35d615722597 135 if(++pollWaitCount==2)
kaiserhaz 6:35d615722597 136 {
kaiserhaz 6:35d615722597 137 pollWaitCount = 0;
kaiserhaz 6:35d615722597 138 sensorPolling = true;
kaiserhaz 6:35d615722597 139 }
kaiserhaz 6:35d615722597 140 }
kaiserhaz 6:35d615722597 141
kaiserhaz 6:35d615722597 142 void fastSensorPollCallback(void)
kaiserhaz 6:35d615722597 143 {
kaiserhaz 6:35d615722597 144 fastSensorPolling = true;
kaiserhaz 6:35d615722597 145 }
kaiserhaz 6:35d615722597 146
kaiserhaz 6:35d615722597 147 void pumpActivateCallback(void)
kaiserhaz 6:35d615722597 148 {
kaiserhaz 6:35d615722597 149 pumpPWM.write(0.7);
kaiserhaz 6:35d615722597 150 }
kaiserhaz 6:35d615722597 151
kaiserhaz 6:35d615722597 152 void pumpDeactivateCallback(void)
kaiserhaz 6:35d615722597 153 {
kaiserhaz 6:35d615722597 154 pumpPWM.write(1);
kaiserhaz 6:35d615722597 155 }
kaiserhaz 6:35d615722597 156
kaiserhaz 6:35d615722597 157
kaiserhaz 6:35d615722597 158
kaiserhaz 6:35d615722597 159 /** Functions **/
kaiserhaz 6:35d615722597 160
kaiserhaz 0:7dce5e74ad91 161 // Helper functions for retrieving data from sensors
kaiserhaz 0:7dce5e74ad91 162 float getMoistureValue()
kaiserhaz 0:7dce5e74ad91 163 {
kaiserhaz 0:7dce5e74ad91 164 float moisture = 0;
kaiserhaz 6:35d615722597 165 for (int i=1;i<=10;i++) {
kaiserhaz 0:7dce5e74ad91 166 moisture += moisture_sensor.read(); // Get ten samples
kaiserhaz 0:7dce5e74ad91 167 }
kaiserhaz 0:7dce5e74ad91 168 moisture = moisture / 10;
kaiserhaz 0:7dce5e74ad91 169 moisture = moisture * 3300; // Change the value to be in the 0 to 3300 range
kaiserhaz 0:7dce5e74ad91 170 moisture = moisture / 33; // Convert to percentage
kaiserhaz 0:7dce5e74ad91 171 return moisture;
kaiserhaz 0:7dce5e74ad91 172 }
kaiserhaz 0:7dce5e74ad91 173
kaiserhaz 0:7dce5e74ad91 174 float getHumidityValue()
kaiserhaz 0:7dce5e74ad91 175 {
kaiserhaz 0:7dce5e74ad91 176 float humidity = 0;
kaiserhaz 0:7dce5e74ad91 177 humidity_sensor->GetHumidity(&humidity);
kaiserhaz 0:7dce5e74ad91 178 return humidity;
kaiserhaz 0:7dce5e74ad91 179 }
kaiserhaz 0:7dce5e74ad91 180
kaiserhaz 0:7dce5e74ad91 181 float getTemperatureValue()
kaiserhaz 0:7dce5e74ad91 182 {
kaiserhaz 0:7dce5e74ad91 183 float temperature = 0;
kaiserhaz 0:7dce5e74ad91 184 temp_sensor->GetTemperature(&temperature);
kaiserhaz 0:7dce5e74ad91 185 return temperature;
kaiserhaz 0:7dce5e74ad91 186 }
kaiserhaz 0:7dce5e74ad91 187
kaiserhaz 0:7dce5e74ad91 188
kaiserhaz 6:35d615722597 189 // Miscellaneous functions
kaiserhaz 2:326a19b95766 190 void activateFastSensorPoll(void)
kaiserhaz 2:326a19b95766 191 {
kaiserhaz 2:326a19b95766 192 fastSensorPolling = true;
kaiserhaz 6:35d615722597 193 fastSensorPollTicker.attach(&fastSensorPollCallback, 1.9f);
kaiserhaz 2:326a19b95766 194 }
kaiserhaz 2:326a19b95766 195
kaiserhaz 2:326a19b95766 196 void deactivateFastSensorPoll(void)
kaiserhaz 2:326a19b95766 197 {
kaiserhaz 2:326a19b95766 198 fastSensorPolling = false;
kaiserhaz 2:326a19b95766 199 fastSensorPollTicker.detach();
kaiserhaz 2:326a19b95766 200 }
kaiserhaz 2:326a19b95766 201
kaiserhaz 5:9d68ed883e95 202 void pumpSetup(void)
kaiserhaz 5:9d68ed883e95 203 {
kaiserhaz 5:9d68ed883e95 204 pumpPWM.write(1);
kaiserhaz 5:9d68ed883e95 205 pumpPWM.period(2.0f);
kaiserhaz 5:9d68ed883e95 206 }
kaiserhaz 5:9d68ed883e95 207
kaiserhaz 0:7dce5e74ad91 208 void errorLoop(void)
kaiserhaz 0:7dce5e74ad91 209 {
kaiserhaz 0:7dce5e74ad91 210 sanityTicker.detach();
kaiserhaz 0:7dce5e74ad91 211 sensorPollTicker.detach();
kaiserhaz 0:7dce5e74ad91 212 ble.shutdown();
kaiserhaz 5:9d68ed883e95 213
kaiserhaz 0:7dce5e74ad91 214 while(true)
kaiserhaz 0:7dce5e74ad91 215 {
kaiserhaz 5:9d68ed883e95 216 led1 != led1;
kaiserhaz 5:9d68ed883e95 217 printf("\n\n\n\n\n\n\n\n");
kaiserhaz 0:7dce5e74ad91 218 }
kaiserhaz 0:7dce5e74ad91 219 }
kaiserhaz 0:7dce5e74ad91 220
kaiserhaz 0:7dce5e74ad91 221
kaiserhaz 0:7dce5e74ad91 222
kaiserhaz 0:7dce5e74ad91 223 /** Pre-main inits **/
kaiserhaz 0:7dce5e74ad91 224
kaiserhaz 0:7dce5e74ad91 225
kaiserhaz 0:7dce5e74ad91 226
kaiserhaz 0:7dce5e74ad91 227 /** Main loop **/
kaiserhaz 0:7dce5e74ad91 228 int main(void)
kaiserhaz 0:7dce5e74ad91 229 {
kaiserhaz 5:9d68ed883e95 230 pumpSetup(); // Setup pump
kaiserhaz 6:35d615722597 231
kaiserhaz 5:9d68ed883e95 232 sensorPolling = false;
kaiserhaz 2:326a19b95766 233 fastSensorPolling = false;
kaiserhaz 5:9d68ed883e95 234 bleActive = false;
kaiserhaz 5:9d68ed883e95 235 pumpActive = false;
kaiserhaz 0:7dce5e74ad91 236
kaiserhaz 5:9d68ed883e95 237 sanityTicker.attach(sanityCallback, 1.1f); // LED sanity checker
kaiserhaz 6:35d615722597 238 sensorPollTicker.attach(sensorPollCallback, 1799.9f); // Sensor poll ticker (30 mins)
kaiserhaz 0:7dce5e74ad91 239
kaiserhaz 0:7dce5e74ad91 240 volatile GreenBuildingService::PlantEnvironmentType_t peVal; // Plant environment var
kaiserhaz 5:9d68ed883e95 241 uint8_t pumpLimitCount = 0; // Pump limit counter
kaiserhaz 0:7dce5e74ad91 242
kaiserhaz 0:7dce5e74ad91 243 ble.init(bleInitComplete); // Pass BLE init complete function upon init
kaiserhaz 0:7dce5e74ad91 244
kaiserhaz 5:9d68ed883e95 245 // while(ble.hasInitialized() == false); // Buggy loop
kaiserhaz 0:7dce5e74ad91 246
kaiserhaz 0:7dce5e74ad91 247 // Infinite loop
kaiserhaz 0:7dce5e74ad91 248 while (true) {
kaiserhaz 0:7dce5e74ad91 249
kaiserhaz 2:326a19b95766 250 if(sensorPolling || fastSensorPolling)
kaiserhaz 0:7dce5e74ad91 251 {
kaiserhaz 6:35d615722597 252 sensorPolling = false; // Deassert polling bit
kaiserhaz 2:326a19b95766 253 fastSensorPolling = false;
kaiserhaz 0:7dce5e74ad91 254
kaiserhaz 0:7dce5e74ad91 255 peVal.soilMoisture = (uint8_t) getMoistureValue(); // Update all measurements
kaiserhaz 0:7dce5e74ad91 256 peVal.airHumidity = (uint8_t) getHumidityValue();
kaiserhaz 0:7dce5e74ad91 257 peVal.airTemperature = (int8_t) getTemperatureValue();
kaiserhaz 0:7dce5e74ad91 258
kaiserhaz 0:7dce5e74ad91 259 if(ble.getGapState().connected) // Update characteristic if connected
kaiserhaz 0:7dce5e74ad91 260 gbServicePtr->updatePlantEnvironment(peVal);
kaiserhaz 0:7dce5e74ad91 261
kaiserhaz 2:326a19b95766 262 printf("%d\t%d\t%d\r\n", peVal.airTemperature, peVal.airHumidity, peVal.soilMoisture);
kaiserhaz 0:7dce5e74ad91 263
kaiserhaz 2:326a19b95766 264 // If moisture is below 50% of max when user is present
kaiserhaz 2:326a19b95766 265 // or if less than 30% of max
kaiserhaz 5:9d68ed883e95 266 // and pump is not active
kaiserhaz 2:326a19b95766 267 if( ( ((peVal.soilMoisture < 0.5*GB_SOIL_MOISTURE_MAX) && ble.getGapState().connected) ||
kaiserhaz 5:9d68ed883e95 268 ((peVal.soilMoisture < 0.3*GB_SOIL_MOISTURE_MAX) && !ble.getGapState().connected) &&
kaiserhaz 5:9d68ed883e95 269 !pumpActive
kaiserhaz 5:9d68ed883e95 270 )
kaiserhaz 2:326a19b95766 271 )
kaiserhaz 2:326a19b95766 272 {
kaiserhaz 2:326a19b95766 273 activateFastSensorPoll();
kaiserhaz 2:326a19b95766 274 pumpActive = true;
kaiserhaz 5:9d68ed883e95 275 // TODO: calculate pumpWaitTime ( pumpWaitTime = f(peVal.airHumidity, peVal.airTemperature) )
kaiserhaz 5:9d68ed883e95 276 pumpWaitTimeout.attach(&pumpActivateCallback, pumpWaitTime);
kaiserhaz 2:326a19b95766 277 }
kaiserhaz 2:326a19b95766 278
kaiserhaz 5:9d68ed883e95 279 // Stop condition: when soil moisture is at 60% of max or after few pump cycles
kaiserhaz 5:9d68ed883e95 280 if(pumpActive)
kaiserhaz 2:326a19b95766 281 {
kaiserhaz 5:9d68ed883e95 282 ++pumpLimitCount;
kaiserhaz 5:9d68ed883e95 283
kaiserhaz 5:9d68ed883e95 284 if( (peVal.soilMoisture >= 0.6*GB_SOIL_MOISTURE_MAX) ||
kaiserhaz 5:9d68ed883e95 285 (pumpLimitCount>GB_PUMP_CYCLE_MAX)
kaiserhaz 5:9d68ed883e95 286 )
kaiserhaz 6:35d615722597 287 { // Generally here, we should notify user when there is no water
kaiserhaz 5:9d68ed883e95 288 pumpWaitTimeout.detach();
kaiserhaz 5:9d68ed883e95 289 pumpDeactivateCallback();
kaiserhaz 6:35d615722597 290 pumpActive = false;
kaiserhaz 5:9d68ed883e95 291 if(!bleActive)
kaiserhaz 5:9d68ed883e95 292 deactivateFastSensorPoll();
kaiserhaz 6:35d615722597 293 pumpLimitCount = 0;
kaiserhaz 5:9d68ed883e95 294 }
kaiserhaz 0:7dce5e74ad91 295 }
kaiserhaz 2:326a19b95766 296
kaiserhaz 0:7dce5e74ad91 297 }
kaiserhaz 0:7dce5e74ad91 298 else
kaiserhaz 2:326a19b95766 299 ble.waitForEvent(); //Low power wait for event
kaiserhaz 0:7dce5e74ad91 300
kaiserhaz 0:7dce5e74ad91 301 }
kaiserhaz 0:7dce5e74ad91 302 }