mirror of
https://github.com/SasaKaranovic/HousePlantMonitoringSystem.git
synced 2026-07-08 17:52:37 +02:00
Initial commit
This commit is contained in:
@@ -13,6 +13,9 @@ int WiFi_status = WL_IDLE_STATUS;
|
|||||||
volatile uint32_t nFlowSensorCount = 0;
|
volatile uint32_t nFlowSensorCount = 0;
|
||||||
volatile uint32_t nFlowSensorCount_last = 0;
|
volatile uint32_t nFlowSensorCount_last = 0;
|
||||||
|
|
||||||
|
char dbgBuff[4024] = {0};
|
||||||
|
uint32_t dbgBuffPos = 0;
|
||||||
|
|
||||||
void IRAM_ATTR ISR_flowSensor() {
|
void IRAM_ATTR ISR_flowSensor() {
|
||||||
nFlowSensorCount++;
|
nFlowSensorCount++;
|
||||||
}
|
}
|
||||||
@@ -61,7 +64,20 @@ void setup()
|
|||||||
setupWebServer();
|
setupWebServer();
|
||||||
server.begin();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ uint8_t gnSolenoidsOnBusCnt = 0;
|
|||||||
// Plant watering definitions
|
// Plant watering definitions
|
||||||
#define WATERING_VOLUME_MINIMUM 10
|
#define WATERING_VOLUME_MINIMUM 10
|
||||||
#define WATERING_VOLUME_MAXIMUM 550
|
#define WATERING_VOLUME_MAXIMUM 550
|
||||||
#define WATERING_FLOW_EDGES_PER_ML 4
|
#define WATERING_FLOW_EDGES_PER_L 5880 //98
|
||||||
|
|
||||||
// PlantSystem_tick periods
|
// PlantSystem_tick periods
|
||||||
#define PERIOD_RESCAN_BUS 24*3600*1000 // Every 24h
|
#define PERIOD_RESCAN_BUS 24*3600*1000 // Every 24h
|
||||||
@@ -66,6 +66,7 @@ uint32_t nTimeout = 0;
|
|||||||
|
|
||||||
void PlantSystem_tick(void)
|
void PlantSystem_tick(void)
|
||||||
{
|
{
|
||||||
|
bool bWateringError = false;
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
// -- Rescan I2C bus
|
// -- Rescan I2C bus
|
||||||
@@ -124,15 +125,23 @@ void PlantSystem_tick(void)
|
|||||||
// -- Process watering request
|
// -- Process watering request
|
||||||
if(bWatering_requestPending || bWatering_inProgress)
|
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");
|
Serial.println("bWatering_requestPending | bWatering_inProgress");
|
||||||
// Transition to in progress
|
// Transition to in progress
|
||||||
bWatering_inProgress = true;
|
bWatering_inProgress = true;
|
||||||
bWatering_requestPending = false;
|
bWatering_requestPending = false;
|
||||||
|
nFlowSensorCount = 0;
|
||||||
|
|
||||||
// Note: Solenoid address and volume must have been validated
|
// - Open solenoid
|
||||||
Serial.println("Turning pump ON");
|
|
||||||
digitalWrite(WATER_PUMP_EN_PIN, HIGH);
|
|
||||||
delay(200);
|
|
||||||
Serial.println("Energizing solenoid");
|
Serial.println("Energizing solenoid");
|
||||||
if (PlantSystem_SetSolenoidState(nWatering_i2cAddress, true) != true)
|
if (PlantSystem_SetSolenoidState(nWatering_i2cAddress, true) != true)
|
||||||
{
|
{
|
||||||
@@ -141,33 +150,83 @@ void PlantSystem_tick(void)
|
|||||||
digitalWrite(WATER_PUMP_EN_PIN, LOW);
|
digitalWrite(WATER_PUMP_EN_PIN, LOW);
|
||||||
Serial.println("Turning pump OFF");
|
Serial.println("Turning pump OFF");
|
||||||
Serial.println("Failed to open solenoid. Aborting...");
|
Serial.println("Failed to open solenoid. Aborting...");
|
||||||
|
LED_Blink(4, 250);
|
||||||
return;
|
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();
|
esp_task_wdt_reset();
|
||||||
nTimeout = millis() + 10000;
|
nTimeout = millis() + 10000; // 10sec time-out for watering
|
||||||
while(nFlowSensorCount < (WATERING_FLOW_EDGES_PER_ML*nWatering_volume))
|
|
||||||
|
// 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();
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
Serial.println("De-Energizing solenoid");
|
// - Turn OFF pump
|
||||||
PlantSystem_SetSolenoidState(nWatering_i2cAddress, false);
|
|
||||||
delay(200);
|
|
||||||
digitalWrite(WATER_PUMP_EN_PIN, LOW);
|
digitalWrite(WATER_PUMP_EN_PIN, LOW);
|
||||||
Serial.println("Turning pump OFF");
|
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
|
// Store last flow data and prepare for new request
|
||||||
nFlowSensorCount_last = nFlowSensorCount;
|
nFlowSensorCount_last = 0;
|
||||||
nFlowSensorCount = 0;
|
nFlowSensorCount = 0;
|
||||||
|
nWatering_volume = 0;
|
||||||
|
|
||||||
// Reset request
|
// Reset request
|
||||||
bWatering_inProgress = false;
|
bWatering_inProgress = false;
|
||||||
bWatering_requestPending = 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)
|
bool PlantSystem_PrimeSystemWithWater(void)
|
||||||
{
|
{
|
||||||
// Turn ON Pump
|
|
||||||
Serial.println("Turning pump ON");
|
bool bSolenoidOpen = false;
|
||||||
digitalWrite(WATER_PUMP_EN_PIN, HIGH);
|
|
||||||
delay(1000);
|
|
||||||
|
|
||||||
// Turn ON all solenoids
|
// Turn ON all solenoids
|
||||||
Serial.println("Energizing ALL solenoids");
|
Serial.println("Energizing ALL solenoids");
|
||||||
@@ -623,6 +680,7 @@ bool PlantSystem_PrimeSystemWithWater(void)
|
|||||||
{
|
{
|
||||||
Serial.print("Openned solenoid 0x");
|
Serial.print("Openned solenoid 0x");
|
||||||
Serial.println(gSolenoidsOnBus[i].i2cAddress, HEX);
|
Serial.println(gSolenoidsOnBus[i].i2cAddress, HEX);
|
||||||
|
bSolenoidOpen = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -630,11 +688,25 @@ bool PlantSystem_PrimeSystemWithWater(void)
|
|||||||
Serial.println(gSolenoidsOnBus[i].i2cAddress, HEX);
|
Serial.println(gSolenoidsOnBus[i].i2cAddress, HEX);
|
||||||
}
|
}
|
||||||
delay(500);
|
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
|
// Let the water flow for a while
|
||||||
delay(5000);
|
delay(5000);
|
||||||
|
|
||||||
|
// Turn OFF pump
|
||||||
|
delay(1000);
|
||||||
|
Serial.println("Turning pump OFF");
|
||||||
|
digitalWrite(WATER_PUMP_EN_PIN, LOW);
|
||||||
|
|
||||||
// Turn OFF all solenoids
|
// Turn OFF all solenoids
|
||||||
Serial.println("De-energizing ALL solenoids");
|
Serial.println("De-energizing ALL solenoids");
|
||||||
for(uint8_t i=0; i<gnSolenoidsOnBusCnt; i++)
|
for(uint8_t i=0; i<gnSolenoidsOnBusCnt; i++)
|
||||||
@@ -653,11 +725,6 @@ bool PlantSystem_PrimeSystemWithWater(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Turn OFF pump
|
|
||||||
delay(1000);
|
|
||||||
Serial.println("Turning pump OFF");
|
|
||||||
digitalWrite(WATER_PUMP_EN_PIN, LOW);
|
|
||||||
|
|
||||||
nFlowSensorCount = 0;
|
nFlowSensorCount = 0;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user