cycle timer with four relays

Needs some help with some code. I’m trying to get four irrigation solenoids to run for so many seconds and off for 5 minutes as a repeat cycle timer.
I tried with these two bits of code I found but first one all the relays on at the same time.
Second code they will lap each other after an hour I think as 5 seconds on every 5 minutes. As the time off time is starts after first relay finishes not when they have all finished if that makes any sense.

Any one able to Help as I’ve been trying to work it out but my I have no idea about coding.
A big forward thanks for any help.

4_relay_untested.ino|attachment (3.44 KB)

_4_pump_start_up.ino (1.93 KB)

Any luck with this?

// These variables store the flash pattern
// and the current state of the LED

#define NUM_VALVES      4

const byte ledPin1 =  8;      // the number of the LED pin
const byte ledPin2 =  9;      // the number of the LED pin
const byte ledPin3 =  10;      // the number of the LED pin
const byte ledPin4 =   11;      // the number of the LED pin

typedef struct
{
    const byte      Pin;
    bool            State;
    unsigned long   Time;
    unsigned long   OnTime;
    unsigned long   OffTime;
    
}struct_ValveStruct;

struct_ValveStruct Valves[NUM_VALVES] = 
{
    {
        //LED 1
        .Pin = ledPin1,
        .State = false,
        .Time = 0,
        .OnTime = 500ul,
        .OffTime = 2000ul  
    },
    {
        //LED 2
        .Pin = ledPin2,
        .State = false,
        .Time = 0,
        .OnTime = 500ul,
        .OffTime = 2000ul  
    },
    {
        //LED 3
        .Pin = ledPin3,
        .State = false,
        .Time = 0,
        .OnTime = 500ul,
        .OffTime = 2000ul  
    },
    {
        //LED 4
        .Pin = ledPin4,
        .State = false,
        .Time = 0,
        .OnTime = 100ul,
        .OffTime = 2000ul  
    }
};

void setup()
{
    for( int i=0; i<NUM_VALVES; i++ )
    {
        pinMode( Valves[i].Pin, OUTPUT );
        Valves[i].Time = millis();
        
    }//for
        
}//setup


void SolenoidStateMachine( void )
{
    static byte
        ValveIdx = 0;
    unsigned long
        timeNow;

    timeNow = millis();
    switch( Valves[ValveIdx].State )
    {
        case    false:
            if( (timeNow - Valves[ValveIdx].Time) >= Valves[ValveIdx].OffTime )
            {
                Valves[ValveIdx].Time = millis();
                Valves[ValveIdx].State = true;
                digitalWrite( Valves[ValveIdx].Pin, HIGH );
            }//if
            
        break;

        case    true:
            if( (timeNow - Valves[ValveIdx].Time) >= Valves[ValveIdx].OnTime )
            {
                Valves[ValveIdx].Time = millis();
                Valves[ValveIdx].State = false;
                digitalWrite( Valves[ValveIdx].Pin, LOW );
            }//if
        break;
    
    }//switch

    ValveIdx++;
    if( ValveIdx > NUM_VALVES )
        ValveIdx = 0;
        
}//SolenoidStateMachine

void loop()
{
    SolenoidStateMachine();
    
}//loop

Thanks for your reply today. I’ve tried your code and changed the times. But i need led1 to run for 5 seconds then off for 30 seconds, then led2 for set time of 5 seconds also off for 30 seconds then led3 so on.
At the moment they all come on at the same time not one after each other.
Big Thanks again

cycle_timer.ino (2.28 KB)

To be clear it needs to be led1 5 seconds on,
led2 on for 5 seconds led3 on for 5 then led4 on for 5 seconds.
With a 30 second off time between cycles.

Better?

// These variables store the flash pattern
// and the current state of the LED

#define NUM_VALVES      4

const byte ledPin1 =  8;      // the number of the LED pin
const byte ledPin2 =  9;      // the number of the LED pin
const byte ledPin3 =  10;      // the number of the LED pin
const byte ledPin4 =   11;      // the number of the LED pin

typedef struct
{
    const byte      Pin;
    bool            State;
    unsigned long   Time;
    unsigned long   OnTime;
    unsigned long   OffTime;
    
}struct_ValveStruct;

struct_ValveStruct Valves[NUM_VALVES] = 
{
    {
        //LED 1
        .Pin = ledPin1,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 30000ul  
    },
    {
        //LED 2
        .Pin = ledPin2,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 30000ul  
    },
    {
        //LED 3
        .Pin = ledPin3,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 30000ul  
    },
    {
        //LED 4
        .Pin = ledPin4,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 30000ul  
    }
};

void setup()
{
    for( int i=0; i<NUM_VALVES; i++ )
        pinMode( Valves[i].Pin, OUTPUT );

    //turn on valve 1 to start
    Valves[0].State = true;
    Valves[0].Time = millis();
    digitalWrite( Valves[0].Pin, HIGH );

}//setup


void SolenoidStateMachine( void )
{
    static byte
        ValveIdx = 0;
    unsigned long
        timeNow;

    timeNow = millis();
    switch( Valves[ValveIdx].State )
    {
        case    true:
            if( (timeNow - Valves[ValveIdx].Time) >= Valves[ValveIdx].OnTime )
            {
                Valves[ValveIdx].Time = millis();
                Valves[ValveIdx].State = false;
                digitalWrite( Valves[ValveIdx].Pin, LOW );

            }//if
        break;
        
        case    false:
            if( (timeNow - Valves[ValveIdx].Time) >= Valves[ValveIdx].OffTime )
            {
                ValveIdx++;
                if( ValveIdx > NUM_VALVES )
                    ValveIdx = 0;            
                //
                Valves[ValveIdx].Time = millis();
                Valves[ValveIdx].State = true;
                digitalWrite( Valves[ValveIdx].Pin, HIGH );
                                
            }//if
            
        break;
    
    }//switch
        
}//SolenoidStateMachine

void loop()
{
    SolenoidStateMachine();
    
}//loop

Great work Black Fin :slight_smile: If i wanted them to run one after each other then the 30 Second break how do i change that.
Thanks for your time

If I understand you correctly, you want #1 to fire for 5-sec, switch off and #2 to turn on immediately for 5-sec etc, and at the end of #4's on-time, wait 30-sec?

If so, just change the OffTime value for the first 3 in the structure from 30000ul to 0 whille leaving #4's at 30000ul:

struct_ValveStruct Valves[NUM_VALVES] = 
{
    {
        //LED 1
        .Pin = ledPin1,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 0  
    },
    {
        //LED 2
        .Pin = ledPin2,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 0  
    },
    {
        //LED 3
        .Pin = ledPin3,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 0  
    },
    {
        //LED 4
        .Pin = ledPin4,
        .State = false,
        .Time = 0,
        .OnTime = 5000ul,
        .OffTime = 30000ul  
    }
};

Thanks works perfectly
I hope someone else finds this helpful.
Thanks Black Fin