recording "on time" with millis

hi, im having a bit of trouble with timing and millis. i want the arduino to remember how long "fanrelay" has been low in the below code. i then need to write another if statement that says, if fanrelay has been in the LOW state for more than "x amount" of time then set pump relay low. i can figure most of it except i cant figure out how to record only the amount of time fanrelay has been low. if i compare pumpauto to millis then my code wont work right because millis keeps counting while the if statements false. can someone please show me what to do thankyou

 if (autocontrol == 1)
  {
    if ( h1 > 98.00 )
      digitalWrite(fanrelay, LOW); //turn it on
   pumpauto = millis();
    if ( h1 < 81.00 )
      digitalWrite(fanrelay, HIGH);  //turn it off


  }
  if (fanrelay has been on for 20 minutes total between on and off cycles then turn pump on)

if i compare pumpauto to millis then my code wont work right because millis keeps counting while the if statements false.

If you ALWAYS used curly braces with every if statement, that would NOT be the case.

i dont think you understand what im trying to say, what i mean to do is set another pins state after "fanrelay" has been LOW for x amount of time. the problem is i cant visualize how to program it. fanrelay is triggered ON when "h1 humidity" is above 97. then it shuts off when the humidity drops to 81 percent. but i need to somehow compare some time to something and i cant figure it out. example- fanrelay comes on for 30 seconds then its off for an hour. then it comes on for 30 more seconds. then after the fanrelay has been on so many times that 30 sec +14+ 27+ 30 == some trigger to turn on another relay. hopefully you understand. ive been on google for hours and i cant figure it out yet

i dont think you understand what im trying to say

he does...

if ( h1 > 98.00 ) {
      digitalWrite(fanrelay, LOW); //turn it on
      pumpauto = millis();
}

would ensure pumpauto is only recorded when you turn it on.

indentation does not dictate what is in the if. you need braces

if (condition) [b][color=red]{[/color][/b]
   statements to be executed if condition true
   statements to be executed if condition true
   statements to be executed if condition true
   ...
[b][color=red]}[/color][/b]

or

if (condition) [b][color=red]{[/color][/b]
   statements to be executed if condition true
   statements to be executed if condition true
   statements to be executed if condition true
   ...
[b][color=red]}[/color][/b] else [b][color=red]{[/color][/b]
   statements to be executed if condition false
   statements to be executed if condition false
   statements to be executed if condition false
   ...
[b][color=red]}[/color][/b]

You already have a Thread running to 82 Replies on what seems to be the same problem. Why have you started a new one?

...R

but if i update pumpauto and it hasn't been on for 5 hours then its going to jump a huge amount of time that would exceed my interval and not work right. how can i compare pumpauto to somthing taht says hey its been LOW now for a total of 30 minutes in between on and off cycles

seems you have another thread so I won't answer here anymore

do the right thing, don't waste contributors time.

well i cant find that either

robin gave you a link to your other thread

this isn't even the same project so my other thread dose not concern me or relate to the problems im having is this better

if (autocontrol == 1)
  {
    if ( h1 > 98.00 )
      digitalWrite(relay, LOW);
    if ( h1 < 81.00 )
      digitalWrite(relay, HIGH);

      
        if ( relay has been LOW for x amount of time )
      digitalWrite(relay2, LOW);

seems you describe your need there as

im trying to make it count how many times each relay turns on. eventually i would like to be able to convert ms on time into liters per minute

how is this not the same thing?

basically you need

  • record the value of milllis() when you turn it on
  • record the value of millis() when you turn it off
    then the difference is how many milliseconds your thing has been on

of you want to test at any point in time for how long it has been on, subtract the first record from millis()

okay, so i record the value 1000ms when its on, then its on for 3 more seconds so record the value 4000 when its off, but every time when those if statements are true and fales its just going to update the time difference with the current millis and still always be for example 3 seconds apart so i wouldn't know when its lets say 30 minutes apart?

you might have to show me because my adhd is giving me total brain block right now,

#include "DHT.h"
#define tempsensor 2
#define DHTTYPE DHT22

const int relay = 5;  
const int relay2 = 11;

unsigned long relaycurrent = 0;
unsigned long relayprevious = 0;

DHT sensor(tempsensor, DHTTYPE);

unsigned long autocontrol = 0;


void setup() {
pinMode (relay, OUTPUT);
pinMode (relay2, OUTPUT);
sensor.begin();
Serial.println("2=control settting");
}

void loop() {
  
}
  unsigned long Millis = millis();

 float f1 = sensor.readTemperature(true);
  float h1 = sensor.readHumidity(true);


  if (isnan(h1) || isnan(f1)) {
    return;
  }
  
if (Serial.available()) {
    char mode = Serial.read();
    if (mode == '2')
    { Serial.println("Auto Humidity Control enabled");
      autocontrol = 1;
    }

if (autocontrol == 1)
  {
    if ( h1 > 98.00 )
      digitalWrite(relay, LOW);
    if ( h1 < 81.00 )
      digitalWrite(relay, HIGH);

      
        if ( relay has been LOW for x amount of time )
      digitalWrite(relay2, LOW);
  }
}

okay, so i record the value 1000ms when its on

No. You record the value of millis() when it turns on not when it is on.

but whats going to note the time to compare to? im trying to explain what i want to do the best i can. i cant figure it out i know how to update a variable with the current millis it turns on. but how can i constantly compare it to something that knows how long relay has been on. relay don't run on a timer so its on and off time are determined by humidity. relay may only be on for 15 seconds at a time. i need to figure out how i can count the total amount of time realy has been low all together no matter how long its been off. then after it hits a threshold do something else.

UKHeliBob:
No. You record the value of millis() when it turns on not when it is on.

i think this is what your trying to say to do but its going to just keep updating the current and previous states with the amount of time its been on since its last off state and that's not going to work. because it don't keep adding the amount of ms its been on to the last ms it was on untill it adds up to the threshold?!?

#include "DHT.h"
#define tempsensor 2
#define DHTTYPE DHT22

const int relay = 5;  
const int relay2 = 11;

unsigned long relaycurrent = 0;
unsigned long relayprevious = 0;
unsigned long relay2oninterval = 8777UL; 
unsigned long relay2offinterval = "untill relay has been on a total of 30 throughout its on off times"; 
unsigned long interval = 0;
unsigned long interval2 = 0;

DHT sensor(tempsensor, DHTTYPE);

unsigned long autocontrol = 0;


void setup() {
pinMode (relay, OUTPUT);
pinMode (relay2, OUTPUT);
sensor.begin();
Serial.begin(9600);
Serial.println("2=control settting");
interval = relay2oninterval;
interval2 = relay2offinterval;

}

void loop() {
  

  unsigned long Millis = millis();

 float f1 = sensor.readTemperature(true);
  float h1 = sensor.readHumidity(true);


  if (isnan(h1) || isnan(f1)) {
    return;
  }
  
if (Serial.available()) {
    char mode = Serial.read();
    if (mode == '2')
    {
      Serial.println("Auto Humidity Control enabled");
      autocontrol = 1;
    
}
if (autocontrol == 1)
  {
    if ( h1 > 98.00 )
      digitalWrite(relay, LOW);
    relaycurrent = millis;
      {
    if ( h1 < 81.00 )
    relayprevious = millis;
      digitalWrite(relay, HIGH);
      }

   if (relaycurrent - relayprevious >= 3000000 )
    digitalWrite(relay2, LOW);
    interval = relay2oninterval;
    Serial.println ("cycle");
  }
  else {
       digitalWrite(relay2, HIGH);
       interval2 = relay2offinterval;
  }
}
   
}

how would it work if relay previous was update every time relay turns off. it would somehow have to subtract the time difference of the two and add only the difference to another unsigned long. but i cannot for the life of me figure out how to write it i'm stuck..

think this is what your trying to say to do

It's not.

You need to read the sensor and if the value is now above the threshold but was below the threshold the previous time that it was read then save the start time from millis(). Using this logic the start time will not be continuously updated.

The StateChangeDetection example in the IDE shows how to do it. Basically, save the value read from the sensor before reading it again then compare the previous value with the current value to determine whether it is now above the threshold.

By the way, in the code snippet you posted above you are still not consistently using curly brackets around the block of code to be executed when the test in the if returns true

    if ( h1 > 98.00 )
      digitalWrite(relay, LOW);
    relaycurrent = millis;

Unless, of course you want relaycurrent = millis; to be executed unconditionally, which you don't

how would it work if relay previous was update every time relay turns off.

That is not how you save or use the previous value. See reply #17

I cant even get this to compile. and if the relayState was TRUE then it wouldn't run the part of the if statement to turn relay off when the humidity is below 81. please show me what you mean. i cannot have it hold relay low the entire time its above 81. it just needs to set it low one time in case some other event calls for a state change. this still does not show me how to do what im trying to do. not to mention i DO NOT want it to count the amount of time between ON and OFF because it will not always be the same. i need it to count the time relay is LOW and pause the timer when its high, then when it goes LOW again add the elapsed time to the previous elapsed time until previous elapsed time gets to a threshold

#include "DHT.h"
#define tempsensor 2
#define DHTTYPE DHT22

const int relay = 5;  
const int relay2 = 11;

int relayState = 0;
int relayPrevState = 0;

unsigned long relaycurrent = 0;
unsigned long relayprevious = 0;
unsigned long relay2oninterval = 8777UL; 
unsigned long relay2offinterval = "untill relay has been on a total of 30 throughout its on off times"; 
unsigned long interval = 0;
unsigned long interval2 = 0;

DHT sensor(tempsensor, DHTTYPE);

unsigned long autocontrol = 0;


void setup() {
pinMode (relay, OUTPUT);
pinMode (relay2, OUTPUT);
sensor.begin();
Serial.begin(9600);
Serial.println("2=control settting");
interval = relay2oninterval;
interval2 = relay2offinterval;

}

void loop() {
  

  unsigned long Millis = millis();

 float f1 = sensor.readTemperature(true);
  float h1 = sensor.readHumidity(true);


  if (isnan(h1) || isnan(f1)) {
    return;
  }
  
if (Serial.available()) {
    char mode = Serial.read();
    if (mode == '2')
    {
      Serial.println("Auto Humidity Control enabled");
      autocontrol = 1;
    
}


relayState = digitalRead(relay); 

if (relayState != relayPrevState) {

if (autocontrol == 1 )
{
    if ( h1 > 98.00 )
      digitalWrite(relay, LOW);
    relaycurrent = millis;
    relayState = LOW;
      {                                               
    if ( h1 < 81.00 )
    relayprevious = millis;
      digitalWrite(relay, HIGH);
      relayState = HIGH;
      }

   if (relaycurrent - relayprevious >= 3000000 )
    digitalWrite(relay2, LOW);
    interval = relay2oninterval;
    Serial.println ("cycle");
  }
  else {
       digitalWrite(relay2, HIGH);
       
       interval2 = relay2offinterval;
  }
}
   
}