Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API X_NUCLEO_IDB0XA1 X_NUCLEO_IKS01A1 mbed
main.cpp
00001 /************************ STM32NUCLEO IOT Contest ****************************** 00002 * 00003 * Green Building IoT Solution for 00004 * Plant Life Monitoring And Maintenance 00005 * 00006 * Authored by 00007 * Dien Hoa Truong 00008 * Muhammad Haziq Bin Kamarul Azman 00009 * 00010 * for the 00011 * eSAME 2016 STM32NUCLEO IoT Contest in Sophia-Antipolis 00012 * 00013 * main.cpp | Program main 00014 * 00015 * See LICENCE.txt for information on copyrights 00016 * 00017 ******************************************************************************/ 00018 00019 /** Includes **/ 00020 #include "mbed.h" // ARM mbed library 00021 #include "x_nucleo_iks01a1.h" // STM32NUCLEO board library 00022 #include "ble/BLE.h" // Bluetooth LE library 00023 #include "GreenBuildingService.h" // Green Building service library 00024 00025 00026 00027 /** Defines **/ 00028 #define GB_SOIL_MOISTURE_MAX 70 // Soil moisture threshold value 00029 00030 00031 00032 /** Device declarations **/ 00033 00034 // Board-specific 00035 PwmOut pumpPWM(PC_8); // PWM motor control out pin 00036 DigitalOut led1(LED1, 1); // Debug pin instance 00037 AnalogIn moisture_sensor(PB_1); // Moisture sensor 00038 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15); // Expansion board instance 00039 static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor; // Expansion board humidity sensor instance 00040 static TempSensor *temp_sensor = mems_expansion_board->ht_sensor; // Expansion board temperature sensor instance 00041 00042 // BLE-specific 00043 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); // BLE device instance 00044 const static char DEVICE_NAME[] = "GB-Sensor"; // Device name 00045 static const uint16_t uuid16_list[] = {GreenBuildingService::UUID_GREEN_BUILDING_SERVICE}; 00046 GreenBuildingService *gbServicePtr; // Service pointer 00047 00048 // Program-specific 00049 float getMoistureValue(); 00050 float getHumidityValue(); 00051 float getTemperatureValue(); 00052 void errorLoop(void); 00053 void activateFastSensorPoll(); 00054 void deactivateFastSensorPoll(); 00055 void pumpActivateCallback(void); 00056 void pumpDeactivateCallback(void); 00057 00058 Ticker sanityTicker; 00059 Ticker sensorPollTicker; 00060 Ticker fastSensorPollTicker; 00061 Timeout pumpWaitTimeout; 00062 uint8_t usersConnected; 00063 bool sensorPolling; 00064 bool fastSensorPolling; 00065 bool pumpActivate; 00066 bool waitOnce; 00067 bool bleActive; 00068 bool pumpActive; 00069 00070 00071 /** Callbacks **/ 00072 00073 // BLE-specific callback 00074 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) // Callback for everytime the connection gets disconnected 00075 { 00076 ble.gap().startAdvertising(); // Restart advertising 00077 if((!pumpActive)||(!usersConnected)) 00078 deactivateFastSensorPoll(); 00079 bleActive = false; 00080 --usersConnected; 00081 // printf("\r\n> BLE : Disconnected. Advertising restarted."); 00082 } 00083 00084 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) // Callback for everytime the connection is established 00085 { 00086 ble.gap().stopAdvertising(); // Stop advertising 00087 activateFastSensorPoll(); 00088 bleActive = true; 00089 ++usersConnected; 00090 // printf("\r\n> BLE : Connected to %x. Accept no subsequent connections.", params->peerAddr); 00091 } 00092 00093 void onBleInitError(BLE &ble, ble_error_t error) 00094 { 00095 // printf("\r\n> BLE : Init error encountered. Error returned: %d", error); 00096 errorLoop(); 00097 } 00098 00099 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 00100 { 00101 BLE& ble = params->ble; 00102 ble_error_t error = params->error; 00103 00104 if (error != BLE_ERROR_NONE) { // Check to see init errors 00105 onBleInitError(ble, error); 00106 errorLoop(); 00107 } 00108 00109 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { // If this is not default instance (double instanciation?) 00110 // printf("\r\n> BLE : BLE controller instance is invalid."); 00111 errorLoop(); 00112 } 00113 00114 ble.gap().onDisconnection(disconnectionCallback); // Register disconnection callback 00115 ble.gap().onConnection(connectionCallback); // Register connection callback 00116 00117 gbServicePtr = new GreenBuildingService(ble); // Init service with initial value 00118 00119 /* Setup advertising. */ 00120 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00121 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00122 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,(uint8_t *)uuid16_list, sizeof(uuid16_list)); 00123 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00124 ble.gap().setAdvertisingInterval(1000); /* 1000ms */ 00125 ble.gap().startAdvertising(); 00126 00127 // printf("\r\n> BLE : BLE Init done."); 00128 } 00129 00130 // Helper functions for retrieving data from sensors 00131 float getMoistureValue() 00132 { 00133 float moisture = 0; 00134 for (int i = 1;i<=10;i++) { 00135 moisture += moisture_sensor.read(); // Get ten samples 00136 } 00137 moisture = moisture / 10; 00138 moisture = moisture * 3300; // Change the value to be in the 0 to 3300 range 00139 moisture = moisture / 33; // Convert to percentage 00140 return moisture; 00141 } 00142 00143 float getHumidityValue() 00144 { 00145 float humidity = 0; 00146 humidity_sensor->GetHumidity(&humidity); 00147 return humidity; 00148 } 00149 00150 float getTemperatureValue() 00151 { 00152 float temperature = 0; 00153 temp_sensor->GetTemperature(&temperature); 00154 return temperature; 00155 } 00156 00157 00158 // Miscellaneous callbacks & functions 00159 void sanityCallback(void) 00160 { 00161 led1 = !led1; // Blink LED1 to indicate system sanity 00162 } 00163 00164 void sensorPollCallback(void) 00165 { 00166 sensorPolling = true; 00167 } 00168 00169 void fastSensorPollCallback(void) 00170 { 00171 fastSensorPolling = true; 00172 } 00173 00174 void pumpActivateCallback(void) 00175 { 00176 pumpActivate = true; 00177 } 00178 00179 void pumpDeactivateCallback(void) 00180 { 00181 pumpActivate = false; 00182 } 00183 00184 void activateFastSensorPoll(void) 00185 { 00186 fastSensorPolling = true; 00187 fastSensorPollTicker.attach(&fastSensorPollCallback, 0.9); 00188 } 00189 00190 void deactivateFastSensorPoll(void) 00191 { 00192 fastSensorPolling = false; 00193 fastSensorPollTicker.detach(); 00194 } 00195 00196 00197 void errorLoop(void) 00198 { 00199 sanityTicker.detach(); 00200 sensorPollTicker.detach(); 00201 ble.shutdown(); 00202 // printf("\r\n> ERROR : Error encountered. Infinite looping."); 00203 while(true) 00204 { 00205 led1 != led1; 00206 } 00207 } 00208 00209 00210 00211 /** Pre-main inits **/ 00212 00213 00214 00215 /** Main loop **/ 00216 int main(void) 00217 { 00218 pumpPWM.write(1); 00219 pumpPWM.period(1.0f); 00220 00221 printf("\r\n/**\r\n * Green Building Sensor Device: Debug Info\r\n */"); 00222 00223 sensorPolling = false; 00224 fastSensorPolling = false; 00225 pumpActivate = false; 00226 waitOnce = true; 00227 bleActive = false; 00228 pumpActive = false; 00229 00230 sanityTicker.attach(sanityCallback, 1.1); // LED sanity checker 00231 sensorPollTicker.attach(sensorPollCallback, 4.9); // Sensor poll ticker 00232 00233 printf("\r\n> MAIN : Tickers initialized."); 00234 00235 volatile GreenBuildingService::PlantEnvironmentType_t peVal; // Plant environment var 00236 uint8_t pumpWaitTime = 3; // Pump waiting time 00237 00238 ble.init(bleInitComplete); // Pass BLE init complete function upon init 00239 00240 // while(ble.hasInitialized() == false); 00241 00242 printf("\r\n> MAIN : BLE Init procedure done."); 00243 00244 // Infinite loop 00245 while (true) { 00246 00247 if(sensorPolling || fastSensorPolling) 00248 { 00249 sensorPolling = false; // Deassert polling bit 00250 fastSensorPolling = false; 00251 00252 peVal.soilMoisture = (uint8_t) getMoistureValue(); // Update all measurements 00253 peVal.airHumidity = (uint8_t) getHumidityValue(); 00254 peVal.airTemperature = (int8_t) getTemperatureValue(); 00255 00256 if(ble.getGapState().connected) // Update characteristic if connected 00257 gbServicePtr->updatePlantEnvironment(peVal); 00258 00259 // printf("\r\n> MAIN : Current soil moisture = %d", peVal.soilMoisture); 00260 // printf("\r\n> MAIN : Current air humidity = %d", peVal.airHumidity); 00261 // printf("\r\n> MAIN : Current air temperature = %d", peVal.airTemperature); 00262 printf("%d\t%d\t%d\r\n", peVal.airTemperature, peVal.airHumidity, peVal.soilMoisture); 00263 00264 // If moisture is below 50% of max when user is present 00265 // or if less than 30% of max 00266 if( ( ((peVal.soilMoisture < 0.5*GB_SOIL_MOISTURE_MAX) && ble.getGapState().connected) || 00267 ((peVal.soilMoisture < 0.3*GB_SOIL_MOISTURE_MAX) && !ble.getGapState().connected) ) && 00268 waitOnce 00269 ) 00270 { 00271 pumpWaitTimeout.attach(&pumpActivateCallback, pumpWaitTime); // Waiting time is hard coded but may be calculated, I think 00272 activateFastSensorPoll(); 00273 waitOnce = false; 00274 pumpActive = true; 00275 } 00276 else if((peVal.soilMoisture >= 0.6*GB_SOIL_MOISTURE_MAX) && pumpActivate) // Stop condition: when soil moisture is at 60% of max 00277 { 00278 pumpPWM.write(1); 00279 pumpWaitTimeout.detach(); 00280 pumpDeactivateCallback(); 00281 if(!bleActive) 00282 deactivateFastSensorPoll(); 00283 waitOnce = true; 00284 pumpActive = false; 00285 } 00286 00287 if(pumpActivate) 00288 { 00289 // printf("\r\n> MAIN : Activating water pump."); 00290 pumpPWM.write(0.7); 00291 pumpActivate = false; 00292 pumpWaitTimeout.attach(&pumpActivateCallback, 1); 00293 } 00294 00295 } 00296 else 00297 ble.waitForEvent(); //Low power wait for event 00298 00299 } 00300 }
Generated on Tue Jul 12 2022 14:54:29 by
1.7.2