![](/media/cache/group/I3S.png.50x50_q85.jpg)
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
This branch is the main continuation of the original project. You can find it here.
Diff: main.cpp
- Revision:
- 5:9d68ed883e95
- Parent:
- 3:c460d60ffda6
- Child:
- 6:35d615722597
--- a/main.cpp Thu Dec 01 08:28:55 2016 +0000 +++ b/main.cpp Fri Dec 02 17:36:56 2016 +0000 @@ -6,9 +6,6 @@ * Authored by * Dien Hoa Truong * Muhammad Haziq Bin Kamarul Azman - * - * for the - * eSAME 2016 STM32NUCLEO IoT Contest in Sophia-Antipolis * * main.cpp | Program main * @@ -24,46 +21,50 @@ /** Defines **/ #define GB_SOIL_MOISTURE_MAX 70 // Soil moisture threshold value +#define GB_USERS_CONNECTED_MAX 4 // Maximum connected users +#define GB_PUMP_CYCLE_MAX 40 // Maximum pump cycle allowed /** Device declarations **/ // Board-specific -PwmOut pumpPWM(PC_8); // PWM motor control out pin +PwmOut pumpPWM(PC_8); // PWM motor control out pin DigitalOut led1(LED1, 1); // Debug pin instance -AnalogIn moisture_sensor(PB_1); // Moisture sensor +AnalogIn moisture_sensor(PB_1); // Moisture sensor static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15); // Expansion board instance -static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor; // Expansion board humidity sensor instance -static TempSensor *temp_sensor = mems_expansion_board->ht_sensor; // Expansion board temperature sensor instance +static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor; // Expansion board humidity sensor instance +static TempSensor *temp_sensor = mems_expansion_board->ht_sensor; // Expansion board temperature sensor instance // BLE-specific BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); // BLE device instance const static char DEVICE_NAME[] = "GB-Sensor"; // Device name -static const uint16_t uuid16_list[] = {GreenBuildingService::UUID_GREEN_BUILDING_SERVICE}; +static const uint16_t uuid16_list[] = {GreenBuildingService::UUID_GREEN_BUILDING_SERVICE}; // UUID service list GreenBuildingService *gbServicePtr; // Service pointer +//Gap::Handle_t bleConnectionHandles[GB_USERS_CONNECTED_MAX]; // Connection handle tables // Program-specific float getMoistureValue(); float getHumidityValue(); float getTemperatureValue(); -void errorLoop(void); -void activateFastSensorPoll(); -void deactivateFastSensorPoll(); -void pumpActivateCallback(void); -void pumpDeactivateCallback(void); +void errorLoop(void); +void activateFastSensorPoll(); +void deactivateFastSensorPoll(); +void pumpActivateCallback(void); +void pumpDeactivateCallback(void); -Ticker sanityTicker; -Ticker sensorPollTicker; -Ticker fastSensorPollTicker; +Ticker sanityTicker; +Ticker sensorPollTicker; +Ticker fastSensorPollTicker; Timeout pumpWaitTimeout; + +uint8_t pumpWaitTime = 3; // Pump waiting time uint8_t usersConnected; -bool sensorPolling; -bool fastSensorPolling; -bool pumpActivate; -bool waitOnce; -bool bleActive; -bool pumpActive; +bool sensorPolling; +bool fastSensorPolling; +bool bleActive; +bool pumpActive; + /** Callbacks **/ @@ -76,21 +77,22 @@ deactivateFastSensorPoll(); bleActive = false; --usersConnected; -// printf("\r\n> BLE : Disconnected. Advertising restarted."); } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) // Callback for everytime the connection is established { - ble.gap().stopAdvertising(); // Stop advertising - activateFastSensorPoll(); - bleActive = true; - ++usersConnected; -// printf("\r\n> BLE : Connected to %x. Accept no subsequent connections.", params->peerAddr); + if(usersConnected>GB_USERS_CONNECTED_MAX) + ble.disconnect(params->handle, Gap::REMOTE_USER_TERMINATED_CONNECTION); // Disconnect automatically due to connection constraint + else + { + activateFastSensorPoll(); + bleActive = true; + ++usersConnected; + } } void onBleInitError(BLE &ble, ble_error_t error) { -// printf("\r\n> BLE : Init error encountered. Error returned: %d", error); errorLoop(); } @@ -105,7 +107,6 @@ } if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { // If this is not default instance (double instanciation?) -// printf("\r\n> BLE : BLE controller instance is invalid."); errorLoop(); } @@ -121,8 +122,6 @@ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setAdvertisingInterval(1000); /* 1000ms */ ble.gap().startAdvertising(); - -// printf("\r\n> BLE : BLE Init done."); } // Helper functions for retrieving data from sensors @@ -169,20 +168,10 @@ fastSensorPolling = true; } -void pumpActivateCallback(void) -{ - pumpActivate = true; -} - -void pumpDeactivateCallback(void) -{ - pumpActivate = false; -} - void activateFastSensorPoll(void) { fastSensorPolling = true; - fastSensorPollTicker.attach(&fastSensorPollCallback, 0.9); + fastSensorPollTicker.attach(&fastSensorPollCallback, 0.9f); } void deactivateFastSensorPoll(void) @@ -191,16 +180,32 @@ fastSensorPollTicker.detach(); } +void pumpSetup(void) +{ + pumpPWM.write(1); + pumpPWM.period(2.0f); +} + +void pumpActivateCallback(void) +{ + pumpPWM.write(0.7); +} + +void pumpDeactivateCallback(void) +{ + pumpPWM.write(1); +} void errorLoop(void) { sanityTicker.detach(); sensorPollTicker.detach(); ble.shutdown(); -// printf("\r\n> ERROR : Error encountered. Infinite looping."); + while(true) { - led1 != led1; + led1 != led1; + printf("\n\n\n\n\n\n\n\n"); } } @@ -213,31 +218,22 @@ /** Main loop **/ int main(void) { - pumpPWM.write(1); - pumpPWM.period(1.0f); + pumpSetup(); // Setup pump - printf("\r\n/**\r\n * Green Building Sensor Device: Debug Info\r\n */"); - - sensorPolling = false; + sensorPolling = false; fastSensorPolling = false; - pumpActivate = false; - waitOnce = true; - bleActive = false; - pumpActive = false; + bleActive = false; + pumpActive = false; - sanityTicker.attach(sanityCallback, 1.1); // LED sanity checker - sensorPollTicker.attach(sensorPollCallback, 4.9); // Sensor poll ticker - - printf("\r\n> MAIN : Tickers initialized."); + sanityTicker.attach(sanityCallback, 1.1f); // LED sanity checker + sensorPollTicker.attach(sensorPollCallback, 3559.9f); // Sensor poll ticker (1 hr too long?) volatile GreenBuildingService::PlantEnvironmentType_t peVal; // Plant environment var - uint8_t pumpWaitTime = 3; // Pump waiting time + uint8_t pumpLimitCount = 0; // Pump limit counter ble.init(bleInitComplete); // Pass BLE init complete function upon init -// while(ble.hasInitialized() == false); - - printf("\r\n> MAIN : BLE Init procedure done."); +// while(ble.hasInitialized() == false); // Buggy loop // Infinite loop while (true) { @@ -254,42 +250,41 @@ if(ble.getGapState().connected) // Update characteristic if connected gbServicePtr->updatePlantEnvironment(peVal); -// printf("\r\n> MAIN : Current soil moisture = %d", peVal.soilMoisture); -// printf("\r\n> MAIN : Current air humidity = %d", peVal.airHumidity); -// printf("\r\n> MAIN : Current air temperature = %d", peVal.airTemperature); printf("%d\t%d\t%d\r\n", peVal.airTemperature, peVal.airHumidity, peVal.soilMoisture); // If moisture is below 50% of max when user is present // or if less than 30% of max + // and pump is not active if( ( ((peVal.soilMoisture < 0.5*GB_SOIL_MOISTURE_MAX) && ble.getGapState().connected) || - ((peVal.soilMoisture < 0.3*GB_SOIL_MOISTURE_MAX) && !ble.getGapState().connected) ) && - waitOnce + ((peVal.soilMoisture < 0.3*GB_SOIL_MOISTURE_MAX) && !ble.getGapState().connected) && + !pumpActive + ) ) { - pumpWaitTimeout.attach(&pumpActivateCallback, pumpWaitTime); // Waiting time is hard coded but may be calculated, I think activateFastSensorPoll(); - waitOnce = false; pumpActive = true; - } - else if((peVal.soilMoisture >= 0.6*GB_SOIL_MOISTURE_MAX) && pumpActivate) // Stop condition: when soil moisture is at 60% of max - { - pumpPWM.write(1); - pumpWaitTimeout.detach(); - pumpDeactivateCallback(); - if(!bleActive) - deactivateFastSensorPoll(); - waitOnce = true; - pumpActive = false; + // TODO: calculate pumpWaitTime ( pumpWaitTime = f(peVal.airHumidity, peVal.airTemperature) ) + pumpWaitTimeout.attach(&pumpActivateCallback, pumpWaitTime); } - if(pumpActivate) + // Stop condition: when soil moisture is at 60% of max or after few pump cycles + if(pumpActive) { -// printf("\r\n> MAIN : Activating water pump."); - pumpPWM.write(0.7); - pumpActivate = false; - pumpWaitTimeout.attach(&pumpActivateCallback, 1); + ++pumpLimitCount; + + if( (peVal.soilMoisture >= 0.6*GB_SOIL_MOISTURE_MAX) || + (pumpLimitCount>GB_PUMP_CYCLE_MAX) + ) + { + pumpWaitTimeout.detach(); + pumpDeactivateCallback(); + pumpActive = false; // Something not right here... + if(!bleActive) + deactivateFastSensorPoll(); + } } + } else ble.waitForEvent(); //Low power wait for event