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 Nov 28 15:19:38 2016 +0000
Revision:
1:b30300f95d4a
Parent:
0:7dce5e74ad91
Child:
2:326a19b95766
Corrected ports for moisture sensor and PWM motor because all other ports on the Arduino-compatible headers have been used up by the modules.

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 * for the
kaiserhaz 0:7dce5e74ad91 11 * eSAME 2016 STM32NUCLEO IoT Contest in Sophia-Antipolis
kaiserhaz 0:7dce5e74ad91 12 *
kaiserhaz 0:7dce5e74ad91 13 * main.cpp | Program main
kaiserhaz 0:7dce5e74ad91 14 *
kaiserhaz 0:7dce5e74ad91 15 ******************************************************************************/
kaiserhaz 0:7dce5e74ad91 16
kaiserhaz 0:7dce5e74ad91 17 /** Includes **/
kaiserhaz 0:7dce5e74ad91 18 #include "mbed.h" // ARM mbed library
kaiserhaz 0:7dce5e74ad91 19 #include "x_nucleo_iks01a1.h" // STM32NUCLEO board library
kaiserhaz 0:7dce5e74ad91 20 #include "ble/BLE.h" // Bluetooth LE library
kaiserhaz 0:7dce5e74ad91 21 #include "GreenBuildingService.h" // Green Building service library
kaiserhaz 0:7dce5e74ad91 22
kaiserhaz 0:7dce5e74ad91 23
kaiserhaz 0:7dce5e74ad91 24
kaiserhaz 0:7dce5e74ad91 25 /** Defines **/
kaiserhaz 0:7dce5e74ad91 26 #define GB_SOIL_MOISTURE_MAX 100 // Soil moisture threshold value
kaiserhaz 0:7dce5e74ad91 27
kaiserhaz 0:7dce5e74ad91 28
kaiserhaz 0:7dce5e74ad91 29
kaiserhaz 0:7dce5e74ad91 30 /** Device declarations **/
kaiserhaz 0:7dce5e74ad91 31
kaiserhaz 0:7dce5e74ad91 32 // Board-specific
kaiserhaz 1:b30300f95d4a 33 PwmOut pumpPWM(PC_8); // PWM motor control out pin
kaiserhaz 0:7dce5e74ad91 34 DigitalOut led1(LED1, 1); // Debug pin instance
kaiserhaz 1:b30300f95d4a 35 AnalogIn moisture_sensor(PB_1); // Moisture sensor
kaiserhaz 0:7dce5e74ad91 36 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15); // Expansion board instance
kaiserhaz 0:7dce5e74ad91 37 static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor; // Expansion board humidity sensor instance
kaiserhaz 0:7dce5e74ad91 38 static TempSensor *temp_sensor = mems_expansion_board->ht_sensor; // Expansion board temperature sensor instance
kaiserhaz 0:7dce5e74ad91 39
kaiserhaz 0:7dce5e74ad91 40 // BLE-specific
kaiserhaz 0:7dce5e74ad91 41 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); // BLE device instance
kaiserhaz 0:7dce5e74ad91 42 const static char DEVICE_NAME[] = "GB-Sensor"; // Device name
kaiserhaz 0:7dce5e74ad91 43 static const uint16_t uuid16_list[] = {GreenBuildingService::UUID_GREEN_BUILDING_SERVICE};
kaiserhaz 0:7dce5e74ad91 44 GreenBuildingService *gbServicePtr; // Service pointer
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 0:7dce5e74ad91 50 void errorLoop(void);
kaiserhaz 0:7dce5e74ad91 51
kaiserhaz 0:7dce5e74ad91 52 Ticker sanityTicker;
kaiserhaz 0:7dce5e74ad91 53 Ticker sensorPollTicker;
kaiserhaz 0:7dce5e74ad91 54 bool sensorPolling;
kaiserhaz 0:7dce5e74ad91 55
kaiserhaz 0:7dce5e74ad91 56
kaiserhaz 0:7dce5e74ad91 57
kaiserhaz 0:7dce5e74ad91 58 /** Callbacks **/
kaiserhaz 0:7dce5e74ad91 59
kaiserhaz 0:7dce5e74ad91 60 // BLE-specific callback
kaiserhaz 0:7dce5e74ad91 61 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) // Callback for everytime the connection gets disconnected
kaiserhaz 0:7dce5e74ad91 62 {
kaiserhaz 0:7dce5e74ad91 63 ble.gap().startAdvertising(); // Restart advertising
kaiserhaz 0:7dce5e74ad91 64 // printf("\r\n> BLE : Disconnected. Advertising restarted.");
kaiserhaz 0:7dce5e74ad91 65 }
kaiserhaz 0:7dce5e74ad91 66
kaiserhaz 0:7dce5e74ad91 67 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) // Callback for everytime the connection is established
kaiserhaz 0:7dce5e74ad91 68 {
kaiserhaz 0:7dce5e74ad91 69 // ble.gap().stopAdvertising(); // Stop advertising
kaiserhaz 0:7dce5e74ad91 70 // printf("\r\n> BLE : Connected to %x. Accept no subsequent connections.", params->peerAddr);
kaiserhaz 0:7dce5e74ad91 71 }
kaiserhaz 0:7dce5e74ad91 72
kaiserhaz 0:7dce5e74ad91 73 void onBleInitError(BLE &ble, ble_error_t error)
kaiserhaz 0:7dce5e74ad91 74 {
kaiserhaz 0:7dce5e74ad91 75 // printf("\r\n> BLE : Init error encountered. Error returned: %d", error);
kaiserhaz 0:7dce5e74ad91 76 errorLoop();
kaiserhaz 0:7dce5e74ad91 77 }
kaiserhaz 0:7dce5e74ad91 78
kaiserhaz 0:7dce5e74ad91 79 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
kaiserhaz 0:7dce5e74ad91 80 {
kaiserhaz 0:7dce5e74ad91 81 BLE& ble = params->ble;
kaiserhaz 0:7dce5e74ad91 82 ble_error_t error = params->error;
kaiserhaz 0:7dce5e74ad91 83
kaiserhaz 0:7dce5e74ad91 84 if (error != BLE_ERROR_NONE) { // Check to see init errors
kaiserhaz 0:7dce5e74ad91 85 onBleInitError(ble, error);
kaiserhaz 0:7dce5e74ad91 86 errorLoop();
kaiserhaz 0:7dce5e74ad91 87 }
kaiserhaz 0:7dce5e74ad91 88
kaiserhaz 0:7dce5e74ad91 89 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { // If this is not default instance (double instanciation?)
kaiserhaz 0:7dce5e74ad91 90 // printf("\r\n> BLE : BLE controller instance is invalid.");
kaiserhaz 0:7dce5e74ad91 91 errorLoop();
kaiserhaz 0:7dce5e74ad91 92 }
kaiserhaz 0:7dce5e74ad91 93
kaiserhaz 0:7dce5e74ad91 94 ble.gap().onDisconnection(disconnectionCallback); // Register disconnection callback
kaiserhaz 0:7dce5e74ad91 95 ble.gap().onConnection(connectionCallback); // Register connection callback
kaiserhaz 0:7dce5e74ad91 96
kaiserhaz 0:7dce5e74ad91 97 gbServicePtr = new GreenBuildingService(ble); // Init service with initial value
kaiserhaz 0:7dce5e74ad91 98
kaiserhaz 0:7dce5e74ad91 99 /* Setup advertising. */
kaiserhaz 0:7dce5e74ad91 100 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
kaiserhaz 0:7dce5e74ad91 101 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
kaiserhaz 0:7dce5e74ad91 102 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,(uint8_t *)uuid16_list, sizeof(uuid16_list));
kaiserhaz 0:7dce5e74ad91 103 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
kaiserhaz 0:7dce5e74ad91 104 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
kaiserhaz 0:7dce5e74ad91 105 ble.gap().startAdvertising();
kaiserhaz 0:7dce5e74ad91 106
kaiserhaz 0:7dce5e74ad91 107 // printf("\r\n> BLE : BLE Init done.");
kaiserhaz 0:7dce5e74ad91 108 }
kaiserhaz 0:7dce5e74ad91 109
kaiserhaz 0:7dce5e74ad91 110 // Helper functions for retrieving data from sensors
kaiserhaz 0:7dce5e74ad91 111 float getMoistureValue()
kaiserhaz 0:7dce5e74ad91 112 {
kaiserhaz 0:7dce5e74ad91 113 float moisture = 0;
kaiserhaz 0:7dce5e74ad91 114 for (int i = 1;i<=10;i++) {
kaiserhaz 0:7dce5e74ad91 115 moisture += moisture_sensor.read(); // Get ten samples
kaiserhaz 0:7dce5e74ad91 116 }
kaiserhaz 0:7dce5e74ad91 117 moisture = moisture / 10;
kaiserhaz 0:7dce5e74ad91 118 moisture = moisture * 3300; // Change the value to be in the 0 to 3300 range
kaiserhaz 0:7dce5e74ad91 119 moisture = moisture / 33; // Convert to percentage
kaiserhaz 0:7dce5e74ad91 120 return moisture;
kaiserhaz 0:7dce5e74ad91 121 }
kaiserhaz 0:7dce5e74ad91 122
kaiserhaz 0:7dce5e74ad91 123 float getHumidityValue()
kaiserhaz 0:7dce5e74ad91 124 {
kaiserhaz 0:7dce5e74ad91 125 float humidity = 0;
kaiserhaz 0:7dce5e74ad91 126 humidity_sensor->GetHumidity(&humidity);
kaiserhaz 0:7dce5e74ad91 127 return humidity;
kaiserhaz 0:7dce5e74ad91 128 }
kaiserhaz 0:7dce5e74ad91 129
kaiserhaz 0:7dce5e74ad91 130 float getTemperatureValue()
kaiserhaz 0:7dce5e74ad91 131 {
kaiserhaz 0:7dce5e74ad91 132 float temperature = 0;
kaiserhaz 0:7dce5e74ad91 133 temp_sensor->GetTemperature(&temperature);
kaiserhaz 0:7dce5e74ad91 134 return temperature;
kaiserhaz 0:7dce5e74ad91 135 }
kaiserhaz 0:7dce5e74ad91 136
kaiserhaz 0:7dce5e74ad91 137
kaiserhaz 0:7dce5e74ad91 138 // Miscellaneous callbacks & functions
kaiserhaz 0:7dce5e74ad91 139 void sanityCallback(void)
kaiserhaz 0:7dce5e74ad91 140 {
kaiserhaz 0:7dce5e74ad91 141 led1 = !led1; // Blink LED1 to indicate system sanity
kaiserhaz 0:7dce5e74ad91 142 }
kaiserhaz 0:7dce5e74ad91 143
kaiserhaz 0:7dce5e74ad91 144 void sensorPollCallback(void)
kaiserhaz 0:7dce5e74ad91 145 {
kaiserhaz 0:7dce5e74ad91 146 sensorPolling = true;
kaiserhaz 0:7dce5e74ad91 147 }
kaiserhaz 0:7dce5e74ad91 148
kaiserhaz 0:7dce5e74ad91 149 void errorLoop(void)
kaiserhaz 0:7dce5e74ad91 150 {
kaiserhaz 0:7dce5e74ad91 151 sanityTicker.detach();
kaiserhaz 0:7dce5e74ad91 152 sensorPollTicker.detach();
kaiserhaz 0:7dce5e74ad91 153 ble.shutdown();
kaiserhaz 1:b30300f95d4a 154 // printf("\r\n> ERROR : Error encountered. Infinite looping.");
kaiserhaz 0:7dce5e74ad91 155 while(true)
kaiserhaz 0:7dce5e74ad91 156 {
kaiserhaz 0:7dce5e74ad91 157 led1 != led1;
kaiserhaz 0:7dce5e74ad91 158 }
kaiserhaz 0:7dce5e74ad91 159 }
kaiserhaz 0:7dce5e74ad91 160
kaiserhaz 0:7dce5e74ad91 161
kaiserhaz 0:7dce5e74ad91 162
kaiserhaz 0:7dce5e74ad91 163 /** Pre-main inits **/
kaiserhaz 0:7dce5e74ad91 164
kaiserhaz 0:7dce5e74ad91 165
kaiserhaz 0:7dce5e74ad91 166
kaiserhaz 0:7dce5e74ad91 167 /** Main loop **/
kaiserhaz 0:7dce5e74ad91 168 int main(void)
kaiserhaz 0:7dce5e74ad91 169 {
kaiserhaz 0:7dce5e74ad91 170 printf("\r\n/**\r\n * Green Building Sensor Device: Debug Info\r\n */");
kaiserhaz 0:7dce5e74ad91 171
kaiserhaz 0:7dce5e74ad91 172 sensorPolling = false;
kaiserhaz 0:7dce5e74ad91 173
kaiserhaz 0:7dce5e74ad91 174 sanityTicker.attach(sanityCallback, 1.1); // LED sanity checker
kaiserhaz 0:7dce5e74ad91 175 sensorPollTicker.attach(sensorPollCallback, 5); // Sensor poll ticker
kaiserhaz 0:7dce5e74ad91 176
kaiserhaz 0:7dce5e74ad91 177 printf("\r\n> MAIN : Tickers initialized.");
kaiserhaz 0:7dce5e74ad91 178
kaiserhaz 0:7dce5e74ad91 179 volatile GreenBuildingService::PlantEnvironmentType_t peVal; // Plant environment var
kaiserhaz 0:7dce5e74ad91 180 uint8_t pumpCount = 0; // Pump timer
kaiserhaz 0:7dce5e74ad91 181
kaiserhaz 0:7dce5e74ad91 182 ble.init(bleInitComplete); // Pass BLE init complete function upon init
kaiserhaz 0:7dce5e74ad91 183
kaiserhaz 1:b30300f95d4a 184 // while(ble.hasInitialized() == false);
kaiserhaz 0:7dce5e74ad91 185
kaiserhaz 0:7dce5e74ad91 186 printf("\r\n> MAIN : BLE Init procedure done.");
kaiserhaz 0:7dce5e74ad91 187
kaiserhaz 0:7dce5e74ad91 188 // Infinite loop
kaiserhaz 0:7dce5e74ad91 189 while (true) {
kaiserhaz 0:7dce5e74ad91 190
kaiserhaz 0:7dce5e74ad91 191 if(sensorPolling)
kaiserhaz 0:7dce5e74ad91 192 {
kaiserhaz 0:7dce5e74ad91 193 sensorPolling = false; // Deassert polling bit
kaiserhaz 0:7dce5e74ad91 194
kaiserhaz 0:7dce5e74ad91 195 peVal.soilMoisture = (uint8_t) getMoistureValue(); // Update all measurements
kaiserhaz 0:7dce5e74ad91 196 peVal.airHumidity = (uint8_t) getHumidityValue();
kaiserhaz 0:7dce5e74ad91 197 peVal.airTemperature = (int8_t) getTemperatureValue();
kaiserhaz 0:7dce5e74ad91 198
kaiserhaz 0:7dce5e74ad91 199 if(ble.getGapState().connected) // Update characteristic if connected
kaiserhaz 0:7dce5e74ad91 200 gbServicePtr->updatePlantEnvironment(peVal);
kaiserhaz 0:7dce5e74ad91 201
kaiserhaz 0:7dce5e74ad91 202 printf("\r\n> MAIN : Current soil moisture = %d", peVal.soilMoisture);
kaiserhaz 0:7dce5e74ad91 203 printf("\r\n> MAIN : Current air humidity = %d", peVal.airHumidity);
kaiserhaz 0:7dce5e74ad91 204 printf("\r\n> MAIN : Current air temperature = %d", peVal.airTemperature);
kaiserhaz 0:7dce5e74ad91 205 printf("\r\n");
kaiserhaz 0:7dce5e74ad91 206
kaiserhaz 0:7dce5e74ad91 207 if (peVal.soilMoisture < 0.6*GB_SOIL_MOISTURE_MAX) // If moisture is below 60% of max
kaiserhaz 0:7dce5e74ad91 208 {
kaiserhaz 0:7dce5e74ad91 209 printf("\r\n> MAIN : Activating water pump.");
kaiserhaz 0:7dce5e74ad91 210 pumpPWM.write(1); // Activate pump
kaiserhaz 0:7dce5e74ad91 211 pumpCount = 0;
kaiserhaz 0:7dce5e74ad91 212 while((getMoistureValue()<0.75*GB_SOIL_MOISTURE_MAX)&&(pumpCount<40)) // Activate for 20s or until 75% max moisture
kaiserhaz 0:7dce5e74ad91 213 {
kaiserhaz 0:7dce5e74ad91 214 wait(0.5);
kaiserhaz 0:7dce5e74ad91 215 pumpCount++;
kaiserhaz 0:7dce5e74ad91 216 }
kaiserhaz 0:7dce5e74ad91 217 pumpPWM.write(0);
kaiserhaz 0:7dce5e74ad91 218 }
kaiserhaz 0:7dce5e74ad91 219 }
kaiserhaz 0:7dce5e74ad91 220 else
kaiserhaz 0:7dce5e74ad91 221 ble.waitForEvent(); // Low power wait for event
kaiserhaz 0:7dce5e74ad91 222
kaiserhaz 0:7dce5e74ad91 223 }
kaiserhaz 0:7dce5e74ad91 224 }