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

    }
  }
}
13
  • 1
    what problem are you struggling with? ... what is your question?
    – jsotola
    Nov 5, 2020 at 4:45
  • @jsotola 1st checking and 3nd checking only working Nov 5, 2020 at 4:47
  • 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 5, 2020 at 4:52
  • 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 5, 2020 at 4:55
  • 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 5, 2020 at 5:59

2 Answers 2

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;
    }
}
2
  • I dont know how to thank you , it work like charm Nov 5, 2020 at 11:29
  • Thanks for understanding my goal :) Nov 5, 2020 at 11:31
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.

12
  • Thanks , when i change the interval time to 20000 OnTime long OffTime change automatically to 20000 @towe Nov 5, 2020 at 8: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 5, 2020 at 8:46
  • Yes , i want the interval time exactly, i don't know how to check :( Nov 5, 2020 at 8: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 Nov 5, 2020 at 8: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 5, 2020 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.