Adding a timer without delay

Hello,
I would like to add a timer into my sketch where the solar panel goes to low (see the comment in the sketch). It needs to be for 10 minutes. How do I implement this?

The sketch....

#include "etherShield.h"
#include "ETHER_28J60.h"
#include "Timer.h"

Timer t;
// Define MAC address and IP address - both should be unique in your network
static uint8_t mac[6] = {
 0x54, 0x55, 0x58, 0x10, 0x00, 0x24};  
static uint8_t ip[4] = {
 192, 168, 0, 12}; 
static uint16_t port = 80; // Use port 80 - the standard for HTTP                                     

int loadrelay = 7;
int solarrelay = 6;

int solar_val;
int load_val;
int volt_val;
int voltage;

ETHER_28J60 ethernet;

void setup()
{ 
 pinMode(loadrelay, OUTPUT);
 pinMode(solarrelay, OUTPUT);
 digitalWrite(solarrelay, HIGH);
 digitalWrite(loadrelay, HIGH);
 Serial.begin(9600);
 t.pulse(solarrelay, 20 * 1000, LOW); 

 ethernet.setup(mac, ip, port);
}

void loop()
{
{
 load_val = digitalRead(loadrelay);
 solar_val = digitalRead(solarrelay);
 int sensorValue = analogRead(A0);
 float voltage = sensorValue * (20.0 / 1023.0);
 Serial.println(voltage);

//low battery cutoff
 if(voltage  <12.0){
   digitalWrite(loadrelay, LOW);
   delay(100);
 }
 else{
   digitalWrite(loadrelay, HIGH);
 }  


 
// This is where I would like to add a ten minute timer after the 'else', it needs to keep the the solarrelay LOW.
 
 {
 if(voltage <14.0){ 
   digitalWrite(solarrelay, HIGH);
 }
 else{ 
     t.update();

   //digitalWrite(solarrelay, LOW);  
 }
 }
 
}
 
 { if (ethernet.serviceRequest())
 {
   ethernet.print("<meta http-equiv='refresh' content='1'>");
   ethernet.print("<font face='verdana'>");
   ethernet.print("<center><H1>Remote Management</H1></center>");
   ethernet.print("<p>Solar panel is turned off after batteries reach 14v,  Load is turned off if batteries drop below 12v </p>");
   ethernet.print("
");
   ethernet.print("<h3> Load Status </h3>");
   if( load_val == HIGH){
     ethernet.print("Load Enabled");
   }
   else
   {
     ethernet.print("Load Disabled");
   }
   ethernet.print("<h3> Battery Bank Status </h3>");
   if( solar_val == HIGH){
     ethernet.print("Charging");
   }
   else
   {
     ethernet.print("Discharging");
   }
   ethernet.print("<h3> Solar Panel Status </h3>");
   if( solar_val == HIGH){
     ethernet.print("Enabled");
   }
   else
   {
     ethernet.print("Disabled");
   }

   // ethernet.print("<h3> Battery Bank Voltage </h3>");
   // ethernet.print(voltage);
   ethernet.print("</font>");

   ethernet.respond();

 }

 delay(100);
}
}

Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

The demo Several Things at a Time illustrates how to use millis() for timing.

Briefly, you save the value of millis() at the start of the time period and then keep checking that compared to the latest value of millis() until the desired amount of time has passed.

...R

Do you know how to use millis() ?

You need a global unsigned long variable that keeps the timestamp. It is often called 'previousMillis'.
You need a global boolean flag to indicate that the delay is active.

Start the delay:
1 ) set the timestamp to the millis : previousMillis = millis() ;
2 ) set the boolean flag : delayActive = true;

Check the delay in the loop:
1 ) Only if the delay is active : if ( delayActive ) check the delay : if ( millis() - previousMillis > 10L * 60L * 1000L )
2 ) if that is true, do the code and stop the delay by making the flag false : delayActive = false;

Try to change your sketch and show us your new sketch.
Read number 7 here about your sketch between code tags : http://forum.arduino.cc/index.php/topic,148850.0.html

While I was typing this, Robin2 already wrote about millis() and code tags.

Thanks for the helpful advice :slight_smile:
How does this look? I cannot test at the moment because of the sun having just gone down, I will try it tomorrow.

#include "etherShield.h"
#include "ETHER_28J60.h"


previousMillis = millis() ;
delayActive = true;

// Define MAC address and IP address - both should be unique in your network
static uint8_t mac[6] = {
  0x54, 0x55, 0x58, 0x10, 0x00, 0x24};  
static uint8_t ip[4] = {
  192, 168, 0, 12}; 
static uint16_t port = 80; // Use port 80 - the standard for HTTP                                     

int loadrelay = 7;
int solarrelay = 6;

int solar_val;
int load_val;
int volt_val;
int voltage;

ETHER_28J60 ethernet;

void setup()
{ 
  pinMode(loadrelay, OUTPUT);
  pinMode(solarrelay, OUTPUT);
  digitalWrite(solarrelay, HIGH);
  digitalWrite(loadrelay, HIGH);
  Serial.begin(9600);
  t.pulse(solarrelay, 20 * 1000, LOW); 

  ethernet.setup(mac, ip, port);
}

void loop()
{
  {
    load_val = digitalRead(loadrelay);
    solar_val = digitalRead(solarrelay);
    int sensorValue = analogRead(A0);
    float voltage = sensorValue * (20.0 / 1023.0);
    Serial.println(voltage);

    //low battery cutoff
    if(voltage  <12.0){
      digitalWrite(loadrelay, LOW);
      delay(100);
    }
    else{
      digitalWrite(loadrelay, HIGH);
    }  

    // Solar cutoff

    {
      if(voltage <14.0){ 
        digitalWrite(solarrelay, HIGH);
      }
      else{ 
        if ( delayActive ){
          if ( millis() - previousMillis > 10L * 60L * 1000L )
          { 
            delayActive = false;

            digitalWrite(solarrelay, LOW);  
          }
        }
      }
    }
  }

  { 
    if (ethernet.serviceRequest())
    {
      ethernet.print("<meta http-equiv='refresh' content='1'>");
      ethernet.print("<font face='verdana'>");
      ethernet.print("<center><H1>Remote Management</H1></center>");
      ethernet.print("<p>Solar panel is turned off after batteries reach 14v,  Load is turned off if batteries drop below 12v </p>");
      ethernet.print("
");
      ethernet.print("<h3> Load Status </h3>");
      if( load_val == HIGH){
        ethernet.print("Load Enabled");
      }
      else
      {
        ethernet.print("Load Disabled");
      }
      ethernet.print("<h3> Battery Bank Status </h3>");
      if( solar_val == HIGH){
        ethernet.print("Charging");
      }
      else
      {
        ethernet.print("Discharging");
      }
      ethernet.print("<h3> Solar Panel Status </h3>");
      if( solar_val == HIGH){
        ethernet.print("Enabled");
      }
      else
      {
        ethernet.print("Disabled");
      }

      // ethernet.print("<h3> Battery Bank Voltage </h3>");
      // ethernet.print(voltage);
      ethernet.print("</font>");

      ethernet.respond();

    }

    delay(100);
  }
}

I think you misunderstand my pseudo code.

When the delay should start, that very moment has to be remembered. That is when the previousMillis should be filled with the actual time from millis().

unsigned long previousMillis;
boolean delayActive = false;     // default false, the delay has not started yet


void setup() {
  ...
}


void loop() {
  ...

  // start the delay
  delayActive = true;
  previousMillis = millis();     // timestamp this moment.
}

Thankyou, I think I understand now.

I have added that, silly question but where do I add my 10 min delay in?

I don't know, I didn't understand that part. When should the delay start ?
If the voltage rises above 14.0V the solar should turn off after 10 minutes ?
Or if the voltage rises above 14.0V, the solar must stay off during 10 minutes ?

The millis() is the same as looking at an ordinary clock. For example when boiling an egg. Look at the clock, let's say it is 3:12 pm, that time has be remember. Keep looking at the clock and substract 3:12 from the time until it is 5 minutes. At 3:17 the time has 5 minutes advanced and the egg is ready.

The millis() return an unsigned long, and the value will rollover at 0xFFFFFFFF and start again at 0x00000000. The delay can still be calculated, even during a rollover of millis() by a few rules:
1 ) Use "unsigned long" for variable with millis().
2 ) Remember the time that the delay starts, do not remember the time in the future. That is why 3:12 has to be remembered and not 3:17. Because of the "unsigned long", no negative time can be used. When 3:12 is remembered and the difference is calculated, then everything stays positive and the rollover problem does not occur.