I started to show delay removal in the functions that were called from nested positions in other functions but most of the code is like that.
For example, ControlWateringSystem() gets called by void loop(), can use millis timing.
But CaptureSoilMoistureSetpoint(), SoilMoisture() and WaterPlant() can't, so they have delays.
void ControlWateringSystem()
{
CaptureSoilMoistureSetpoint();//checks for button press, if yes debounces and waters plant
if (currentMillis - soilMillis >= soilCycle) //if it has been 12 hours since the soil humidity has been measured
{
if (SoilMoisture() < soilMoistureSetpoint)//and if soil moisture is too low
{
WaterPlant();
}
soilMillis = currentMillis; //reset soil timer
}
}
int SoilMoisture()
{
digitalWrite(soilPinD, HIGH);
delay(25);
int soilReading = analogRead(soilPinA);
digitalWrite(soilPinD, LOW);
return soilReading;
}
void CaptureSoilMoistureSetpoint()
{
for (int x = 0; digitalRead(soilCapButPin); x++)
{
if (x = 50)
{
soilMoistureSetpoint = SoilMoisture();
digitalWrite(soilCapIndPin, HIGH);
delay(1000 * 3);
digitalWrite(soilCapIndPin, LOW);
WaterPlant();
}
}
}
void WaterPlant()
{
digitalWrite(solenoidPin, HIGH); //|
delay(1000 * 20); //// water the plant
digitalWrite(solenoidPin, LOW); ///
}
CaptureSoilMoistureSetpoint(), SoilMoisture() and WaterPlant() need to run in void loop().
The sensor readers should have associated global int variables that they update whenever they run.
The sensor readers should run at regular times, like at least 10 seconds apart?
WaterPlant() should have an associated global byte or int variable, make as small as needed.
When another function sets that value > 0, water the plant perhaps as long as the value.
WaterPlant() can decrement or zero the variable to shut off, ANY function can trigger or stop WaterPlant().
WaterPlant() should run all the time. if ( doWater > 0 ) .....
Change ControlWateringSystem() to read the sensor variables instead of running the sensors.
Change ControlWateringSystem() to set the water variable instead of running WaterPlant().
Then -- all those parts can use millis timing to ditch the delays. There are more but if you see how using
variables to pass data and control between tasks running void loop() to break dependencies between
tasks, you can rearrange your own code. The sensors are free to read as often as they should, the water
can be shut off by a button/task and you have cycles left over to do 300 other things.
PS tips:
don't use an int where a byte would do.
you can time 250ms with 1 byte timers. 1 byte where unsigned long is most used.