Boolean and millis: doing it wrong?

Hi there,

I am still trying to figure out the best way to do this: I have some led (pin9) being dimmed by a button (pin4) and a cooling fan(pin 10) which needs to be on when the leds are on, and also to STAY on for some seconds when the leds are switched off.
I am using boolean debounce and millis, but for some odd reason this only works the first time that I run it on the arduino, if I press the button again the fan doesn't switch on until the leds are off.. pretty confusing. Stupid mistake?

//Milano 0.1

int buttonPin = 4;
int ledPin = 9;
int fanPin = 10;
boolean lastButton = LOW;
boolean currentButton = LOW;
int ledpwmLevel = 0;
int lastLEDtime = 0;
boolean fanOn = false;

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(fanPin, OUTPUT);
  Serial.begin(9600);
}

boolean debounce(boolean last)
{
  boolean current = digitalRead(buttonPin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(buttonPin);
  }
  return current;
}

void loop()
{
  currentButton = debounce(lastButton);
  if (lastButton == LOW && currentButton == HIGH)
  {
    fanOn = true;
    analogWrite(fanPin, 255);
    ledpwmLevel = ledpwmLevel + 85;
    Serial.println("BUTTON");
  }
  
  if (ledpwmLevel > 255)
  {
    ledpwmLevel = 0;
    lastLEDtime = millis();
  }
  analogWrite(ledPin, ledpwmLevel);


if (fanOn && millis() - lastLEDtime > 5000)

{ 
  fanOn = false;
  analogWrite(fanPin, 0);
}
  
  lastButton = currentButton;


}

lastLEDtime is only ever updated when you turn the fan off, so when you hit the button during the intermediate stages, millis() - lastLEDtime is continually ticking. That means the if statement to turn the fan off will only work if the intermediate stages occur within the 5 seconds. You can get rid of the fanOn variable entirely. Instead, check if the analogWrite value for the LED is equal to 0 and it's been over 5 seconds since you turned the LED off.

That would be perfect.. but how do you do it? Did you do anything similar before?
Checking the 5 seconds thing... :blush: and how would you turn the fan on then if you remove the fanOn variable then?

This expression is true even if the LED is still on:

if (fanOn && millis() - lastLEDtime > 5000)

You could write it like this, so that is only true if the LEDs are off:

if (ledpwmLevel  == 0 && fanOn && millis() - lastLEDtime > 5000)

troglodisme:
That would be perfect.. but how do you do it? Did you do anything similar before?
Checking the 5 seconds thing...

You're already doing that.

and how would you turn the fan on then if you remove the fanOn variable then?

You're already doing that. Take out the fanOn variable, and the fan still turns on; you're only using it to turn the fan off.

Hi Peter,

Thanks for your suggestion, pretty good indeed!
Now, the fan stays on all the time which is amazing. But I leave the light on one of the pwm steps for more then 5 seconds then the fan will not go on when the leds go of.. does that make any sense?

Post your code?

Just introduced your bit...

//Milano 0.1

int buttonPin = 4;
int ledPin = 9;
int fanPin = 10;
boolean lastButton = LOW;
boolean currentButton = LOW;
int ledpwmLevel = 0;
int lastLEDtime = 0;
boolean fanOn = false;

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(fanPin, OUTPUT);
  Serial.begin(9600);
}

boolean debounce(boolean last)
{
  boolean current = digitalRead(buttonPin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(buttonPin);
  }
  return current;
}

void loop()
{
  currentButton = debounce(lastButton);
  if (lastButton == LOW && currentButton == HIGH)
  {
     fanOn = true; 
    analogWrite(fanPin, 255);
    Serial.println("FANISON");
    
    
    ledpwmLevel = ledpwmLevel + 85;
    Serial.println("BUTTON");
  }
  
  if (ledpwmLevel > 255)
  {
    ledpwmLevel = 0;
    lastLEDtime = millis();
  }
  analogWrite(ledPin, ledpwmLevel);



if (ledpwmLevel  == 0 && fanOn && millis() - lastLEDtime > 5000)

//if (fanOn && ((millis() - lastLEDtime) > 5000))


{ 
  fanOn = false;
  analogWrite(fanPin, 0);
      Serial.println("FANISOFF");

}
  
  lastButton = currentButton;


}

troglodisme:
But I leave the light on one of the pwm steps for more then 5 seconds then the fan will not go on when the leds go of.. does that make any sense?

Can you describe the problem again? I thought the goal was that the fan went on when the LED went on, and went off five seconds after the LED goes off.