multiple independant soilsensor/waterpump setup timing issue

hello all!

i am currently trying to accomplish the following for greenhouse application:

-automated control of the watering of strawberry rows, (many sensor and relay(waterpumps)

-at the same time collect the sensor reading over an internet shield

-adding various fail safe down the road, so i want to keep this project easy for future addons

what i want from you guys:

helping me resolve a timing issue,

at the moment, i have 2 soil sensor running their own relay (water pump) independant, but im having trouble with the timers.

what happends, if the reading is over 800, sensor1 kicks in after 2-5 sec, then closes after 8 sec

if the reading is over 800, sensor2 kicks in after 8sec, then closes after 20sec

there is a mixed up timer setup in there, what i would like is after the sensor reads over 800, that the relay comes ON instant or 2 sec after is fine, but constant.

i dont want to use delays, and i think the script i have avoids the 50days issue with the millisecond internal clock. if you think it does not let me know!

const int RELAY1= 6;
const int RELAY2= 7;

int RELAYSTATE1 = LOW;
int RELAYSTATE2 = LOW;

int sensorReading1= analogRead(A0); 
 int sensorReading2= analogRead(A1);

unsigned long timer[10];
byte timerState[10];


void setup() {

Serial.begin(9600);
Serial.println("Initializing");
pinMode(RELAY1, OUTPUT); 
pinMode(RELAY2, OUTPUT);
digitalWrite(RELAY1,HIGH);
digitalWrite(RELAY2,HIGH);
}

void loop() {

//the number "1" is the timer used
//The next number "1000" is the delay in milliseconds
  if (delayMilliSeconds(1,2000)){
 int sensorReading1= analogRead(A0);
 int sensorReading2= analogRead(A1);
 Serial.print("Sensor1: ");
 Serial.println (sensorReading1); //prints out the sensor reading
 Serial.print("Sensor2: ");
 Serial.println (sensorReading2); //prints out the sensor reading
  }
  int sensorReading1= analogRead(A0); //reads the sensor value
 if (delayMilliSeconds(2,8000))
   if (sensorReading1> 800){//if reading is above 800  
digitalWrite(RELAY1,LOW); //turns the pump on
Serial.print("watering! ");
}
 else { digitalWrite(RELAY1,HIGH); //turns the pump off after 8sec
}
 int sensorReading2= analogRead(A1);
 if (delayMilliSeconds(3,20000))
   if (sensorReading2> 800){//if reading is above 800  
digitalWrite(RELAY2,LOW); //turns the pump on
Serial.print("watering! ");
}
 else{digitalWrite(RELAY2,HIGH); //turns the pump off
 //Serial.print("finished watering! ");
}
}
// Do something else here if enough time has not passed

//======================================
//Everything from here down comes after the main "loop()"

int delayHours(byte timerNumber,unsigned long delaytimeH){    //Here we make it easy to set a delay in Hours
  delayMilliSeconds(timerNumber,delaytimeH*1000*60*60);
}
int delayMinutes(byte timerNumber,unsigned long delaytimeM){    //Here we make it easy to set a delay in Minutes
  delayMilliSeconds(timerNumber,delaytimeM*1000*60);
}
int delaySeconds(byte timerNumber,unsigned long delaytimeS){    //Here we make it easy to set a delay in Seconds
  delayMilliSeconds(timerNumber,delaytimeS*1000);
}
int delayMilliSeconds(int timerNumber,unsigned long delaytime){
  unsigned long timeTaken;
  if (timerState[timerNumber]==0){    //If the timer has been reset (which means timer (state ==0) then save millis() to the same number timer,
    timer[timerNumber]=millis();
    timerState[timerNumber]=1;      //now we want mark this timer "not reset" so that next time through it doesn't get changed.
  }
  if (millis()> timer[timerNumber]){
    timeTaken=millis()+1-timer[timerNumber];    //here we see how much time has passed
  }
  else{
    timeTaken=millis()+2+(4294967295-timer[timerNumber]);    //if the timer rolled over (more than 48 days passed)then this line accounts for that
  }
  if (timeTaken>=delaytime) {          //here we make it easy to wrap the code we want to time in an "IF" statement, if not then it isn't and so doesn't get run.
     timerState[timerNumber]=0;  //once enough time has passed the timer is marked reset.
     return 1;                          //if enough time has passed the "IF" statement is true
  }
  else {                               //if enough time has not passed then the "if" statement will not be true.
    return 0;
  }
}
  if (millis() > timer[timerNumber]) {
    timeTaken = millis() + 1 - timer[timerNumber]; //here we see how much time has passed
  }
  else {
    timeTaken = millis() + 2 + (4294967295 - timer[timerNumber]); //if the timer rolled over (more than 48 days passed)then this line accounts for that
  }

You have made things unnecessarily complicated. If you simply subtract the millis() value of when a state started from the current millis() value and compare it with the required period then the 49 day millis() rollover is automatically taken care of.

thanks for the input!

Ive been able to put this together, still one thing that does not work, the RelayPin1 comes ON when its over 800 after 1sec, that part works, but not until the value goes under 800 that the else if comes into play to shut down the relay 8 sec later

    const int RelayPin1 =  6;      
    int RelayState1 = LOW;             
    unsigned long previousMillis1 = 0;        
    long OnTime1 = 2000;           
    long OffTime1 = 750;          
     
    const int RelayPin2 =  7;      
    int RelayState2 = LOW;             
    unsigned long previousMillis2 = 0;        
    long OnTime2 = 1000;          
    long OffTime2 = 8000; 
unsigned long previousMillis3 = 0;

 const int sensorReading1= analogRead(A0);
const int sensorReading2= analogRead(A1);





void setup() {
 
  Serial.begin(9600);
  Serial.println("Initializing");

      pinMode(RelayPin1, OUTPUT);      
      pinMode(RelayPin2, OUTPUT); 
      digitalWrite(RelayPin1,HIGH); //turns the pump off 
      digitalWrite(RelayPin2,HIGH); 
}

void loop() {
  
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis1 >= OnTime1)
   {
   int sensorReading1= analogRead(A0); //reads the sensor value
 int sensorReading2= analogRead(A1);   
 Serial.print("Sensor1: ");
 Serial.println (sensorReading1); //prints out the sensor reading
 Serial.print("Sensor2: ");
 Serial.println (sensorReading2); //prints out the sensor reading
   previousMillis1 = currentMillis;
  
  }
  int sensorReading1= analogRead(A0);
 if ((sensorReading1>= 800) && (currentMillis - previousMillis2 >= OnTime2))
      {
        digitalWrite(RelayPin1,LOW); //turns the pump on
        Serial.print("watering! ");
        previousMillis2 = currentMillis;  // Remember the time
        }
       
        else if((RelayState1==LOW)&&(currentMillis - previousMillis2 >= OffTime2))
          {
        digitalWrite(RelayPin1,HIGH);
        previousMillis2 = currentMillis;   // Remember the time
      
       } 
       }

ill continue working on it tomorrow, in the mean time if someone knows what’s wrong or can easely correct what im doing wrong, that would be great. Ill keep updating on my progress, thanks in advance!

I have made a few changes in this each marked with //======
You had some unncessary and confusing int definitions. Just define a variable in one place

const int RelayPin1 =  6;     
int RelayState1 = LOW;             
unsigned long previousMillis1 = 0;       
long OnTime1 = 2000;           
long OffTime1 = 750;         
 
const int RelayPin2 =  7;     
int RelayState2 = LOW;             
unsigned long previousMillis2 = 0;       
long OnTime2 = 1000;         
long OffTime2 = 8000;
unsigned long previousMillis3 = 0;

int sensorReading1 = 0;  // ====== you can't read values here
int sensorReading2 = 0;  // ====== don't make variables CONST

void setup() {
 
	Serial.begin(9600);
	Serial.println("Initializing");

		pinMode(RelayPin1, OUTPUT);     
		pinMode(RelayPin2, OUTPUT);
		digitalWrite(RelayPin1,HIGH); //turns the pump off
		digitalWrite(RelayPin2,HIGH);
}

void loop() {
 
	unsigned long currentMillis = millis();
	
	if (currentMillis - previousMillis1 >= OnTime1)
	{
		sensorReading1= analogRead(A0); //reads the sensor value //======== Don't redefine variables
		sensorReading2= analogRead(A1);   //========
		Serial.print("Sensor1: ");
		Serial.println (sensorReading1); //prints out the sensor reading
		Serial.print("Sensor2: ");
		Serial.println (sensorReading2); //prints out the sensor reading
		previousMillis1 = currentMillis;
	}
	
	sensorReading1= analogRead(A0); //======== why is this here ?
	
	if ((sensorReading1>= 800) && (currentMillis - previousMillis2 >= OnTime2))
	{
		digitalWrite(RelayPin1,LOW); //turns the pump on
		Serial.print("watering! ");
		previousMillis2 = currentMillis;  // Remember the time
	}
	else if((RelayState1==LOW)&&(currentMillis - previousMillis2 >= OffTime2))
	{
		digitalWrite(RelayPin1,HIGH);
		previousMillis2 = currentMillis;   // Remember the time
	 
	}
}

...R

thanks robin for the heads up! i do alot of copy/paste and those things slipped my mind, and im still new to the arduino programming so sometimes i cant see if its needed or not.

anyway, i think i got it to work except a minor glitch but that not too bad(until the sensor reads over 600, its gonna keep saying watering! every 1sec)

    const int RelayPin1 =  6;      
    int RelayState1 = LOW;             
    unsigned long previousMillis1 = 0;        
    long OnTime1 = 2000;           
    long OffTime1 = 750;          
     
    const int RelayPin2 =  7;      
    int RelayState2 = LOW;             
    unsigned long previousMillis2 = 0;        
    long OnTime2 = 1000;          
    long OffTime2 = 15000; 
    
unsigned long previousMillis3 = 0;
long OnTime3 = 1000;          
    long OffTime3 = 30000; 

int sensorReading1 = 0; 
int sensorReading2 = 1;





void setup() {
 
  Serial.begin(9600);
  Serial.println("Initializing");

      pinMode(RelayPin1, OUTPUT);      
      pinMode(RelayPin2, OUTPUT); 
      digitalWrite(RelayPin1,HIGH); //turns the pump off 
      digitalWrite(RelayPin2,HIGH); 
}

void loop() {
  
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis1 >= OnTime1)
   {
      sensorReading1= analogRead(A0); //reads the sensor value
      sensorReading2= analogRead(A1);  
 Serial.print("Sensor1: ");
 Serial.println (sensorReading1); //prints out the sensor reading
 Serial.print("Sensor2: ");
 Serial.println (sensorReading2); 
   previousMillis1 = currentMillis;
  
  }
 if ((sensorReading1>= 600) && (currentMillis - previousMillis2 >= OnTime2))
      {
        digitalWrite(RelayPin1,LOW); //turns the pump on
        Serial.print("watering! ");
        previousMillis2 = currentMillis;  // Remember the time
        }
       
        else if((RelayState1==LOW)&&(currentMillis - previousMillis2 >= OffTime2))
          {
        digitalWrite(RelayPin1,HIGH);
      
       } 
       if ((sensorReading2>= 600) && (currentMillis - previousMillis3 >= OnTime3))
      {
        digitalWrite(RelayPin2,LOW); //turns the pump on
        Serial.print("watering! ");
        previousMillis3 = currentMillis;  // Remember the time
        }
       
        else if((RelayState2==LOW)&&(currentMillis - previousMillis3 >= OffTime3))
          {
        digitalWrite(RelayPin2,HIGH);
       
       }
        }

if you guys got some input let me know! so far im gonna go with this.

Oh and please, i know the millis() gets reset, but just to ease my mind, can you guys confirm those

loops wont be affected by the 49days end of timer issue, thanks in advance!

i know the millis() gets reset, but just to ease my mind, can you guys confirm those

loops wont be affected by the 49days end of timer issue, thanks in advance!

The use of subtraction in determining whether the required period has elapsed and the use of unsigned long variables assures that the rollover of millis() to zero will not affect the timing.

alphagreen:
except a minor glitch but that not too bad(until the sensor reads over 600, its gonna keep saying watering! every 1sec)

To stop that you need a variable to record the fact that it has started watering. You could also use that as a substitute for checking

if ((sensorReading1>= 600) && (currentMillis - previousMillis2 >= OnTime2))

every iteration of loop()

As you have noted these are just cosmetic changes and should not affect the functioning of the system

...R