programming a sensor information based pump

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
int trigger;
const long interval = 120000;

void setup() {
Serial.begin(9600);
pinMode(9, OUTPUT);
pinMode(sensor1, INPUT);
pinMode(sensor2, INPUT);
}

void loop() {
unsigned long currentMillis = millis();
val1 = analogRead(sensor1);
val2 = analogRead(sensor2);
Serial.println(val1);
Serial.println(val2);
if (currentMillis - previousMillis >= interval) {
  trigger = 1;
}
else {
  trigger = 0;
}
if ((trigger = 1) && (val1 >= 510)) {
  digitalWrite(9, HIGH);
  delay(2500);
  digitalWrite(9, LOW);
  delay(10000);
  digitalWrite(9, HIGH);
  delay(2500);
  digitalWrite(9, LOW);
  delay(10000);
  digitalWrite(9, HIGH);
  delay(2500);
  digitalWrite(9, LOW);
  delay(60000);
  if (val1 >= 500)
  digitalWrite(9, HIGH);
  delay(2500);
  digitalWrite(9, LOW);
}
[color=red]}[/color]
if (trigger = 0){
  digitalWrite(9, LOW);
}
previousMillis = currentMillis;
}

thats my code for the moment, I want that the code does the following:

every 2 minutes the pump should start pumping while the sensor value is greater than 510.

then the pump should pump 3 times,
wait 1 minute
and check then if the sensor is still greater than 500
if the sensor is greater than 500, the pump should pumpe once again.

otherwise the pump should be off.

This is thought to water some plant every day. So I would change the times I listed above, but the scheme is the same.

My question is, if the programming is done correctly.
I'm guessing I used some formula wrong.

Many thanks in advance!

Edit your post and place your code inside code tags (the button to add them looks like </>)

I think you are missing a {

if (val1 >= 500) <------- Right there
digitalWrite(9, HIGH);

DangerToMyself:
Edit your post and place your code inside code tags (the button to add them looks like </>)

I think you are missing a {

if (val1 >= 500) <------- Right there
digitalWrite(9, HIGH);

yes thank you. You are right!

it is working great as far.

til the moment when the arduino should pause for 2 minutes again
for this reason I added some new line to the code:
trigger = 0;

to turn the pump off.

But after that the pumpe does not stand still for 2 minutes

so my code is the following:

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
int trigger;
const long interval = 120000;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  val1 = analogRead(sensor1);
  val2 = analogRead(sensor2);
  Serial.println(val1);
  Serial.println(val2);
  if (currentMillis - previousMillis >= interval) {
    trigger = 1;
  }
  else {
    trigger = 0;
  }
  if ((trigger = 1) && (val1 >= 510)) {
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(60000);
    if (val1 >= 500){
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    trigger = 0;
  }
  }
  if (trigger = 0){
    digitalWrite(9, LOW);
  }
  previousMillis = currentMillis;
}

Everything is working fine now?

If so, good. Now you can work on getting rid of all those delays :slight_smile:

unfortuneatly the pump does not wait for 2 minutes...

if (currentMillis - previousMillis >= interval) {
trigger = 1;
previousMillis = currentMillis; <------- Need that
}

tells the controller when the last time it was ran. So it can calculate the next time it needs ran.

yeah I had that at the very last line before..
I placed it now to where you advised me to insert it.

But somehow it still does not wait 2 minutes....
already after 10 seconds, the pump is running again

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
int trigger;
const long interval = 120000;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  val1 = analogRead(sensor1);
  val2 = analogRead(sensor2);
  Serial.println(val1);
  Serial.println(val2);
  if (currentMillis - previousMillis >= interval) {
    trigger = 1;
    previousMillis = currentMillis;
  }
  else {
    trigger = 0;
  }
  if ((trigger = 1) && (val1 >= 510)) {
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(60000);
    if (val1 >= 500){
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    trigger = 0;
  }
  }
  if (trigger = 0){
    digitalWrite(9, LOW);
  }
}

All of those delays take up 90,500 milliseconds. So, as it is written, it should restart 29.5 seconds after the last delay is finished.

You want it to have a 2 minute gap between the last delay and restarting the process?

If so, easiest way in my opinion is to change "interval = 120000" to "interval = 210500".

I would probably use an entirely different method. But to get YOUR code working, it should work.

DangerToMyself:
All of those delays take up 90,500 milliseconds. So, as it is written, it should restart 29.5 seconds after the last delay is finished.

You want it to have a 2 minute gap between the last delay and restarting the process?

If so, easiest way in my opinion is to change "interval = 120000" to "interval = 210500".

I would probably use an entirely different method. But to get YOUR code working, it should work.

haaa!! okay! that makes totally sense!
thanks you.
As you see in kinda new to the arduino scene and open for any changes!
Please feel free :wink:

I would probably do something like this (NOT complete code)

void loop(){
  checkTime();
  runPumps();
}

void checkTime(){
  if pumpsFinished equals 0
    unsigned long currentMillis = millis();
    if time is up
        pumpsFinished = 1
        startPumps = 1;
}

void runPumps(){
   if startPumps equals 1
      //do pump stuff

      //when finished
      pumpsFinished = 0
      startPumps = 0
}

I would also take it further by doing away with all the delays. And if you plan to add other operations to your code, you will have to do away with them as well.

aronyi:
haaa!! okay! that makes totally sense!
thanks you.
As you see in kinda new to the arduino scene and open for any changes!
Please feel free :wink:

somehow the pump does not wait 2 minutes... after the pumping and waiting for 1 minute, the pump turns on again after 5 seconds...

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
int trigger;
const long interval = 210500;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  val1 = analogRead(sensor1);
  val2 = analogRead(sensor2);
  Serial.println(val1);
  Serial.println(val2);
  Serial.println(currentMillis);
  Serial.println(previousMillis);
  if (currentMillis - previousMillis >= interval) {
    trigger = 1;
    previousMillis = currentMillis;
  }
  else {
    trigger = 0;
  }
  if ((trigger = 1) && (val1 >= 510)) {
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(60000);
    if (val1 >= 500){
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
  }
  trigger = 0;
  }
  if (trigger = 0){
    digitalWrite(9, LOW);
  }
}

DangerToMyself:
I would probably do something like this (NOT complete code)

void loop(){

checkTime();
  runPumps();
}

void checkTime(){
  if pumpsFinished equals 0
    unsigned long currentMillis = millis();
    if time is up
        pumpsFinished = 1
        startPumps = 1;
}

void runPumps(){
  if startPumps equals 1
      //do pump stuff

//when finished
      pumpsFinished = 0
      startPumps = 0
}




I would also take it further by doing away with all the delays. And if you plan to add other operations to your code, you will have to do away with them as well.
int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
int pumpsFinished;
int startPumps;
const long interval = 210500;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  val1 = analogRead(sensor1);
  val2 = analogRead(sensor2);
  Serial.println(val1);
  Serial.println(val2);
  checkTime();
  runPumps();
}

void checkTime(){
  if (pumpsFinished = 0){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    pumpsFinished = 1;
    startPumps = 1;
    previousMillis = currentMillis;
  }
  }
  }

void runPumps(){
  if ((startPumps = 1) && (val1 >= 510)) {
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(60000);
    if (val1 >= 500){
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    pumpsFinished = 0;
    startPumps = 0;
  }
  }
  }

that's what I have now. But the pump still does not pause for 2 minutes..
btw how can I get rid of those delays?
adding more and more variables, and compare the differences between them? Already like I did with the time planning of the "main schedule"(repeated every 2 minutes)?

I edited your code, simplified it and removed the trigger so that I could test it. This works fine for me. It waits 210500, goes through the pumps and then waits 210500 again.

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
int trigger;
const long interval = 210500;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  //val1 = analogRead(sensor1);
  //val2 = analogRead(sensor2);
  val1 = 600;
  //Serial.println(val1);
  //Serial.println(val2);
  //Serial.println(currentMillis);
  //Serial.println(previousMillis);
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (val1 >= 510) {
      Serial.println("9, HIGH");
      delay(2500);
      Serial.println("9, LOW");
      delay(10000);
      Serial.println("9, HIGH");
      delay(2500);
      Serial.println("9, LOW");
      delay(10000);
      Serial.println("9, HIGH");
      delay(2500);
      Serial.println("9, LOW");
      delay(60000);
      if (val1 >= 500) {
        Serial.println("9, HIGH");
        delay(2500);
        Serial.println("9, LOW");
      }
    }
    Serial.println("9, LOW");
  }
}

if ((startPumps = 1) && (val1 >= 510)) { //startPumps == NOT =

same for if (pumpsFinished = 0){ should be ==

aronyi:

int sensor1 = A1;

int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
int pumpsFinished;
int startPumps;
const long interval = 210500;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  val1 = analogRead(sensor1);
  val2 = analogRead(sensor2);
  Serial.println(val1);
  Serial.println(val2);
  checkTime();
  runPumps();
}

void checkTime(){
  if (pumpsFinished = 0){
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    pumpsFinished = 1;
    startPumps = 1;
    previousMillis = currentMillis;
  }
  }
  }

void runPumps(){
  if ((startPumps = 1) && (val1 >= 510)) {
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(10000);
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    delay(60000);
    if (val1 >= 500){
    digitalWrite(9, HIGH);
    delay(2500);
    digitalWrite(9, LOW);
    pumpsFinished = 0;
    startPumps = 0;
  }
  }
  }




that's what I have now. But the pump still does not pause for 2 minutes..
btw how can I get rid of those delays? 
adding more and more variables, and compare the differences between them? Already like I did with the time planning of the "main schedule"(repeated every 2 minutes)?

aronyi:
btw how can I get rid of those delays?
adding more and more variables, and compare the differences between them? Already like I did with the time planning of the "main schedule"(repeated every 2 minutes)?

I do this

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
unsigned long previousPumpMillis = 0;
int pumpsFinished;
int startPumps;
const long interval = 210500;
int pumpStage = 0;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  val1 = analogRead(sensor1);
  val2 = analogRead(sensor2);
  Serial.println(val1);
  Serial.println(val2);
  checkTime();
  runPumps();
}

void checkTime() {
  if (pumpsFinished == 0) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      pumpsFinished = 1;
      startPumps = 1;
      previousMillis = currentMillis;
    }
  }
}

void runPumps() {
  if ((startPumps == 1) && (val1 >= 510)) {
    switch (pumpStage) {
      case 0:
        digitalWrite(9, HIGH);
        pumpTiming(2500);
        break;
      case 1:
        digitalWrite(9, LOW);
        pumpTiming(10000);
        break;

      //and so on
      //and so on

      default:
        pumpStage = 0;
        break;
    }
    //    digitalWrite(9, HIGH);
    //    delay(2500);
    //    digitalWrite(9, LOW);
    //    delay(10000);
    //    digitalWrite(9, HIGH);
    //    delay(2500);
    //    digitalWrite(9, LOW);
    //    delay(10000);
    //    digitalWrite(9, HIGH);
    //    delay(2500);
    //    digitalWrite(9, LOW);
    //    delay(60000);


                                             //BTW, this will always be true as it is inside 
                                             //if ((startPumps == 1) && (val1 >= 510)) {
                                             //so val1 HAS to be greater than 500
    //    if (val1 >= 500) {
    //      digitalWrite(9, HIGH);
    //      delay(2500);
    //      digitalWrite(9, LOW);
    //      pumpsFinished = 0;
    //      startPumps = 0;
    //    }
  }
}

void pumpTiming(unsigned long thisDelay) {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= thisDelay) {
    previousPumpMillis = currentMillis;
    pumpStage++;
  }
}

Question for the Gurus!!!

As you can tell, I've been attempting to help aronyi with his code. I started messing around with getting rid of the delays in his code and have come across an issue that I can't seem to figure out.

The following code runs a millis timer to start pumps. The pump function uses a switch case to run through his sequence. Each case sends a number to another timer using millis.

The issue is that it only goes through case 0 one time before calling case 1. When it should wait the desired 2500 milliseconds before changing cases. All other cases do as they should.

What am I not seeing?

Also, I've replaced his digitalWrite calls with Serial.println() and set val1 to 600 (he gets it from a sensor read) so that the sketch can be ran without the pins connected. You can run it if you like. But you'll need to have
Autoscroll unchecked to see what I am referring to.

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
unsigned long previousPumpMillis = 0;
int pumpsFinished;
int startPumps;
const long interval = 10000;
//const long interval = 120000;
int pumpStage = 0;
unsigned long myDelay;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  val1 = 600;
//  val1 = analogRead(sensor1);
//  val2 = analogRead(sensor2);
//  Serial.println(val1);
//  Serial.println(val2);
  checkTime();
  runPumps();
}

void checkTime() {
  if (pumpsFinished == 0) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      pumpsFinished = 1;
      startPumps = 1;
      pumpStage = 0;
      previousMillis = currentMillis;
      Serial.println("............................Restarting pumps");
    }
  }
}

void runPumps() {
  if ((startPumps == 1) && (val1 >= 500)) {
    if (val1 < 510) {
      pumpStage = 6;
    }
    switch (pumpStage) {
      case 0:
        Serial.println("Stage 0 = 9, HIGH");
        myDelay = 2500;
        pumpTiming(myDelay);
        break;
      case 1:
        Serial.println("Stage 1 = 9, LOW");
        myDelay = 10000;
        pumpTiming(myDelay);
        break;
      case 2:
        Serial.println("Stage 2 = 9, HIGH");
        myDelay = 2500;
        pumpTiming(myDelay);
        break;
      case 3:
        Serial.println("Stage 3 = 9, LOW");
        myDelay = 10000;
        pumpTiming(myDelay);
        break;
      case 4:
        Serial.println("Stage 4 = 9, HIGH");
        myDelay = 2500;
        pumpTiming(myDelay);
        break;
      case 5:
        Serial.println("Stage 5 = 9, LOW");
        myDelay = 60000;
        pumpTiming(myDelay);
        break;
      case 6:
        Serial.println("Stage 6 = 9, HIGH");
        myDelay = 2500;
        pumpTiming(myDelay);
        break;
      case 7:
        Serial.println("Stage 7 = 9, LOW");
        break;
      default:
        pumpStage = 0;
        pumpsFinished = 0;
        startPumps = 0;
        break;
    }
  }
}

void pumpTiming(unsigned long thisDelay) {
  unsigned long currentPumpMillis = millis();
  if (currentPumpMillis - previousPumpMillis >= thisDelay) {
    previousPumpMillis = currentPumpMillis;
    pumpStage++;
  }
}

EDIT:

I get this in the serial monitor

............................Restarting pumps
Stage 0 = 9, HIGH <----This should repeat for 2500 milliseconds
Stage 1 = 9, LOW
Stage 1 = 9, LOW
Stage 1 = 9, LOW
etc
etc
etc

Well, I didn't get any assistance with the issue above. So, I reworked it a bit and it does what >I THINK< it should now. Test it out and see if it works for you. I don't generally make it a point to write code for folks. But the issue above had me stumped (still does). There are probably better ways to handle your pump sequence as there is redundancy in your sequence. However, this way will allow you to easily change the timing at each stage should you want/need to in the future.

int sensor1 = A1;
int sensor2 = A4;
int val1;
int val2;
unsigned long previousMillis = 0;
unsigned long previousPumpMillis = 0;
int pumpsFinished;
int startPumps;
unsigned long interval = 120000;
int pumpStage = 0;
unsigned long myDelay;

void setup() {
  Serial.begin(9600);
  pinMode(9, OUTPUT);
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
}

void loop() {
  val1 = 600;
    val1 = analogRead(sensor1);
    val2 = analogRead(sensor2);
    Serial.println(val1);
    Serial.println(val2);
  checkTime();
  runPumps();
}

void checkTime() {
  if (pumpsFinished == 0) {
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;

      //added this after conversing with wildbill
      //this restarts the clock, so to speak, for the pump timing sequence
      previousPumpMillis = currentMillis; 

      pumpsFinished = 1;
      startPumps = 1;
      pumpStage = 0;
      //Serial.println("Restarting Sequence");
    }
  }
}

void runPumps() {
  if ((startPumps == 1) && (val1 >= 500)) {
    if (val1 < 510) { //if val1 is 500 to 509 jump to stage 6
      pumpStage = 6;
    } else if (pumpStage == 6) {
      pumpStage = 0;
      pumpsFinished = 0;
      startPumps = 0;
    }
    switch (pumpStage) {
      case 0:
        myDelay = 2500;
        pumpTiming(myDelay, 1);
        break;
      case 1:
        myDelay = 10000;
        pumpTiming(myDelay, 0);
        break;
      case 2:
        myDelay = 2500;
        pumpTiming(myDelay, 1);
        break;
      case 3:
        myDelay = 10000;
        pumpTiming(myDelay, 0);
        break;
      case 4:
        myDelay = 2500;
        pumpTiming(myDelay, 1);
        break;
      case 5:
        myDelay = 60000;
        pumpTiming(myDelay, 0);
        break;
      case 6:
        myDelay = 2500;
        pumpTiming(myDelay, 1);
        break;
      case 7:
        myDelay = 1;
        pumpTiming(myDelay, 0);
        break;
      default:
        pumpStage = 0;
        pumpsFinished = 0;
        startPumps = 0;
        break;
    }
  }
}

void pumpTiming(unsigned long thisDelay, int thisNum) {
  unsigned long currentPumpMillis = millis();
  if (currentPumpMillis - previousPumpMillis >= thisDelay) {
    previousPumpMillis = currentPumpMillis;
    pumpStage++;
    if (thisNum == 1) {
      digitalWrite(9, HIGH);
      //Serial.println("Pump On");
    } else {
      digitalWrite(9, LOW);
      //Serial.println("Pump Off");
    }
  }
}

DangerToMyself:
Well, I didn't get any assistance with the issue above. So, I reworked it a bit and it does what >I THINK< it should now. Test it out and see if it works for you. I don't generally make it a point to write code for folks. But the issue above had me stumped (still does).

The issue is confusion between previousPumpMillis and previousMillis.

previousPumpMillis is set zero at the beginning. CheckTime waits ten seconds before kicking the process off. When it does, it should set previousPumpMillis, but it doesn't, so the at the first check in pumpTiming, previousPumpMillis is still zero and millis is at least 10,000. That difference is greater than 2500, so it immediately moves pump stage to the next.

wildbill:
The issue is confusion between previousPumpMillis and previousMillis.

previousPumpMillis is set zero at the beginning. CheckTime waits ten seconds before kicking the process off. When it does, it should set previousPumpMillis, but it doesn't, so the at the first check in pumpTiming, previousPumpMillis is still zero and millis is at least 10,000. That difference is greater than 2500, so it immediately moves pump stage to the next.

I think I understand what you're saying. However, the last code I posted above uses the EXACT same timing set up. The only difference is the calls to serial.print/digital.write were called in the switch case causing them to be ran every time through loop. The latter code calls them in the timing function so they are only called once when the timer is up.

So, while I think I see where you are coming from. I don't see the WHY of it all.

As far as I can see, your later code has the same defect.