Using Millis to turn relay on and off

I am having difficulty understanding and applying the Millis() function.

What I am trying to do is run a water pump in a timed sequence, while other loops are running. So I have a water pump that I want to turn on and have it run for 5 minutes, and then do nothing for 2 hours. After that it will repeat the loop. This section of code is to water plants

While this is going on I will be running an ultra sonic sensor to monitor Reservoir tank level, and tap water rely and flowmeter, PH sensor and water temp to monitor the reservoir tank and keep it full. The system will be 24/7 run time.

My question is, can the Millis function do this? If so can someone help me with the code? I have watched many tutorial videos on the Millis function and just can seem to get a clear understand of how to keep the loop going.

Any help would be greatly appreciated.

I have a water pump that I want to turn on and have it run for 5 minutes, and then do nothing for 2 hours.

That is almost exactly what the BlinkWithoutDelay example does. The only change needed is to change the length of the period each time the output state changes

You can also take a look at several things at the same time to see how to structure your code to achieve all of this "at the same time"

1 Like

I had looked at the BlinkWithoutDelay example. However, my timing is not symmetric and I was unable to determine how to add another statement that told the pump relay to turn off for 2 hours. I am currently looking at the "several things example. Thank you for the feedback.

    if (ledState == LOW)
    {
      ledState = HIGH;
      //set interval to short period here
     }
    else
    {
      ledState = LOW;
      //set interval to long period here
    }

Adjust the lengths of the interval to suit your needs

Hello,
There is a simple way to create timers: you need to add to 2 files to your sketch and then you can write code like below (code that does not uses waits and does not use millis() as wawiTimer encapsulates millis(). (the code below inverts 2 booleans, one each 250ms and one each 500ms creating blinkbits with variable frequency).

// create blinkbits:
wawiTimer tBlink250, tBlink500;
void UtilsLoop()
{
  if (tBlink250.isZero())
  {
    tBlink250.setMs(250);
    blink250=!blink250;  
  }
  if (tBlink500.isZero())
  {
    tBlink500.setMs(500);
    blink500=!blink500;  
  }

  tBlink250.loop(); // 250 ms on
  tBlink500.loop(); // 500 ms
}

It is part of a tutorial demo I have put on the Arduino project hub.

Arduino project hub demo

This movie shows a peristaltic pump that is driven by a pulse width solid state relay.

The application contains blinking led's that blink in parallel with the main program running.

The program contains a finite state machine to do the job = simple way to manage complex automation jobs.
And there is a 40 page step by step manual (including demo sketches) how to do. It describes in detail the source code of the timer files and also shows you how to build a finite state machine that is able to do your job reliably.

Best Regards,
Johi.

Johi,

The link to the project doesn't work. I will try to search for it. As well you mention 2 files that need to be added. Can you tell me what there are?

Thanks

blh64,

I am messing with the "servalThings" program. I left the program alone other than switching "onBoardLedPin" to pin 8, and I only have a relay connect to pin 8. I started messing with the "onBoardLedInterval" and "blinkDuration" times. I found that if these numbers get larger, eg. 60000 or 60sec, the program doesn't work. I can't figure out why. It works perfect when times are set to 40000. Any ideas.

Hi,

there is the hard way of understanding posting a link to long article

and there is a more easy way to understand the basic principle first:

as an allday example with easy to follow numbers
delay() is blocking. As long as the delay is "delaying" nothing else of the code can be executed.
Now there is a technique of non-blocking timing.
The basic principle of non-blocking timing is fundamental different from using delay()

You have to understand the difference first and then look into the code.
otherwise you might try to "see" a "delay-analog-thing" in the millis()-code which it really isn't
Trying to see a "delay-analog-thing" in millis() makes it hard to understand millis()
Having understood the basic principle of non-blocking timing based on millis() makes it easy to understand.

imagine baking a frosted pizza
the cover says for preparation heat up oven to 200°C
then put pizza in.
Baking time 10 minutes

You are estimating heating up needs 3 minutes
You take a look onto your watch it is 13:02 (snapshot of time)
You start reading the newspaper and from time to time looking onto your watch
watch 13:02 not yet time
watch 13:03 not yet time
watch 13:04 not yet time 13:04 - 13:02 = 2 minutes is less than 3 minutes
watch 13:05 when did I start 13:02? OK 13:05 - 13:02 = 3 minutes time to put pizza into the oven

New basetime 13:05 (the snapshot of time)
watch 13:06 not yet time
watch 13:07 not yet time
watch 13:08 not yet time (13:08 - 13:05 = 3 minutes is less than 10 minutes
watch 13:09 not yet time
watch 13:10 not yet time
watch 13:11 not yet time
watch 13:12 not yet time
watch 13:13 not yet time
watch 13:14 not yet time (13:14 - 13:05 = 9 minutes is less than 10 minutes
watch 13:15 when did I start 13:05 OK 13:15 - 13:05 = 10 minutes time to eat pizza (yum yum)

You did a repeated comparing how much time has passed by
This is what non-blocking timing does

In the code looking at "How much time has passed by" is done

currentTime - startTime >= bakingTime

bakingTime is 10 minutes

13:06 - 13:05 = 1 minute >= bakingTime is false
13:07 - 13:05 = 2 minutes >= bakingTime is false
...
13:14 - 13:05 = 9 minutes >= bakingTime is false
13:15 - 13:05 = 10 minutes >= bakingTime is TRUE time for timed action!!

if (currentTime - previousTime >= period) {

it has to be coded exactly this way because in this way it manages the rollover from Max back to zero
of the function millis() automatically

You should write a testcode that uses much smaller periods
1 second and 5 seconds and for testing making an LED blink The difference is long enough to easily see it.

Or using the serial monitor to output different words like "pump on" and "pump off"

if you post your code that you have so far it will be much easier to explain how to implement this functionality

best regards Stefan

I had looked at the BlinkWithoutDelay example. However, my timing is not symmetric

So?

pnorsworthy:
blh64,

I am messing with the "servalThings" program. I left the program alone other than switching "onBoardLedPin" to pin 8, and I only have a relay connect to pin 8. I started messing with the "onBoardLedInterval" and "blinkDuration" times. I found that if these numbers get larger, eg. 60000 or 60sec, the program doesn't work. I can't figure out why. It works perfect when times are set to 40000. Any ideas.

pnorsworthy:
blh64,

I am messing with the "servalThings" program. I left the program alone other than switching "onBoardLedPin" to pin 8, and I only have a relay connect to pin 8. I started messing with the "onBoardLedInterval" and "blinkDuration" times. I found that if these numbers get larger, eg. 60000 or 60sec, the program doesn't work. I can't figure out why. It works perfect when times are set to 40000. Any ideas.

without seeing the code I estimate the variables that you are using are integers.
integers can hold values between +-32768
for millis() you should always use variables of type unsigned long
So again if you post the code you are working with a much more detailed analyses can be done
best regards Stefan

TheMemberFormerlyKnownAsAWOL:
So?

TheMemberFormerlyKnownAsAWOL:
So?

asawol you should be behind counting up postings at high-speed

StefanL38:
asawol you should be behind counting up postings at high-speed

And now in English?

Stop making things complicated

No need for a library or extra files, just our old friend BlinkWithoutDelay and two extra lines of code, as illustrated in reply #4

If you are prepared to declare an array to hold the 2 intervals you can even do it with just that array and a minor modification to 1 lines of code in BWoD

const int ledPin =  LED_BUILTIN;
int ledState = LOW;
unsigned long previousMillis = 0;
const unsigned long intervals[] = {1000, 5000}; //the two intervals

void setup()
{
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervals[ledState])
  {
    previousMillis = currentMillis;
    if (ledState == LOW)
    {
      ledState = HIGH;
    }
    else
    {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}

TheMemberFormerlyKnownAsAWOL:
And now in English?

asawol you claim to ask didactic stimulating questions for yourself.

Now what I've learned from this is

It is best to ignore these questions.
And to concentrate on explanations for the thread opener.

Bob,

if the TO is very new to programming implementing an array make things even harder to understand.
best regards Stefan

No, I want to stimulate auto-didactism.

Didactism has prescriptive, pejorative overtones, in my opinion.

if the TO is very new to programming implementing an array make things even harder to understand.

Hence my simple solution proposed in replies #1 and #4

However, this could be a nice gentle introduction to arrays if he/she uses my alternative solution

Here is the link to the peristaltic pump project --
https://create.arduino.cc/projecthub/394412/dosing-peristaltic-pump-pwm-ssr-hx711-scale-and-an-fsm-da9b06

copy & paste into the address bar (trying to post links is a ... here anymore)

That link does not work for me