need help with code please

hi, i have a few segments of code i need help with, i have a photosensor changing the timers off duration in my code. the problems is i need all 3 of the timers to have independent on/off times. if i remove the code for the photo sensor i can do what i want but then i dont have the photo sensor. can someone tell me what i need to add to make pump pins 4,5,6 to have independent on/off times with the photo sensor code. i dont know how to modify the case statement at the bottom of the code to change individual timers. right now it changes all the timers for all pumps to the same time. thanks

#define Pump_Timer(x) (uint32_t)(x)*60*1 // Multiplies Ms by 60 SO I COULD SET TIME AS FRACTIONS OF MINUTES
#define PhotoSensor_Delay 2000
#define ButtonDelay 20
#define PRESSED LOW
#define NOT_PRESSED HIGH


int  Pump1Pin = 4;
int  Pump2Pin = 5;
// int  Pump3Pin = 6;


// create a Button variable type
Button button;

class PumpTimer {
    using functPtr = void(*)(void);
  public:
    PumpTimer(int pumpPin, uint32_t runTime, uint32_t pauseTime, functPtr stoppedAction = nullptr) : pin(pumpPin), cycleMillis(runTime), offMillis(pauseTime), callback(stoppedAction) {}
    void setTime(uint32_t runTime) {
      cycleMillis = runTime;
    }
    void setTime(uint32_t runTime, uint32_t pauseTime) {
      cycleMillis = runTime;
      offMillis = pauseTime;
    }
    void setPauseTime(uint32_t pauseTime) {
      offMillis = pauseTime;
    }
    void init(void) {
      pinMode(pin, OUTPUT);
    }
    void start(uint32_t duration) {
      cycleMillis = duration;
      start();
    }
    void start(void) {
      startMillis = millis();
      state = ACTIVE_RUNNING;
      digitalWrite(pin, LOW);
      pumponstate = 0;
      digitalWrite(BLUE_PIN, HIGH);
    }
    void process(void) {
      switch (state) {
        case STOPPED:
          break;
        case ACTIVE_RUNNING:
          if (millis() - startMillis > cycleMillis) {
            digitalWrite(pin, HIGH);
            state = ACTIVE_PAUSED;
            startMillis = millis();
            pumponstate = 1;
            digitalWrite(BLUE_PIN, LOW);
            digitalWrite(GREEN_PIN, HIGH);

          }
          break;
        case ACTIVE_PAUSED:
          if (millis() - startMillis > offMillis) {
            state = STOPPED;
            pumponstate = 1;
            digitalWrite(BLUE_PIN, HIGH);
            digitalWrite(GREEN_PIN, LOW);
            if (callback) {
              callback();
            }
          }
          break;
      }
    }
    void stop(void) {
      digitalWrite(pin, HIGH);
      state = STOPPED;
      callback();
    }
  private:
    enum {
      STOPPED,
      ACTIVE_RUNNING,
      ACTIVE_PAUSED,
    } state = STOPPED;
    uint8_t pin;
    uint32_t cycleMillis;
    uint32_t offMillis;
    uint32_t startMillis;
    functPtr callback;
};

PumpTimer timer[] = {
  /*Pin number, On Time, Pause Time and pointer to callback function */
  { 4, Pump_Timer(10000), Pump_Timer(6000), []() { //PUMP2
      timer[1].start();
    }
  },
  { 5, Pump_Timer(10000), Pump_Timer(6000), []() {  //PUMP3
      timer[0].start();
  //  }
 // },
//  { 6, Pump_Timer(12400), Pump_Timer(9000), []() {  //PUMP1
      timer[2].start();
    }
  },
};

enum SwitchState {
  PHOTOSENSOR_DAY,
  PHOTOSENSOR_NIGHT,
  UNKNOWN,
} savedState = UNKNOWN;

const uint8_t PhotoSensor = 8;


void setup() {
  // put your setup code here, to run once:

}

void loop() {

   for (auto& t : timer) {
      t.init();
    }
    timer[0].start();
    
  static uint32_t lastSwitchMillis = 0;
  SwitchState currentState = digitalRead(PhotoSensor) ? PHOTOSENSOR_DAY : PHOTOSENSOR_NIGHT;
  if (currentState != savedState) {
    if (millis() - lastSwitchMillis > PhotoSensor_Delay) {
      lastSwitchMillis = millis();
      savedState = currentState;
      setCycle(currentState);
    }
  }
}

void setCycle(SwitchState state) {
  switch (state) {
    case PHOTOSENSOR_DAY:
      for (auto& t : timer) {
        t.setTime(Pump_Timer(10000), Pump_Timer(6000));  //set all timers --day formula is Ms divided by 60
      }
      break;
    case PHOTOSENSOR_NIGHT:
      for (auto& t : timer) {
        t.setTime(Pump_Timer(10000), Pump_Timer(20000));  //set all  timers --night
   t.setTime(pin 5???
  t.setTime(pin 4???
etc

      }
      break;
    case UNKNOWN:
      break;
  }
}

i suggest using struct to keep track of your stuffs

struct worker {
   int pin;
   unsigned long start_time;
   unsigned long duration;
};


//declare objects and initialize

worker my_workers[3] = {{4, 0, 0}, {5, 0, 0}, {6, 0, 0}}; //4, 5, 6 are pin numbers respectively

void setup()
{
   ...
   //set pins mode here
   //use for loop
   ...
}

void loop()
{
   ...

}

but how can i change just one timer profile with the photosensor code at the bottom. right now it sets all the timers at the same time. i would like to to set all the timers except each timer be a different duration? right now it sets all timers to 10000,6000 i would like to set the timers like this,

pump 1 = 10000, 6000
pump 2 = 12400, 6000
pump 3 = 13100, 600

instead of just

t.set.all.timers = 10000, 6000

do you get what im trying to say?

for example something like this,

void setCycle(SwitchState state) {
  switch (state) {
    case PHOTOSENSOR_DAY:
      for (auto& t : timer) {
        t.setTime(Pump_Timer(10000), Pump_Timer(6000));  pump 1
 
     t.setTime(Pump_Timer(12400), Pump_Timer(6000));   pump 2

     t.setTime(Pump_Timer(13100), Pump_Timer(6000));  pump 3
      }
      break;
    case PHOTOSENSOR_NIGHT:
      for (auto& t : timer) {
        t.setTime(Pump_Timer(10000), Pump_Timer(20000));  //set all  timers --night //pump 1

        t.setTime(Pump_Timer(12400), Pump_Timer(20000));  //set all  timers --night //pump 2

        t.setTime(Pump_Timer(13100), Pump_Timer(20000));  //set all  timers --night //pump 3

      }
      break;
    case UNKNOWN:
      break;
  }
}

if you wrote the posted code. I suggest to rewrite the whole thing instead of patching them.

if not then … sorry i’m too lazy to look at your code to make more suggestion.

I think there is a quite a bit of merry-go-round with your implementation.

When you're doing for( t : timer) in that switch, you're already iterating through existing 3 timers that are pre-constructed to be on specific pins.

So this construction:

PumpTimer(int pumpPin, uint32_t runTime,  etc...

Already says, that this timer is "hardwired" to a specific pin. Since you construct the object passing a specific pump pin to it.

So when you do a loop through timers using for( t : timer ), you need to know inside that loop if the "t" is the timer that you want.

For the way you have implemented it, this should be part of PumpTimer class:

uint8_t getPin() {
   return pin;
}

Then inside the switch:

case PHOTOSENSOR_NIGHT:
  for (auto& t : timer) {
      if(t.getPin() == 4)
           t.setTime( ..... );
      else if(t.getPin() == 5)
           t.setTime( .... );
      else if(t.getPin() == 6)
           t.setTime( .... );

 }

Cause you're iterating through whole array of these timers, you need to filter which timer object gets set. So if/else logic there, or do another switch() by t.getPin(), or something.

Sorry i really suck at C++, but then again this is not a C++ issue per se. More like like logical one.

crashedfx:
I think there is a quite a bit of merry-go-round with your implementation.

When you're doing for( t : timer) in that switch, you're already iterating through existing 3 timers that are pre-constructed to be on specific pins.

So this construction:

PumpTimer(int pumpPin, uint32_t runTime,  etc...

Already says, that this timer is "hardwired" to a specific pin. Since you construct the object passing a specific pump pin to it.

So when you do a loop through timers using for( t : timer ), you need to know inside that loop if the "t" is the timer that you want.

For the way you have implemented it, this should be part of PumpTimer class:

uint8_t getPin() {

return pin;
}





Then inside the switch: 



case PHOTOSENSOR_NIGHT:
  for (auto& t : timer) {
      if(t.getPin() == 4)
          t.setTime( ..... );
      else if(t.getPin() == 5)
          t.setTime( .... );
      else if(t.getPin() == 6)
          t.setTime( .... );

}

thankyou i think this is what im looking for, im going to see what i can do with this. thanks again

notsolowki:
thankyou i think this is what im looking for, im going to see what i can do with this. thanks again

My pleasure. Hope it works as desired. =)