Use Arduino timers like PLC timers

Using a On-delay timer in a PLC is straight forward, and with this clever function is easy on an Arduino too.

On delay timer in a PLC

A typical On-delay timer of a PLC (often referred as “TON” timer) has one input (“in”, or “en”), one output (“q”, or “out”), and a preset timing value (“pt”). When the input goes high, the timer count the time up to the preset timing value, and once reached it activates the output bit (q). If we want, we can read the value of the timer (ep), which tells how much time has elapsed since when it started counting. When the input goes low, the output goes low and the elapsed time (ep) is set to zero again. Timing diagram:

On delay timer in arduino

On the arduino the same can be achieved defining a data type structure called “timer” that contains two bits (in, q), the preset (pt) and the counting value (et) which keeps track of time.

Once we have the “timer” data type created, we must create the timers, which we call “t[i]”, where i is the number of the timer. MAXT is the total number of timers we use in the program (or more). To access the input enable of timer 3 for example, we write t[3].in. The output of the timer is t[3].q. Don’t forget to tell the timer how much time is the preset, in hundreds of seconds t[3].pt=500 (5 seconds). The preset timing (pt) must be specified in hundreds of seconds, either in the “setup” or in the “loop”.

The only difference with the PLC, is that on the arduino it is more practical to “count down” rather than “up”. The On-delay has elapsed when “et” is equal to zero.

This program will turn on a led (pin D13 on arduino nano) after 1 s from the button press. Two second after, a second led (pin D2) will go on.

//
// simple arduino timer, like in a PLC
// Giorgio Demurtas
// 18-03-2018

#define button 17 //A3
#define led2 2 //pin2

struct timer { //This structure defines a new variable type that consists on:
  boolean in;      //IN: a digital input, that starts the timing after it is at ON state;
  unsigned int pt; //PT: after PT-time, output Q shall trigger to ON state; (Preset Time)
  unsigned int et; //ET: this is the amount of time after IN has gone to ON; (Elapsed Time)
  boolean q;       //Q: the timer output, that would be ON after ET=PT.
};
unsigned long lastTime; //it must be long to receive the output of millis()

#define MAXT 6 //how many timers I have in the program (or more)
timer t[MAXT];  //Create 6 timers


void setup() {  
 pinMode(button, INPUT);
 pinMode(LED_BUILTIN, OUTPUT);
 pinMode(led2, OUTPUT);
 t[1].pt=100; //preset time. Can be in setup or in loop.
 t[2].pt=200; //preset time. Can be in setup or in loop.
}

void loop() {
  t[1].in=digitalRead(button);
  digitalWrite(LED_BUILTIN, t[1].q);
  t[2].in=t[1].q; //start timer2 when timer1 finish to time
  digitalWrite(led2, t[2].q);

  t[3].pt=1;
  t[3].in=1;
  if(t[3].q){
     t[3].in=0;
     Serial.println(millis());
  }

  timers_manager();
}


//------------------------------------------------------------

void timers_manager() { //routine to manage all the timers
  byte i;
  // timers
  for (i=0;i<MAXT;i++) {
    if (!t[i].in) { //if input is off
      t[i].q = false; //put output off
      t[i].et = t[i].pt; //preload the "elapsed time" with "preset time". Nota that the count is towards zero.
    }
    t[i].q = (t[i].in && (t[i].et == 0)); //output is high when "et" arrives to zero (and "in" is 1)
  }
 
   if (millis() >= lastTime) { //lastTime is put to xxx ms forward compared to the present time. When the present time (millis()) reach it
    lastTime = millis() + 1000; //we move it forward again and  
    for (i=0;i<MAXT;i++) // for each timer
      if (t[i].in && t[i].et>0) t[i].et--;  //decrement the counting value ElapsedTime if the in is acrive and if et>0. 
  }
}

The smart thing of this program (inspired by this and this), is that we can create new timers simply calling them t[whatever], and set the delay time with t[whatever].pt , and access the bits with .in and .q. The smart thing is that we have one single function that manage all the timers we have in our program with a “for” loop, taking cares of increments and bits.

 

2 comments

  1. Hi! I need your help please, I have a little problem maybe I am wrong conecting the arduino. I connect a push button to arduino A3 and 1 led to D2 then I upload the code but nothing happens, thank you

  2. Thank you so much Giorgio! I work whit the Plc every day and your compare with arduino help me a lot!

Comments are closed.