Arduino Forum

Using Arduino => LEDs and Multiplexing => Topic started by: iriseth on Jul 13, 2020, 09:47 am

Title: event is not properly executing when using millis in "else if" statement
Post by: iriseth on Jul 13, 2020, 09:47 am
I'm working on a simple project pulls up a relay for 5, 30, 90 minutes based on a keypress. (like a simple countdown timer) the goal is to put the relay LOW after the time passed.
I've been adding 3 leds to control what's going on + a single button
For some reason, the led and the relay is not getting to LOW state once the timer reaches the time.
seems that the led on the relay shows that its low, but I can't actually hear that the contactors switch, also the led remains up. any ideas?

I found a ton of issues with my code in the meantime. millis() is not starting only when the program loads (needs to figure out where to reset/start the countdown) (relay will gets pulled down after time pass without keypress...)

also the original problem -> why the led is not pulled down+where to reset states after the end of each cycle....


here's my code:

Code: [Select]
long halfhour = 1800000; // 30 min
long hour = 3600000; // 3600000 milliseconds in an hour
long ninetymin = 5400000; //90 minutes
long fifteenmin = 900000; // 15 min
long fivemin = 300000; // 5 min
long minute = 60000; // 60000 milliseconds in a minute

const int buttonPin = 12;
const int led1 = 9;
const int led2 = 8;
const int led3 = 5;
const int relay1 = 10;
unsigned long currentMillis;
unsigned long startMillis;

int counter = 0;
void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(relay1, OUTPUT);
}


void loop()
{
  int buttonState;
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW) // light the LED
  {
    counter++;
    delay(150);
  }

  if (counter == 0)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(relay1, LOW);
  }
  
  else if (counter == 1)
  {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
//    delay (5000);
    digitalWrite(relay1, HIGH);
    if (millis() - startMillis >= ninetymin) {
    digitalWrite(led2, HIGH);
    digitalWrite(relay1, LOW);
    startMillis = currentMillis;  
     }
   }
  else if (counter == 2)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
//    delay (5000);
    digitalWrite(relay1, HIGH);
    if (millis() - startMillis >= hour) {
    digitalWrite(relay1, LOW);
    digitalWrite(led2, LOW);
     startMillis = currentMillis;
    }  
  }

  else if (counter == 3)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
//    delay (5000);
    digitalWrite(relay1, HIGH);
    if (millis() - startMillis >= minute) {
    digitalWrite(relay1, LOW);
    digitalWrite(led3, LOW);
    startMillis = currentMillis;
    }  
  }

  else
  {
    counter = 0;
  }
}
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: Grumpy_Mike on Jul 13, 2020, 10:26 am
Can you post the schematic of you setup please.

Note you should be looking for when the buttons BECOMES pressed not when it is pressed.
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: noiasca on Jul 13, 2020, 10:59 am
can you try to initialize your longs with a value as long?

and by the way, why long and not unsigned long?

Code: [Select]

unsigned long halfhour = 1800000UL; // 30 min
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: iriseth on Jul 13, 2020, 11:46 am
hi, thanks much for your help / suggestion.
updated to use UL. but this is just a misc thing :)

Code: [Select]
unsigned long halfhour = 1800000UL; // 30 min
unsigned long hour = 3600000UL; // 3600000 milliseconds in an hour
unsigned long ninetymin = 5400000UL; //90 min
unsigned long fifteenmin = 900000UL; // 15 min
unsigned long fivemin = 300000UL; // 5 min
unsigned long minute = 60000UL; // 60000 milliseconds in a minute

const int buttonPin = 12;
const int led1 = 9;
const int led2 = 8;
const int led3 = 5;
const int relay1 = 10;
unsigned long currentMillis;
unsigned long startMillis;

int counter = 0;
void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(relay1, OUTPUT);
}


void loop()
{
  int buttonState;
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW) // light the LED
  {
    counter++;
    delay(150);
  }

  if (counter == 0)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(relay1, LOW);
  }
 
  else if (counter == 1)
  {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
//    delay (5000);
    digitalWrite(relay1, HIGH);
   
    if (millis() - startMillis >= ninetymin) {
    digitalWrite(led2, HIGH);
    digitalWrite(relay1, LOW); 
     }
    startMillis = currentMillis;
   }
  else if (counter == 2)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
//    delay (5000);
    digitalWrite(relay1, HIGH);
    if (millis() - startMillis >= hour) {
    digitalWrite(relay1, LOW);
    digitalWrite(led2, LOW);
     startMillis = currentMillis;
    } 
  }

  else if (counter == 3)
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
//    delay (5000);
    digitalWrite(relay1, HIGH);
    if (millis() - startMillis >= minute) {
    digitalWrite(relay1, LOW);
    digitalWrite(relay1, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led3, LOW);
    startMillis = currentMillis;
//    digitalWrite(relay1, LOW);
//    digitalWrite(led3, LOW);
    } 
  }

  else
  {
    counter = 0;
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(relay1, LOW);
  }
}
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: iriseth on Jul 13, 2020, 11:58 am
have no sketch really, but a photo of the current circuit. will check how to control the button to see when it BECOME pressed. not sure at this stage what's the difference. Also the point is that the button switches between the modes, so the appropriate leds are lit up, it starts the cycle to wait (though I have to reset the timer somewhere at the beginning of each else statement because now it starts when the program starts) the problem is that the led is not pulling down.
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: Paul__B on Jul 13, 2020, 12:26 pm
(https://forum.arduino.cc/index.php?action=dlattach;topic=695216.0;attach=372911) (https://forum.arduino.cc/index.php?action=dlattach;topic=695216.0;attach=372911)
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: iriseth on Jul 13, 2020, 01:24 pm
I think I finally made this working. will needs some beautify (to wait a few sec before counter start, etc) but it does what I wanted:
Code: [Select]
unsigned long halfhour = 1800000UL; // 30 min
unsigned long hour = 3600000UL; // 3600000 milliseconds in an hour
unsigned long twohours = 7200000; // two hours
unsigned long ninetymin = 5400000UL; //90 minutes
unsigned long fifteenmin = 900000UL; // 15 min
unsigned long fivemin = 300000UL; // 5 min
unsigned long minute = 60000UL; // 60000 milliseconds in a minute

const int buttonPin = 12;
const int led1 = 9;
const int led2 = 8;
const int led3 = 5;
const int relay1 = 10;

unsigned long startMillis;
unsigned long previousMillis = 0;

int counter = 0;
void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(relay1, OUTPUT);
}


void loop()
{
  unsigned long currentMillis = millis();
  int buttonState;
  buttonState = digitalRead(buttonPin);

  if (buttonState == LOW) // light the LED
  {
    counter++;
    delay(150);
  }

  if (counter == 0)
  {
    currentMillis = millis();
    previousMillis = 0;
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(relay1, LOW);
  }
 
  else if (counter == 1)
  {
    currentMillis = millis();
    previousMillis = 0;
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
//    delay (5000);
    digitalWrite(relay1, HIGH);
    if (currentMillis - previousMillis >= ninetymin) {
    counter = 0;
    previousMillis = currentMillis;
    }
  }
  else if (counter == 2)
  {
    currentMillis = millis();
    previousMillis = 0;
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    digitalWrite(relay1, HIGH);
    if (currentMillis - previousMillis >= fivemin) {
    counter = 0;
    previousMillis = currentMillis;
    } 
  }

  else if (counter == 3)
  {
    currentMillis = millis();
    previousMillis = 0;
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
    digitalWrite(relay1, HIGH);
    if (currentMillis - previousMillis >= minute) {
    counter = 0;
    previousMillis = currentMillis;
    } 
  }
  else
  {
    counter = 0;
  }
}
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: Grumpy_Mike on Jul 13, 2020, 03:35 pm
Quote
will check how to control the button to see when it BECOME pressed. not sure at this stage what's the difference.
The difference is that when the button becomes pressed you can detect it but not detect it when the button is constantly held down. In technical terms is is known as triggering on an edge not a level.

To do this you keep a track of the last state of the button and only trigger the increment in the count when the button is LOW and when the current state is not equal to the last state. There is an example in the IDE called state change detection, look at that and try and understand what is happening.

You should not have to have any delays if you write your code correctly.

Replace that long chain of if ... else if statements with a switch ... case structure.
Title: Re: event is not properly executing when using millis in "else if" statement
Post by: (deleted) on Jul 13, 2020, 03:42 pm
(deleted)