RTC + arduino to operate 3 valves in 24hours

// The idea of this project is to open 3 valves one after the other for 5 minutes each, at a time like 7am, 12pm, 4pm in a day.
// The for loop should be executed at 7am, where valve 1 is open and water is pumped for 5minutes, then valve 1 closes and valve 2 runs for 5 minutes, then valve 3 opens and runs for 5 minutes.
// the program comes to a stop. now at 12pm, the same cycle or process repeats for the 3 valves.
// Any expert help ??

#include <SoftwareSerial.h>
#include <DS3231.h>

// intialise Valves for Each Vegetation Bed

int valvePorts[] = { 4,5,6};
int valveCount= 3;

DS3231 rtc(SDA, SCL);
Time t;
const int OnHourOne = 12; // assuming that one Tank- valve takes 5minutes each
const int OnMinOne = 00;
const int OffHourOne = 12;
const int OffMinOne = 30;

const int OnHourTwo = 16;
const int OnMinTwo = 00;
const int OffHourTwo = 16;
const int OffMinTwo = 30;

void setup()
{

for( int thisvalve=0; thisvalve =<valveCount; thisvalve++) {
pinMode(valvePorts[thisvalve], OUTPUT);

}
pinMode(Waterpump,OUTPUT); // Waterpump
Serial.begin(9600);
}

void loop()
{

t = rtc.getTime();
Serial.print(t.hour);
Serial.print(" hour(s), ");
Serial.print(t.min);
Serial.print(" minute(s)");
Serial.println(" ");
delay (1000);

if(t.hour == OnHour && t.min == OnMin){
Startwatering(1);

}

else if(t.hour == OffHour && t.min == OffMin){
Startwatering(0);

}

void Startwatering(int id) {

if( id== 0)
{
return;
}

while(valvePorts[thisvalve],HIGH)
{

for( int thisvalve=0; thisvalve =<valveCount; thisvalve++)
pinMode(valvePorts[thisvalve], OUTPUT);

{
digitalWrite(Waterpump,LOW);
delay(5000)
}

}// close while loop

} // close for loop

this library may make things easier for you...

A simple state machine with millis() timer would do the trick. Here's an outline:

const unsigned long wateringDuration = 5 * 60 * 1000UL;
unsigned long wateringTimer;
const uint8_t valveCount = 3;
uint8_t valveNumber;

enum machineStates {WAITING, WATERING};
machineStates currentState = WAITING;

void loop() {
  switch (currentState) {
    case WAITING:
      if (RTC says it's time to start watering) {
        valveNumber = 0;
        digitalWrite(valvePorts[valveNumber], HIGH);  // Assuming HIGH opens valve, otherwise change to LOW
        wateringTimer = millis();
        currentState = WATERING;
      }
      break;

    case WATERING:
      if (millis() - wateringTimer > wateringDuration) {
        digitalWrite(valvePorts[valveNumber++], LOW);    // Assuming LOW closes valve, otherwise change to HIGH
        if (valveNumber < valveCount) {
          digitalWrite(valvePorts[valveNumber], HIGH);  // Assuming HIGH opens valve, otherwise change to LOW
          wateringTimer = millis();
        } else {
          currentState = WAITING;
        }
      }
      break;

    default:
      break;
  }
}

With only two states, ‘if / else’ structure would work as well as ‘switch / case’. But, this way nicely emphasizes the state machine structure. And, other states can be easily added if your application becomes more complex.

gfvalvo:
A simple state machine with millis() timer would do the trick.

Until the power cycles.

The system needs to be set up so valves close upon power failure. When power returns, setup() should start over in the WAITIG state with valves closed. Then the worse consequence of power failure will be a prematurely aborted watering cycle - plus those cycles missed between the power failure and start of the next cycle following power restoration.