Go Down

Topic: Timer (Read 792 times) previous topic - next topic

rocketboy001

Hello,

I'm just getting started with Arduino and I'm looking for some coding help with a project that I'm starting to work on... I'll give a high level example of what I'm after.

A momentary switch is connected to PIN 2.

The Arduino monitors the state of the switch and if it is HIGH (switch is turned on) it sets the state of digital PIN 3 to HIGH, turning on an LED.

Once digital PIN 2 is LOW (switch is off) it sets digital PIN 3 back LOW (turning off the LED)

If the state if digital PIN 3 is HIGH for longer than, say 5 seconds, the Arduino automatically sets it back to LOW (turning off the LED) and sets digital PIN 4 to HIGH and loops until it's reset.


I have the code from the Arduino button example so I can read the state of the switch and control the state of the LEDs from it but I'm not sure how to do the timer...

Any help is appreciated.

Adam

johnwasser

Use a variable called 'startTime' to store the value of millis() when D3 is set HIGH.  If D3 is HIGH and millis() - startTime > 5000, set D3 to LOW, D4 to HIGH, and execute a "while (1) ;".
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

rocketboy001

Thanks John for your help.

I realized that I was not completely clear - I need the state of the switch monitored so that if it stays on longer than 5 seconds it will put D3 LOW and D4 HIGH.

I'm working on a system to automatically fill a tank and I need to have it so that if the pump switch gets stuck the Arduino will it off after a set period.

So to clarify - The Arduino monitors the state of the switch, when it goes HIGH it turns D3 HIGH. Once the switch is LOW it puts D3 back to LOW and continues to monitor the state of the switch; but if the switch is HIGH for longer than 5 seconds it puts D3 LOW and sets D4 HIGH and stays there until reset.

I've been playing around with the code below and your suggestion helped, the only problem is that the second IF statement only gets executed when the switch is turned off.

Code: [Select]

const int Button = 2;
const int LedGo =  3;
const int LedAlarm =  4;


int ButtonState = 0;
int LedState = 0;
long StartTime = 0;


void setup() {
  pinMode(LedGo, OUTPUT); 
  pinMode(LedAlarm, OUTPUT);   
  pinMode(Button, INPUT); 
}

void loop(){
  ButtonState = digitalRead(Button);
 
  if (ButtonState == HIGH) {       
    digitalWrite(LedGo, HIGH);
    LedState = 1;
    StartTime = millis();
  }
 
  if (LedState = 1 and millis() - StartTime > 5000) {
    digitalWrite(LedGo, LOW);
    digitalWrite(LedAlarm, HIGH);
  }
}

OptimusPrime

Shouldn't the second if not be:
Code: [Select]
if (LedState == 1 and millis() - StartTime > 5000)
Two == ...

rocketboy001

Correct - either way the issue with my code is that the second IF will not execute until the the switch is LOW... as long as the switch remains HIGH it loops in the first IF statement until the switch goes LOW.

It works but I need it to not care about the state of the switch - if D3 and/or the switch are HIGH for too long then I need D3 to go off and D4 to go on.

My coding skills are lacking...

Thanks,

Adam

johnwasser

Code with some fixes and coding hints.
Code: [Select]

const int Button = 2;
const int LedGo =  3;
const int LedAlarm =  4;

bool ButtonState = false;    // HINT: Use type "bool" for true/false or 1/0 values.
bool LedState = false;        // HINT: Use type "bool" for true/false or 1/0 values.
unsigned long StartTime = 0;  // HINT: Time values should "unsigned long"

void setup() {
  pinMode(LedGo, OUTPUT); 
  pinMode(LedAlarm, OUTPUT);   
  pinMode(Button, INPUT); 
}

void loop(){
  ButtonState = digitalRead(Button);
 
// HINT: "ButtonState == 1" is logically equivalent to ButtonState
  if (ButtonState) {       
    digitalWrite(LedGo, HIGH);
    LedState = true;    // HINT: It's good to use 'true' and 'false' constants with bool variables to remind people they are bool
    StartTime = millis();
  }
else {digitalWrite(LedGo, LOW);  LedState = false;}  // HINT: This covers the case of the switch going LOW

// HINT: "LedState == 1" is logically equivalent to LedState
  if (LedState && millis() - StartTime > 5000) {  // HINT: 'and' is defined (somewhere) as '&&' but '&&' will work even if the definition is changed/removed
    digitalWrite(LedGo, LOW);
    digitalWrite(LedAlarm, HIGH);
   while (true) /* Do nothing */ ;  // HINT: This will cause the processor to wait until a reset.
  }
}
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

rocketboy001

Ok below is my code - thanks John for your tips.

This code works: switch goes HIGH and D2 goes HIGH, turning on the LED and it goes off if on for longer than specified. The only problem is that even if the switch goes LOW it still seems to be counting because after the specified time the LED (LedGo) does not come back on...

Code: [Select]

const int Button = 2;
const int LedGo =  3;
const int LedAlarm =  4;

bool ButtonState = false;
bool LedState = false;
unsigned long StartTime = 0;


void setup() {
  pinMode(LedGo, OUTPUT); 
  pinMode(LedAlarm, OUTPUT);   
  pinMode(Button, INPUT); 
}

void loop() {
  ButtonState = digitalRead(Button);
 
  if (ButtonState == true && LedState == false && millis() - StartTime < 5000) {       
    digitalWrite(LedGo, HIGH);
    LedState = true;
    StartTime = millis();
  }
   
  else if (ButtonState == false) {       
    digitalWrite(LedGo, LOW);
    LedState = false;
    StartTime = 0;
  }
 
  else if (ButtonState == true && LedState == true && millis() - StartTime > 5000){
    digitalWrite(LedGo, LOW);
    digitalWrite(LedAlarm, HIGH);
  }

}

rocketboy001

Of note,

As I noted in my last post - If I cycle the switch several times, or turn it on then off and wait then the LED (LedGo) does not come back on if the specified time was reached... what's also noteworthy is that the second LED (LedAlarm) does not come on...

I'm lost.

johnwasser

Did the version I wrote not do what you wanted?
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

rocketboy001

@John

Your code worked - the LED came on when the switch was turned on, and went off when it was turned off. However, the LED (LedGo) would not automatically turn off after the defined time... I'm not sure why so I tried to adapt points from your code to what I had and it works except for the aforementioned issue of it seemingly still counting after the switch first goes HIGH which in turn prevents the LED (LedGo) from coming back on even if it is switched off before the specified time.

Thoughts?

Again, thanks so much for your help, I've already learned a lot really appreciate it.

Adam

johnwasser

I see my mistake...  I was constantly resetting StartTime as long as the switch was on.  Here's the fixed version:

Code: [Select]

const int Button = 2;
const int LedGo =  3;
const int LedAlarm =  4;

bool LedState = false;
unsigned long StartTime = 0;

void setup() {
  pinMode(LedGo, OUTPUT); 
  pinMode(LedAlarm, OUTPUT);   
  pinMode(Button, INPUT); 
}

void loop(){
  if (digitalRead(Button)) {
    // Swich is closed
    if (!LedState) {
      // LED is currently off
      LedState = true; // Light should be on
      StartTime = millis();  // Start the timer
    }
  }
  else {
    // Swich is open
    LedState = false;
  }

  digitalWrite(LedGo, LedState); 

  if (LedState && millis() - StartTime > 5000) {
    // LED has been ON for a full 5 seconds
    digitalWrite(LedGo, LOW);  // Turn it off
    digitalWrite(LedAlarm, HIGH);  // Turn on the alarm
    while (true) /* Do nothing */ ;  // Wait until a reset.
  }
}
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

rocketboy001

@John

Thanks, I'll give the code a try as soon as I get home tonight.

Much appreciated,

Adam

rocketboy001

@John

Thanks for all your help -- the code works perfectly. With just a couple of additions below is what will likely end up being the final version of the code:

Code: [Select]

const int PumpSwitch = 2; // Arduino PIN that the pump switch is connected to
const int Pump =  3; // Arduino PIN that the pump control is connected to
const int AlarmLED =  4; // Arduino PIN that the alarm LED is connected to
const int AlarmSpeaker = 5; // Arduino PIN that the alarm speaker is connected to

bool PumpState = false; // Initializing the pump state as off
unsigned long PumpRunTime = 0; // Initializing the pump running time

// The following set whether the Arduino PINs are inputs or outputs
void setup() {
  pinMode(PumpSwitch, INPUT);
  pinMode(Pump, OUTPUT);
  pinMode(AlarmLED, OUTPUT);
  pinMode(AlarmSpeaker, OUTPUT);
}

void loop(){
  if (digitalRead(PumpSwitch)) { // If the status of PumpSwitch is HIGH then the pump should be on
    if (!PumpState) {
      PumpState = true; // Pump should be on
      PumpRunTime = millis();  // Start the pump running time
    }
  }
// If the status of PumpSwitch is LOW then the pump should be off
  else {
    PumpState = false;
  }

  digitalWrite(Pump, PumpState);
 
// If the pump has been on longer than 5 seconds, turn it off and sound the alarm untill reset

  if (PumpState && millis() - PumpRunTime > 5000) {
    // LED has been ON for a full 5 seconds
    digitalWrite(Pump, LOW);  // Turn it off
    digitalWrite(AlarmLED, HIGH);  // Turn on the alarm LED
    tone (5, 4000); // Sound a 4000 hertz alarm
  while (true);  // Loop here untill reset to prevent the pump from coming back on
  }
}


Again, thank you so much,

Adam

Go Up