diff --git a/Part2_Central_board/Firmware/CentralUnit/CentralUnit.ino b/Part2_Central_board/Firmware/CentralUnit/CentralUnit.ino index 1a51330..c22eebc 100644 --- a/Part2_Central_board/Firmware/CentralUnit/CentralUnit.ino +++ b/Part2_Central_board/Firmware/CentralUnit/CentralUnit.ino @@ -13,6 +13,9 @@ int WiFi_status = WL_IDLE_STATUS; volatile uint32_t nFlowSensorCount = 0; volatile uint32_t nFlowSensorCount_last = 0; +char dbgBuff[4024] = {0}; +uint32_t dbgBuffPos = 0; + void IRAM_ATTR ISR_flowSensor() { nFlowSensorCount++; } @@ -61,7 +64,20 @@ void setup() setupWebServer(); server.begin(); - attachInterrupt(FLOW_SENSOR_PIN, ISR_flowSensor, FALLING); + flowInterruptEnabled(true); +} + + +void flowInterruptEnabled(bool state) +{ + if(state) + { + attachInterrupt(FLOW_SENSOR_PIN, ISR_flowSensor, FALLING); + } + else + { + detachInterrupt(FLOW_SENSOR_PIN); + } } @@ -259,3 +275,16 @@ void setupWebServer(void) }); } + +void LED_Blink(uint8_t nTimes, uint16_t n_delayPeriod) +{ + while(nTimes--) + { + digitalWrite(LED_PIN, HIGH); + delay(n_delayPeriod); + + digitalWrite(LED_PIN, LOW); + delay(n_delayPeriod); + } +} + diff --git a/Part2_Central_board/Firmware/CentralUnit/PlantSystem_MainLogic.ino b/Part2_Central_board/Firmware/CentralUnit/PlantSystem_MainLogic.ino index 2a6b096..312140b 100644 --- a/Part2_Central_board/Firmware/CentralUnit/PlantSystem_MainLogic.ino +++ b/Part2_Central_board/Firmware/CentralUnit/PlantSystem_MainLogic.ino @@ -42,7 +42,7 @@ uint8_t gnSolenoidsOnBusCnt = 0; // Plant watering definitions #define WATERING_VOLUME_MINIMUM 10 #define WATERING_VOLUME_MAXIMUM 550 -#define WATERING_FLOW_EDGES_PER_ML 4 +#define WATERING_FLOW_EDGES_PER_L 5880 //98 // PlantSystem_tick periods #define PERIOD_RESCAN_BUS 24*3600*1000 // Every 24h @@ -66,6 +66,7 @@ uint32_t nTimeout = 0; void PlantSystem_tick(void) { + bool bWateringError = false; esp_task_wdt_reset(); // -- Rescan I2C bus @@ -124,15 +125,23 @@ void PlantSystem_tick(void) // -- Process watering request if(bWatering_requestPending || bWatering_inProgress) { + // Watering logic + // Pump creates high pressure inside watering system. Because of this + // at the beginning of watering process we will first, open valve, then turn on pump. + // When we are done, we will first turn off pump and then solenoid. + // + // In previous version, water pump was too weak so we turned on the pump first to keep the pressure on + // and prevent water from "backing up" (i.e letting air in from plant side). + // With peristaltic pump we can open the solenoids first and still keep air out of the system. + // + Serial.println("bWatering_requestPending | bWatering_inProgress"); // Transition to in progress bWatering_inProgress = true; bWatering_requestPending = false; + nFlowSensorCount = 0; - // Note: Solenoid address and volume must have been validated - Serial.println("Turning pump ON"); - digitalWrite(WATER_PUMP_EN_PIN, HIGH); - delay(200); + // - Open solenoid Serial.println("Energizing solenoid"); if (PlantSystem_SetSolenoidState(nWatering_i2cAddress, true) != true) { @@ -141,33 +150,83 @@ void PlantSystem_tick(void) digitalWrite(WATER_PUMP_EN_PIN, LOW); Serial.println("Turning pump OFF"); Serial.println("Failed to open solenoid. Aborting..."); + LED_Blink(4, 250); return; } + + // - Reset flow counter + nFlowSensorCount = 0; + nFlowSensorCount_last = 0; + flowInterruptEnabled(true); + + // - Turn ON pump + Serial.println("Turning pump ON"); + delay(200); + digitalWrite(WATER_PUMP_EN_PIN, HIGH); + esp_task_wdt_reset(); - nTimeout = millis() + 10000; - while(nFlowSensorCount < (WATERING_FLOW_EDGES_PER_ML*nWatering_volume)) + nTimeout = millis() + 10000; // 10sec time-out for watering + + // Calculate water flow + uint32_t nWaterFlow_millis_timestamp = millis(); + float flowRate = 0.0; + unsigned int flowMilliLitres =0; + unsigned long totalMilliLitres = 0; + + while(millis() < nTimeout) { - if(millis() > nTimeout) + if((millis() - nWaterFlow_millis_timestamp) > 1000) // Only process counters once per second { - break; + flowInterruptEnabled(false); + + nFlowSensorCount_last = nFlowSensorCount; + nFlowSensorCount = 0; + bWateringError = true; + + + flowRate = ((1000.0 / (millis() - nWaterFlow_millis_timestamp)) * nFlowSensorCount_last) / WATERING_FLOW_EDGES_PER_L; + flowMilliLitres = (flowRate / 60) * 1000; + totalMilliLitres += flowMilliLitres; + + if(totalMilliLitres >= nWatering_volume) + { + break; + } + + nWaterFlow_millis_timestamp = millis(); + esp_task_wdt_reset(); + flowInterruptEnabled(true); } } esp_task_wdt_reset(); - Serial.println("De-Energizing solenoid"); - PlantSystem_SetSolenoidState(nWatering_i2cAddress, false); - delay(200); + // - Turn OFF pump digitalWrite(WATER_PUMP_EN_PIN, LOW); Serial.println("Turning pump OFF"); + delay(200); + + // - Close solenoid + Serial.println("De-Energizing solenoid"); + PlantSystem_SetSolenoidState(nWatering_i2cAddress, false); + // Store last flow data and prepare for new request - nFlowSensorCount_last = nFlowSensorCount; + nFlowSensorCount_last = 0; nFlowSensorCount = 0; + nWatering_volume = 0; // Reset request bWatering_inProgress = false; bWatering_requestPending = false; + if(bWateringError) + { + LED_Blink(3, 250); + } + else + { + LED_Blink(2, 500); + } } @@ -610,10 +669,8 @@ void PlantSystem_RequestPrimeSystem(void) bool PlantSystem_PrimeSystemWithWater(void) { - // Turn ON Pump - Serial.println("Turning pump ON"); - digitalWrite(WATER_PUMP_EN_PIN, HIGH); - delay(1000); + + bool bSolenoidOpen = false; // Turn ON all solenoids Serial.println("Energizing ALL solenoids"); @@ -623,6 +680,7 @@ bool PlantSystem_PrimeSystemWithWater(void) { Serial.print("Openned solenoid 0x"); Serial.println(gSolenoidsOnBus[i].i2cAddress, HEX); + bSolenoidOpen = true; } else { @@ -630,11 +688,25 @@ bool PlantSystem_PrimeSystemWithWater(void) Serial.println(gSolenoidsOnBus[i].i2cAddress, HEX); } delay(500); + + // Only turn on pump AFTER solenoid has oppened + if(bSolenoidOpen) + { + // Turn ON Pump + Serial.println("Turning pump ON"); + digitalWrite(WATER_PUMP_EN_PIN, HIGH); + delay(1000); + } } // Let the water flow for a while delay(5000); + // Turn OFF pump + delay(1000); + Serial.println("Turning pump OFF"); + digitalWrite(WATER_PUMP_EN_PIN, LOW); + // Turn OFF all solenoids Serial.println("De-energizing ALL solenoids"); for(uint8_t i=0; i