PLC guy needs abit of help with timers

Hi guys,
i am having a few issues with timers, there implementation, and my understanding for them. I am used to industrial PLC's and how there timers operate, but i am struggling in a big way with arduino's.

what i am trying to achieve is once a switch has been pressed for 2 seconds an LED (for this example) to come on and stay on for say 5 seconds, 10 seconds later the system reset its self.

my problem lies in trying to time the initial switch pressing, i have tried so called "debounce timers" yet none seem to work in the way i require. If anyone could point me in the way of an example that would be epic 8) .

This is where i am at :-

int SW1=12; 
int value_1, value_2=0; 
int LED=13; 
byte Flag=0; 
int i=0; 
int a=0;

void setup() 
{ 
    pinMode(SW1, INPUT); 
    digitalWrite(SW1, HIGH); 
    pinMode(LED, OUTPUT); 
} 

void loop()
{ 
    value_1=digitalRead(SW1); 

    if(!value_1) 
    { 
	delay(50);  
	value_2=digitalRead(SW1); 
	if(!value_2) 
	{ 
	    Flag=1; 
	    do{ 
	    }while(!digitalRead(SW1)); 
	} 
    } 
	
    if(Flag==1)i++; 
    if(i>3000) 
    { 
	digitalWrite(LED, HIGH); 
        delay (5000);
        digitalWrite(LED, LOW);
        delay (1000);
	while(1); 
    } 
	
    delay(1); 
}

just incase you need the info i have the "Franzis Tutorial Kit For Arduino" the board looks like a uno, but its a Duemilanove with the ATmega168 chip

i should also add that i have had a search, but my google'fu has let me down thus far

First, get rid of delay(). Wipe it from your mind. You aren't reading buttons or anything while the in the delay. Use millis() to record the time that the switch was pressed (startTime = millis()). In your loop(), check that the switch is still pressed and the what difference between the recorded millis() and the present millis() is . If pressed and time less than 2000, keep checking. if unpressed and time less than 2000, do something. if pressed and time greater than or equal 2000 (never equal by itself) then your button was pressed the 2 seconds.

Hi Ugly,

I just put this code together. I hope it will get you going:

/*    Umbrasias / LegoTronics 2015    */

#include <Bounce.h>
#define BTN_PIN 4
#define LED 13

Bounce btn_bounce = Bounce(BTN_PIN, 5);
boolean sequence_activated = false;
int time_before = 0;

void setup() {
  pinMode(BTN_PIN, INPUT);
  pinMode(LED, OUTPUT);
  //Serial.begin(9600);
}

void loop() {
  // Update the debouncer
  btn_bounce.update();

  // If the button is pressed:
  if(!sequence_activated && btn_bounce.read() == HIGH) {
    time_before = millis();            // read current time.
    sequence_activated = true;         // "starts" the sequence.
    //Serial.println("Sequence activated"); 
  }
  
  // If the button is released (and the sequence is "started"):
  else if(sequence_activated && btn_bounce.read() == LOW) {   

    // Current time - time before button press is equal or greater than 2 sec:
    if(millis() - time_before >= 2000) {  
      //Serial.println("Button released after min. 2 sec. turning on LED");       
      digitalWrite(LED, HIGH);            // Turn LED on.
      delay(5000);                        // Wait 5 sec.
      digitalWrite(LED, LOW);             // Turn LED off.
      //Serial.println("Turned off LED"); 
      delay(5000);                        // Wait another 5 sec.
    }
    
    sequence_activated = false;         // Reset sequence.
    //Serial.println("Sequence reset"); 
  }
}

As groundfungus mentions, you have to avoid delay() as it is blocking and you cannot read input in the meantime (you can interrupt though). In my example I am using millis(), which will get you the current millis, from the sketch started running. Be aware that the millis() function will overflow at some point (around 50 days).

In the “sequence section” I am using delay, as I thought blocking does not spoil anything at that point. But you can use the same approach, to get rid of those calls here as well.

Have a look at how millis() is used to manage timing in several things at a time. And how there is no need for a bounce library.

...R

Considered that #0 seems to be fairly new to Arduino and the way things work, using a library like debounce can certainly make things less complex and help to focus on the problem at hand and not trying to figure out why certain things fire numerous times, when not expected. Libraries are good for beginners to move some of the complexity and make the main problem code more consumable.

However you millis () post is great Robin2 and i strongly agree with it :slight_smile:

Thanks guys that's been a great help

@umbrasias, Many thanks for the code example, just one thing i noticed while testing, if i release my button, the timer dosn't appear to reset, in such a way where i can "pulse" the button and eventually it activates the cycle.

That's given me an amazing boost, i am sure i will get it figured out :slight_smile:

Woooo Hoooo, think i have it figured (time for a beer)

Major thanks again guys!!!

let me say that this is heavily hacked, and i have not completed the notes yet (bad practice i know, but i like to get things working then spend time on notes etc)

/*    Umbrasias / LegoTronics 2015    */

#include <Bounce.h>
#define BTN_PIN 12
#define LED 13

Bounce btn_bounce = Bounce(BTN_PIN, 5);
boolean sequence_activated = false;
int time_before = 0;
byte Flag=0; 

void setup() {
  pinMode(BTN_PIN, INPUT);
  pinMode(LED, OUTPUT);
  
  //Serial.begin(9600);
}

void loop() {
  // Update the debouncer
  btn_bounce.update();

  // If the button is pressed:
 // if(!sequence_activated && btn_bounce.read() == HIGH) {
   // time_before = millis();            // read current time.
//     sequence_activated = true;         // "starts" the sequence.
    //Serial.println("Sequence activated"); 
//  }
  
  // If the button is released (and the sequence is "started"):
// else if(sequence_activated && btn_bounce.read() == LOW)  
  
  
  if(btn_bounce.read() == LOW) {
    time_before = millis();
  }
  
  
  if(Flag==0) {
    // Current time - time before button press is equal or greater than 2 sec:
   if(millis() - time_before >= 2000) {  
       //Serial.println("Button released after min. 2 sec. turning on LED");       
      digitalWrite(LED, HIGH);            // Turn LED on.
      delay(5000);                        // Wait 5 sec.
      digitalWrite(LED, LOW);             // Turn LED off.
      //Serial.println("Turned off LED"); 
      delay(5000);                        // Wait another 5 sec.
      Flag=1;         // Reset sequence.
  
    }
    

  }
  if(btn_bounce.read() == HIGH) {
    Flag=0;
  }
}