3

I've a exhaust fan that runs when the humidity is high. When the exhaust fan is on it should work for 3 minutes and should wait another 5 minutes to on. I am a beginner to this struggling for almost 2 days now. with this code the led just blink and off

int ledPin =  2;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis2 = 0;
unsigned long previousMillis = 0;
long interval = 10000;           // in
long OnTime = 1000;           // milliseconds of on-time
long OffTime = 2000;          // milliseconds of off-time

void setup()
{

  Serial.begin(9600);
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop()
{

  unsigned long currentMillis2 = millis();

  if (currentMillis2 - previousMillis2 > interval) {
    // save the last time you blinked the LED



    // check to see if it's time to change the state of the LED
    Serial.print("hellohh ");
    unsigned long currentMillis = millis();

    if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
    {
      Serial.print("hellohh2 ");
      ledState = LOW;  // Turn it off
      previousMillis = currentMillis;  // Remember the time
      digitalWrite(ledPin, ledState);  // Update the actual LED
    }
    else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
    {
      Serial.print("hellohh 3");
      ledState = HIGH;  // turn it on
      previousMillis = currentMillis;
      previousMillis2 = 0; // Remember the time
      digitalWrite(ledPin, ledState);    // Update the actual LED

    }
  }
}
  • 1
    what problem are you struggling with? ... what is your question? – jsotola Nov 05 '20 at 04:45
  • @jsotola 1st checking and 3nd checking only working – user2037091 Nov 05 '20 at 04:47
  • In your serial monitor, what is printed? hellohh / hellohh2 / hellohh 3? Can you edit your question and copy/paste some of the output so we can see what logic branches are being followed. – Nick Gammon Nov 05 '20 at 04:47
  • You said 3 minutes and 5 minutes in your question, but I don't see any reference to that in the code (3 minutes would be 3 * 60 * 1000 milliseconds = 180000). – Nick Gammon Nov 05 '20 at 04:49
  • @NickGammon now just trying with some leds, – user2037091 Nov 05 '20 at 04:50
  • @NickGammon one exhaust fan when the humidly is high for 3 minutes, if the humidity still high fan will on again i need 5 minutes gap between the next fan on thats what i meant – user2037091 Nov 05 '20 at 04:52
  • 1
    Your first test of `if (currentMillis2 - previousMillis2 > interval) {` is for a longer interval than 1000/2000 so I expect weird behaviour. You haven't said what is actually happening. Saying a "checking is working" is a bit non-specific. What is being printed? Does the LED light? – Nick Gammon Nov 05 '20 at 04:52
  • now ledblink and off @NickGammon – user2037091 Nov 05 '20 at 04:53
  • 1
    This isn't a forum. Please **edit your question** and supply extra information, like what the serial output is, and what is actually happening. Comments are **not for debugging the problem**. – Nick Gammon Nov 05 '20 at 04:55
  • okay @NickGammon new to things, no idea how to do things sorry – user2037091 Nov 05 '20 at 04:56
  • 1
    I realise that you are new, and I have suggested that you do certain things, which you haven't done as I write this. I recommend that you follow my earlier suggestions about documenting your issue better, and then we may be able to help you better. – Nick Gammon Nov 05 '20 at 05:59
  • Also the question and comments (multiple fans for 3 / 5 minutes) and your code (1 second on / 2 second off LED) don't seem to match at all. – towe Nov 05 '20 at 06:40
  • @towe just testing but it stuck – user2037091 Nov 05 '20 at 06:53

2 Answers2

5

If I understand correctly, you wrote an example code that switches an LED between two states (on and off), and you are stuck because the actual problem you want to solve is more complex than that. And indeed, it seems to me that you want to manage a system with three possible states: it can be on or off but, when it is off, it can be ready to turn on if the humidity is high, or it can be in the five minute wait.

The most natural way to think about this kind of systems is a finite state machine, or FSM. An FSM is defined by the set of states it can be in, the conditions that make it switch states, and the actions performed when doing so. If I correctly understood your specification, your system can be either READY, RUNNING or WAITING, and the transitions are:

  • when READY, if the humidity is too high it switches to RUNNING; it turns the fan on when doing so
  • when RUNNING, if it has been running for 3 minutes, it switches to WAITING and turns the fan off
  • when WAITING, if it has been waiting for 5 minutes, it switches to READY

This can be illustrated by the following state diagram:

state diagram

You should correct me at this stage if I did not fully understand your specification. Otherwise, if the state diagram matches your requirements, converting it to code is quite straightforward:

const uint32_t MINUTE = 60000;

void loop() {
    static enum {READY, RUNNING, WAITING} state;
    static uint32_t last_change;
    uint32_t now = millis();
    switch (state) {
        case READY:
            if (humidity_is_high()) {
                turn_fan_on();
                state = RUNNING;
                last_change = now;
            }
            break;
        case RUNNING:
            if (now - last_change >= 3 * MINUTE) {
                turn_fan_off();
                state = WAITING;
                last_change = now;
            }
            break;
        case WAITING:
            if (now - last_change >= 5 * MINUTE) {
                state = READY;
            }
            break;
    }
}
Edgar Bonet
  • 39,449
  • 4
  • 36
  • 72
2

For your current issue (turning LEDs on and off after 1s / 2s, much of your code can be simplified:

int ledPin =  2;     // Number of the LED pin
int ledState = LOW;  // ledState used to set the LED
unsigned long TimeLedOFF = 0;     //Time at which the LED was last turned off
unsigned long TimeLedON = 0;      //Time at which the LED was last turned on
unsigned long TimeLastCheck = 0;  //Time at which the next LED state was determined last
long interval = 100;  // How often to check for changes in environment - should be shorter than your switching durations
long OnTime = 1000;   // Milliseconds of on-time
long OffTime = 2000;  // Milliseconds of off-time

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); // set the LED pin as output:
}

void loop() {
  if (millis() - TimeLastCheck > interval) { //If the LED state should be evaluated again - "interval" has passed
    TimeLastCheck = millis();

    Serial.println("Determining next LED state");

    if (ledState == HIGH && (millis() - TimeLedON >= OnTime)) { //If LED was on for long enough
      Serial.println("OnTime elapsed. Turning off.");
      TimeLedOFF = millis(); // Remember the time
      ledState = LOW;        // Turn LED flag off
      digitalWrite(ledPin, ledState); // Update the actual LED
    }
    else if (ledState == LOW && (millis() - TimeLedOFF >= OffTime)) { //If LED was off for long enough
      Serial.println("OffTime elapsed. Turning on.");
      TimeLedON = millis(); // Remember the time
      ledState = HIGH;  // turn it on
      digitalWrite(ledPin, ledState);    // Update the actual LED
    }
  }
}

This results in the LED being turned on for one second, then off for two seconds.

towe
  • 833
  • 4
  • 14
  • Thanks , when i change the interval time to 20000 OnTime long OffTime change automatically to 20000 @towe – user2037091 Nov 05 '20 at 08:42
  • Yes, since you only ever check whether something should happen once per "interval time". By then, the other two durations have long since passed. What do you need / want interval time for exactly? – towe Nov 05 '20 at 08:46
  • Yes , i want the interval time exactly, i don't know how to check :( – user2037091 Nov 05 '20 at 08:50
  • my humidity sensor keep checking the temp and hum , i dont want to keep my fan working all time, so i need a interval time 5m if needed – user2037091 Nov 05 '20 at 08:55
  • That's not what the "interval time" does in your (or my) sketch - the fan is turned off once OnTime has passed. – towe Nov 05 '20 at 10:32
  • Yes, i checked. How can i achieve that ? can you show me an example? – user2037091 Nov 05 '20 at 10:33
  • Just to clarify I understand you correctly: You read the humidity level. If it's too high, you want the fan to run for at most three minutes. Then, it must wait for five minutes, until it checks the humidity again and decides whether or not to turn the fan back on (for three minutes)? – towe Nov 05 '20 at 10:38
  • Yes, right. if(humidity < 50){ fogger();} else if (humidity > 70){ digitalWrite(DHTpower, LOW); // exhuast fan on here }else if ((temp > 32) && (hum < 55)) { fogger(); } – user2037091 Nov 05 '20 at 10:41
  • sensor will keep checking the humidity once the fan on for 3 minutes , must need 5 minutes gap to on again for 3 minutes – user2037091 Nov 05 '20 at 10:47
  • So it'll constantly check humidity, and turn on the fan if your level surpasses 70? What does the fogger() function do? – towe Nov 05 '20 at 10:51
  • fogger is actually pump it on when the humidity is below 50 – user2037091 Nov 05 '20 at 11:03
  • thanks towe for your time and effort , i got the code. Thanks for your help – user2037091 Nov 05 '20 at 11:30