help me with a cycle timer

I have a program that works fine, it's set to start over every two weeks, my question is haw do build a cycle counter into it, so that in cycle 1 it does y and cycle2 x

here is the code I have, what I want to do is have everything that says flush happen after cycle 2

 //  Some macros for defining time intervals in milliseconds
#define seconds_in_ms(s) ((s)*1000UL)
#define minutes_in_ms(m) ((m)*60UL*1000UL)
#define hours_in_ms(h)   ((h)*60UL*60UL*1000UL)
#define days_in_ms(d)    ((d)*24UL*60UL*60UL*1000UL)
#define weeks_in_ms(w)   ((w)*7UL*24UL*60UL*60UL*1000UL)

unsigned long CycleStartTime = 0;
unsigned long LastTaskTime = 0;
unsigned long CurrentTaskInterval = 0;
unsigned Task = 0;
 

void setup() {
 

   pinMode(2, OUTPUT);   //PH down
   pinMode(3, OUTPUT);  //B nutrient solution
   pinMode(4, OUTPUT);  //A nutrient solution
   pinMode(5, OUTPUT);  //Drain pump
   pinMode(6, OUTPUT);   //Solenoid Valve
   pinMode(7, OUTPUT);  //Nutrient Heater

  digitalWrite(2, HIGH);     //PH down off
  digitalWrite(3, HIGH);  //B nutrient solution off
  digitalWrite(4, HIGH);  //A nutrient solution off
  digitalWrite(5, HIGH);  //Drain pump off
  digitalWrite(6, HIGH);   //Solenoid Valve off
  digitalWrite(7, HIGH);  //Nutrient Heater off
}
  
void loop() {


  unsigned long currentTime = millis();

  // If the time has not yet come to perform a task
  if (currentTime - LastTaskTime < CurrentTaskInterval)
    return;   // Nothing to do

  LastTaskTime = currentTime;

  switch (Task++)
  {
  case 0:
    CycleStartTime = currentTime;  // Remember this time

   digitalWrite(5,LOW);   // set the drain pump on flush
    
    CurrentTaskInterval = minutes_in_ms(17);
    break;
    
  case 1:
    digitalWrite(5,HIGH);   // set the drain pump off flush
    digitalWrite(6,LOW); // set the Solenoid Valve on flush
    CurrentTaskInterval = minutes_in_ms(17);
 break;
 
 case 2:
    digitalWrite(6,HIGH); // set the Solenoid Valve off flush
    digitalWrite(7,LOW); // set the Nutrient Heater on flush
    CurrentTaskInterval = minutes_in_ms(10);
 break;
 
 case 3:
    digitalWrite(5,LOW);   // set the drain pump on
      digitalWrite(7,HIGH); // set the Nutrient Heater off
    CurrentTaskInterval = minutes_in_ms(17);
 break;

  case 4:
    digitalWrite(5,HIGH);   // set the drain pump off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(2,LOW);  // set the PH down on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = seconds_in_ms(10);
 break;
 

case 5:
    digitalWrite(2,HIGH);  // set the PH down off
    digitalWrite(6,LOW); // set the Solenoid Valve on 
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(6);

break;
 

case 6:
digitalWrite(3,HIGH); // set the B nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on
digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(5.04);


break;

case 7:
digitalWrite(4,HIGH); // set the A nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on

    CurrentTaskInterval = minutes_in_ms(5);


break;


case 8:
digitalWrite(6,HIGH); // set the Solenoid Valve off
digitalWrite(7,LOW); // set the Nutrient Heater on

CurrentTaskInterval = days_in_ms(1);

break;

case 9:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);

break;

case 10:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);

break;

case 11:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);

break;

case 12:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);

break;

case 13:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);

break;

case 14:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);

break;

case 15:
// Start over again in one week from the START of the cycle
    Task = 0;
    LastTaskTime = CycleStartTime;
    CurrentTaskInterval = weeks_in_ms(1);
    break;
  } 
}

What do you means by "cycle counter"?

If you are referring to each time is starts (is it powered off for two weeks?) then you can store a counter in EEPROM.


Rob

Most of those cases are the same, how about removing a heap of code

case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1); 
break;

Rob

"you can store a counter in EEPROM", I think that's what I need....not sure, basically this program runs from start to Finnish in about 2 weeks call it Cycle1 then starts over again, what I like to do is have small changes in Cycle2 3 ect. and no It doesn't power off unless there is a power outage.

Rob....getting rid of a whole heap of code, I'm all for that, not sure how to do that, the case 9-14 is the same it does a small task every day as you can see.

It doesn't power off

Then you just keep a counter variable, this assumes the power supply is reliable and the consequences of loosing count are not very high. If neither are the case then use EEPROM.

not sure how to do that

I just did it for you :)


Rob

Oh wow, so missed it, ya you did do it sry, thanks, and its so simple when you see it. now that "keep a counter variable thing", hmmm I'm thinking I need to edit and include a cycle time a hint would be nice?

ok I think i got it, or am i off base here
why not use a

int X=+1;

so every time it loops x grow 1 2 3 ect

then use an if then statement like if x >1 then

only thing I’m not sure of is if the time starts over this may reset too
and its probably written wrong since I’m lost here.

It's a nicely designed sketch.

As far as I can see, it carries out the sixteen tasks in sequence and then goes back to the first one. I assume this whole sequence is what you're referring to as a cycle.

If you want it to behave differently in some cycles, you could declare a variable (CycleCount, for example) just like you declared Task. The variable would be initialised to zero and incremented at the end of the last Task where you already set Task back to zero.

I'm not sure what difference you want to make but I think you're saying you want to skip tasks commented with 'flush' during the first cycle.

In that case, you could change it from

case 1:
    digitalWrite(5,HIGH);   // set the drain pump off flush
    digitalWrite(6,LOW); // set the Solenoid Valve on flush
    CurrentTaskInterval = minutes_in_ms(17);
 break;

to something like

case 1:
    if(CycleCount > 0)
    {
        digitalWrite(5,HIGH);   // set the drain pump off flush
        digitalWrite(6,LOW); // set the Solenoid Valve on flush
        CurrentTaskInterval = minutes_in_ms(17);
    }
    else
    {
        Task++;
        return;
    }
 break;

Then move this:

LastTaskTime = currentTime;

From before the switch, to after it. The idea being that you [u]don't[/u] update it in the 'skipped step' case, so you come back into the 'time to move to the next step' code next time loop() runs.

ok Peter H trying to do what you were saying not really working and I’m still a little lost.
here’s what i tried

  //  Some macros for defining time intervals in milliseconds
#define seconds_in_ms(s) ((s)*1000UL)
#define minutes_in_ms(m) ((m)*60UL*1000UL)
#define hours_in_ms(h)   ((h)*60UL*60UL*1000UL)
#define days_in_ms(d)    ((d)*24UL*60UL*60UL*1000UL)
#define weeks_in_ms(w)   ((w)*7UL*24UL*60UL*60UL*1000UL)

unsigned long CycleStartTime = 0;
unsigned long LastTaskTime = 0;
unsigned long CurrentTaskInterval = 0;
unsigned Task = 0;
 

void setup() {
 

   pinMode(2, OUTPUT);   //PH down
   pinMode(3, OUTPUT);  //B nutrient solution
   pinMode(4, OUTPUT);  //A nutrient solution
   pinMode(5, OUTPUT);  //Drain pump
   pinMode(6, OUTPUT);   //Solenoid Valve
   pinMode(7, OUTPUT);  //Nutrient Heater

  digitalWrite(2, HIGH);     //PH down off
  digitalWrite(3, HIGH);  //B nutrient solution off
  digitalWrite(4, HIGH);  //A nutrient solution off
  digitalWrite(5, HIGH);  //Drain pump off
  digitalWrite(6, HIGH);   //Solenoid Valve off
  digitalWrite(7, HIGH);  //Nutrient Heater off
}
  
void loop() {


  unsigned long currentTime = millis();

  // If the time has not yet come to perform a task
  if (currentTime - LastTaskTime < CurrentTaskInterval)
    return;   // Nothing to do


  switch (Task++)
  LastTaskTime = currentTime;
  {
  case 0:
  if(CycleCount > 0)
   {
    CycleStartTime = currentTime;  // Remember this time

   digitalWrite(5,LOW);   // set the drain pump on flush
    
    CurrentTaskInterval = minutes_in_ms(17);
    }
    else
    {
        Task++;
        return;
    }
    break;
    
  case 1:
   if(CycleCount > 0)
    {
    digitalWrite(5,HIGH);   // set the drain pump off flush
    digitalWrite(6,LOW); // set the Solenoid Valve on flush
    CurrentTaskInterval = minutes_in_ms(17);
    }
    else
    {
        Task++;
        return;
    }
 break;
 
 case 2:
 if(CycleCount > 0)
  {
    digitalWrite(6,HIGH); // set the Solenoid Valve off flush
    digitalWrite(7,LOW); // set the Nutrient Heater on flush
    CurrentTaskInterval = minutes_in_ms(10);
    }
    else
    {
        Task++;
        return;
    }
 break;
 
 case 3:
    digitalWrite(5,LOW);   // set the drain pump on
      digitalWrite(7,HIGH); // set the Nutrient Heater off
    CurrentTaskInterval = minutes_in_ms(17);
 break;

  case 4:
    digitalWrite(5,HIGH);   // set the drain pump off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(2,LOW);  // set the PH down on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = seconds_in_ms(10);
 break;
 

case 5:
    digitalWrite(2,HIGH);  // set the PH down off
    digitalWrite(6,LOW); // set the Solenoid Valve on 
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(6);

break;
 

case 6:
digitalWrite(3,HIGH); // set the B nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on
digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(5.04);


break;

case 7:
digitalWrite(4,HIGH); // set the A nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on

    CurrentTaskInterval = minutes_in_ms(5);


break;


case 8:
digitalWrite(6,HIGH); // set the Solenoid Valve off
digitalWrite(7,LOW); // set the Nutrient Heater on

CurrentTaskInterval = days_in_ms(1);

break;

case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1); 
break;

case 22:
// Start over again in one week from the START of the cycle
    Task = 0;
    LastTaskTime = CycleStartTime;
    CurrentTaskInterval = weeks_in_ms(1);
    break;
  } 
}

“skip tasks commented with ‘flush’ during the first cycle.”
yes that’s it 1st cycle, or loop, I want it in the 2,3,4 ect.

  switch (Task++)
  LastTaskTime = currentTime;
  {

Is that valid code? I assume you compiled it but I don't know what it will do.


Rob

is it valid code did i compile it
no its not valid, and won’t compile
Did I write it, here’s the funny part, that’s the only area of the program I never wrote myself
originally it went like this, and works fine, its bin running now for a year, so i never questioned it.

LastTaskTime = currentTime;

  switch (Task++)
  {

Tried to switch it around according to like what Peter H said and it wont compile now
but I’m not even sure what it does.

I see, he said

From before the switch, to after it.

Meaning before the switch block to after it. Eg.

switch (Task++) {
 // all the switch stuff
 }
 LastTaskTime = currentTime;

Rob

ok I’m still in space, maybe you can give me a hint to fix it, essentially all I just want is the stuff with flush in it to run after the 1st loop
here’s what I tried, this wont compile
got to move that switch Block thing

  //  Some macros for defining time intervals in milliseconds
#define seconds_in_ms(s) ((s)*1000UL)
#define minutes_in_ms(m) ((m)*60UL*1000UL)
#define hours_in_ms(h)   ((h)*60UL*60UL*1000UL)
#define days_in_ms(d)    ((d)*24UL*60UL*60UL*1000UL)
#define weeks_in_ms(w)   ((w)*7UL*24UL*60UL*60UL*1000UL)

unsigned long CycleStartTime = 0;
unsigned long LastTaskTime = 0;
unsigned long CurrentTaskInterval = 0;
unsigned Task = 0;
 

void setup() {
 

   pinMode(2, OUTPUT);   //PH down
   pinMode(3, OUTPUT);  //B nutrient solution
   pinMode(4, OUTPUT);  //A nutrient solution
   pinMode(5, OUTPUT);  //Drain pump
   pinMode(6, OUTPUT);   //Solenoid Valve
   pinMode(7, OUTPUT);  //Nutrient Heater

  digitalWrite(2, HIGH);     //PH down off
  digitalWrite(3, HIGH);  //B nutrient solution off
  digitalWrite(4, HIGH);  //A nutrient solution off
  digitalWrite(5, HIGH);  //Drain pump off
  digitalWrite(6, HIGH);   //Solenoid Valve off
  digitalWrite(7, HIGH);  //Nutrient Heater off
}
  
void loop() {


  unsigned long currentTime = millis();

  // If the time has not yet come to perform a task
  if (currentTime - LastTaskTime < CurrentTaskInterval)
    return;   // Nothing to do


  switch (Task++)
  LastTaskTime = currentTime;
  {
  case 0:
  if(CycleCount > 0)
   {
    CycleStartTime = currentTime;  // Remember this time

   digitalWrite(5,LOW);   // set the drain pump on flush
    
    CurrentTaskInterval = minutes_in_ms(17);
    }
    else
    {
        Task++;
        return;
    }
    break;
    
  case 1:
   if(CycleCount > 0)
    {
    digitalWrite(5,HIGH);   // set the drain pump off flush
    digitalWrite(6,LOW); // set the Solenoid Valve on flush
    CurrentTaskInterval = minutes_in_ms(17);
    }
    else
    {
        Task++;
        return;
    }
 break;
 
 case 2:
 if(CycleCount > 0)
  {
    digitalWrite(6,HIGH); // set the Solenoid Valve off flush
    digitalWrite(7,LOW); // set the Nutrient Heater on flush
    CurrentTaskInterval = minutes_in_ms(10);
    }
    else
    {
        Task++;
        return;
    }
 break;
 
 case 3:
    digitalWrite(5,LOW);   // set the drain pump on
      digitalWrite(7,HIGH); // set the Nutrient Heater off
    CurrentTaskInterval = minutes_in_ms(17);
 break;

  case 4:
    digitalWrite(5,HIGH);   // set the drain pump off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(2,LOW);  // set the PH down on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = seconds_in_ms(10);
 break;
 

case 5:
    digitalWrite(2,HIGH);  // set the PH down off
    digitalWrite(6,LOW); // set the Solenoid Valve on 
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(6);

break;
 

case 6:
digitalWrite(3,HIGH); // set the B nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on
digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(5.04);


break;

case 7:
digitalWrite(4,HIGH); // set the A nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on

    CurrentTaskInterval = minutes_in_ms(5);


break;


case 8:
digitalWrite(6,HIGH); // set the Solenoid Valve off
digitalWrite(7,LOW); // set the Nutrient Heater on

CurrentTaskInterval = days_in_ms(1);

break;

case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1); 
break;

case 22:
// Start over again in one week from the START of the cycle
    Task = 0;
    LastTaskTime = CycleStartTime;
    CurrentTaskInterval = weeks_in_ms(1);
    break;
  } 
}

here’s what I had that I started with that will compile but runs the flush stuff every loop that I don’t want.

  //  Some macros for defining time intervals in milliseconds
#define seconds_in_ms(s) ((s)*1000UL)
#define minutes_in_ms(m) ((m)*60UL*1000UL)
#define hours_in_ms(h)   ((h)*60UL*60UL*1000UL)
#define days_in_ms(d)    ((d)*24UL*60UL*60UL*1000UL)
#define weeks_in_ms(w)   ((w)*7UL*24UL*60UL*60UL*1000UL)

unsigned long CycleStartTime = 0;
unsigned long LastTaskTime = 0;
unsigned long CurrentTaskInterval = 0;
unsigned Task = 0;
 

void setup() {
 

   pinMode(2, OUTPUT);   //PH down
   pinMode(3, OUTPUT);  //B nutrient solution
   pinMode(4, OUTPUT);  //A nutrient solution
   pinMode(5, OUTPUT);  //Drain pump
   pinMode(6, OUTPUT);   //Solenoid Valve
   pinMode(7, OUTPUT);  //Nutrient Heater

  digitalWrite(2, HIGH);     //PH down off
  digitalWrite(3, HIGH);  //B nutrient solution off
  digitalWrite(4, HIGH);  //A nutrient solution off
  digitalWrite(5, HIGH);  //Drain pump off
  digitalWrite(6, HIGH);   //Solenoid Valve off
  digitalWrite(7, HIGH);  //Nutrient Heater off
}
  
void loop() {


  unsigned long currentTime = millis();

  // If the time has not yet come to perform a task
  if (currentTime - LastTaskTime < CurrentTaskInterval)
    return;   // Nothing to do

  LastTaskTime = currentTime;

  switch (Task++)
  {
  case 0:
    CycleStartTime = currentTime;  // Remember this time

   digitalWrite(5,LOW);   // set the drain pump on flush
    
    CurrentTaskInterval = minutes_in_ms(17);
    break;
    
  case 1:
    digitalWrite(5,HIGH);   // set the drain pump off flush
    digitalWrite(6,LOW); // set the Solenoid Valve on flush
    CurrentTaskInterval = minutes_in_ms(17);
 break;
 
 case 2:
    digitalWrite(6,HIGH); // set the Solenoid Valve off flush
    digitalWrite(7,LOW); // set the Nutrient Heater on flush
    CurrentTaskInterval = minutes_in_ms(10);
 break;
 
 case 3:
    digitalWrite(5,LOW);   // set the drain pump on
      digitalWrite(7,HIGH); // set the Nutrient Heater off
    CurrentTaskInterval = minutes_in_ms(17);
 break;

  case 4:
    digitalWrite(5,HIGH);   // set the drain pump off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(2,LOW);  // set the PH down on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = seconds_in_ms(10);
 break;
 

case 5:
    digitalWrite(2,HIGH);  // set the PH down off
    digitalWrite(6,LOW); // set the Solenoid Valve on 
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(6);

break;
 

case 6:
digitalWrite(3,HIGH); // set the B nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on
digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(5.04);


break;

case 7:
digitalWrite(4,HIGH); // set the A nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on

    CurrentTaskInterval = minutes_in_ms(5);


break;


case 8:
digitalWrite(6,HIGH); // set the Solenoid Valve off
digitalWrite(7,LOW); // set the Nutrient Heater on

CurrentTaskInterval = days_in_ms(1);

break;

case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1); 
break;

case 22:
// Start over again in one week from the START of the cycle
    Task = 0;
    LastTaskTime = CycleStartTime;
    CurrentTaskInterval = weeks_in_ms(1);
    break;
  } 
}

this wont compile

Probably because you still have

  switch (Task++)
  LastTaskTime = currentTime;
  {

move the "LastTaskTime = currentTime;" to after the closing } of the switch.

Also add

 int CycleCount;

with the other global variables.

Note I have not looked at the logic of the code, just got it compiling.


Rob

Dam, still playing with this thing grrrrr
Tried this it wont work, thought I had it grrr
The program starts with the digitalWrite(5,LOW); // set the drain pump on
that’s it stalls won’t go further.

   //  Some macros for defining time intervals in milliseconds
#define seconds_in_ms(s) ((s)*1000UL)
#define minutes_in_ms(m) ((m)*60UL*1000UL)
#define hours_in_ms(h)   ((h)*60UL*60UL*1000UL)
#define days_in_ms(d)    ((d)*24UL*60UL*60UL*1000UL)
#define weeks_in_ms(w)   ((w)*7UL*24UL*60UL*60UL*1000UL)

unsigned long CycleStartTime = 0;
unsigned long LastTaskTime = 0;
unsigned long CurrentTaskInterval = 0;
unsigned Task = 3;  //All you had to change was this. 1st time, Task will = 3.


void setup() {


   pinMode(2, OUTPUT);   //PH down
   pinMode(3, OUTPUT);  //B nutrient solution
   pinMode(4, OUTPUT);  //A nutrient solution
   pinMode(5, OUTPUT);  //Drain pump
   pinMode(6, OUTPUT);   //Solenoid Valve
   pinMode(7, OUTPUT);  //Nutrient Heater
   pinMode(8, OUTPUT);  //Not used Future Nutrient/PH contoller

  digitalWrite(2, HIGH);     //PH down off
  digitalWrite(3, HIGH);  //B nutrient solution off
  digitalWrite(4, HIGH);  //A nutrient solution off
  digitalWrite(5, HIGH);  //Drain pump off
  digitalWrite(6, HIGH);   //Solenoid Valve off
  digitalWrite(7, HIGH);  //Nutrient Heater off
}

void loop() {


  unsigned long currentTime = millis();

  // If the time has not yet come to perform a task
  if (currentTime - LastTaskTime < CurrentTaskInterval)
    return;   // Nothing to do

  LastTaskTime = currentTime;

  switch (Task)
  {
  case 0:
    CycleStartTime = currentTime;  // Remember this time

   digitalWrite(5,LOW);   // set the drain pump on flush

    CurrentTaskInterval = minutes_in_ms(17);
    break;

  case 1:
    digitalWrite(5,HIGH);   // set the drain pump off flush
    digitalWrite(6,LOW); // set the Solenoid Valve on flush
    CurrentTaskInterval = hours_in_ms(1);
 break;

 case 2:
    digitalWrite(6,HIGH); // set the Solenoid Valve off flush
    digitalWrite(7,LOW); // set the Nutrient Heater on flush
    CurrentTaskInterval = minutes_in_ms(60);
 break;

 case 3:
    digitalWrite(5,LOW);   // set the drain pump on
      digitalWrite(7,HIGH); // set the Nutrient Heater off
    CurrentTaskInterval = minutes_in_ms(17);
 break;

  case 4:
    digitalWrite(5,HIGH);   // set the drain pump off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(2,LOW);  // set the PH down on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = seconds_in_ms(10);
 break;


case 5:
    digitalWrite(2,HIGH);  // set the PH down off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(6);

break;


case 6:
digitalWrite(3,HIGH); // set the B nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on
digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(5.04);


break;

case 7:
digitalWrite(4,HIGH); // set the A nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on

    CurrentTaskInterval = minutes_in_ms(5);


break;


case 8:
digitalWrite(6,HIGH); // set the Solenoid Valve off
digitalWrite(7,LOW); // set the Nutrient Heater on
digitalWrite(8,HIGH); // set the Future Nutrient/PH contoller off

CurrentTaskInterval = days_in_ms(1);

break;

case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
delay (20000);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);
break;

case 22:
// Start over again in one week from the START of the cycle
    LastTaskTime = CycleStartTime;
    CurrentTaskInterval = weeks_in_ms(1);
    Task = 0;   //statrts loop at 0
    break;
  }
}
void loop() {


  unsigned long currentTime = millis();

  // If the time has not yet come to perform a task
  if (currentTime - LastTaskTime < CurrentTaskInterval)
    return;   // Nothing to do

You should turn this logic around, and get rid of the return (and put the { and } where the belong and tidy up the white space use).

void loop()
{
   unsigned long currentTime = millis();
   if(currentTime - LastTaskTime >= CurrentTaskInterval)
   {
      // Do something
   }
}
delay (20000);

And here I thought the idea was to get rid of this crap…

Tried this it wont work

It does something. You expect it to do something. That the two somethings are not the same is the reason for your post. You need to explain what those two somethings are, though.

that’s it stalls won’t go further.

Perhaps all that is happening is that you don’t see anything happening.

Thanks I guess this is right, it compiles havn't tried it yet. look Pretty though.

   //  Some macros for defining time intervals in milliseconds
#define seconds_in_ms(s) ((s)*1000UL)
#define minutes_in_ms(m) ((m)*60UL*1000UL)
#define hours_in_ms(h)   ((h)*60UL*60UL*1000UL)
#define days_in_ms(d)    ((d)*24UL*60UL*60UL*1000UL)
#define weeks_in_ms(w)   ((w)*7UL*24UL*60UL*60UL*1000UL)

unsigned long CycleStartTime = 0;
unsigned long LastTaskTime = 0;
unsigned long CurrentTaskInterval = 0;
unsigned Task = 3;  //All you had to change was this. 1st time, Task will = 3.


void setup() {


   pinMode(2, OUTPUT);   //PH down
   pinMode(3, OUTPUT);  //B nutrient solution
   pinMode(4, OUTPUT);  //A nutrient solution
   pinMode(5, OUTPUT);  //Drain pump
   pinMode(6, OUTPUT);   //Solenoid Valve
   pinMode(7, OUTPUT);  //Nutrient Heater
   pinMode(8, OUTPUT);  //Not used Future Nutrient/PH contoller

  digitalWrite(2, HIGH);     //PH down off
  digitalWrite(3, HIGH);  //B nutrient solution off
  digitalWrite(4, HIGH);  //A nutrient solution off
  digitalWrite(5, HIGH);  //Drain pump off
  digitalWrite(6, HIGH);   //Solenoid Valve off
  digitalWrite(7, HIGH);  //Nutrient Heater off
}

void loop() {


  unsigned long currentTime = millis();

  // If the time has not yet come to perform a task
  if(currentTime - LastTaskTime >= CurrentTaskInterval)
  LastTaskTime = currentTime;

  switch (Task)
  {
  case 0:
    CycleStartTime = currentTime;  // Remember this time

   digitalWrite(5,LOW);   // set the drain pump on flush

    CurrentTaskInterval = minutes_in_ms(17);
    break;

  case 1:
    digitalWrite(5,HIGH);   // set the drain pump off flush
    digitalWrite(6,LOW); // set the Solenoid Valve on flush
    CurrentTaskInterval = hours_in_ms(1);
 break;

 case 2:
    digitalWrite(6,HIGH); // set the Solenoid Valve off flush
    digitalWrite(7,LOW); // set the Nutrient Heater on flush
    CurrentTaskInterval = minutes_in_ms(60);
 break;

 case 3:
    digitalWrite(5,LOW);   // set the drain pump on
      digitalWrite(7,HIGH); // set the Nutrient Heater off
    CurrentTaskInterval = minutes_in_ms(17);
 break;

  case 4:
    digitalWrite(5,HIGH);   // set the drain pump off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(2,LOW);  // set the PH down on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = seconds_in_ms(10);
 break;


case 5:
    digitalWrite(2,HIGH);  // set the PH down off
    digitalWrite(6,LOW); // set the Solenoid Valve on
    digitalWrite(3,LOW); // set the B nutrient solution on
    digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(6);

break;


case 6:
digitalWrite(3,HIGH); // set the B nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on
digitalWrite(4,LOW); // set the A nutrient solution on
    CurrentTaskInterval = minutes_in_ms(5.04);


break;

case 7:
digitalWrite(4,HIGH); // set the A nutrient solution off
digitalWrite(6,LOW); // set the Solenoid Valve on

    CurrentTaskInterval = minutes_in_ms(5);


break;


case 8:
digitalWrite(6,HIGH); // set the Solenoid Valve off
digitalWrite(7,LOW); // set the Nutrient Heater on
digitalWrite(8,HIGH); // set the Future Nutrient/PH contoller off

CurrentTaskInterval = days_in_ms(1);

break;

case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
digitalWrite(6,LOW); // set the Solenoid Valve on/ top up
CurrentTaskInterval = seconds_in_ms(20);
digitalWrite(6,HIGH); // set the Solenoid Valve off/ top up
CurrentTaskInterval = days_in_ms(1);
break;

case 22:
// Start over again in one week from the START of the cycle
    LastTaskTime = CycleStartTime;
    CurrentTaskInterval = weeks_in_ms(1);
    Task = 0;   //statrts loop at 0
    break;
  }
   }

look Pretty though.

Except for the random indenting, { in the wrong place (they belong on lines by themselves), the excess white space, and the missing braces after the if test, I guess it's pretty.