Monday, 6 January 2014

PLC Timers in Arduino

PLC Timers use to consist on a digital input plus a number that specifies time. Most of them use to behave as an ON-delay (also known as TON timers), this is to say, timer output triggers after the specified time. There are other options like OFF-delays (known as TOFF timers).

This can be easily assembled with C++ in an Arduino:
typedef struct timer {
  boolean in;
  unsigned int pt;
  unsigned int et;
  boolean q;
};
 This structure defines a new variable type that consists on:

- IN: a digital input, that starts the timing after it is at ON state;
- PT: after PT-time, output Q shall trigger to ON state;
- ET: this is the amount of time after IN has gone to ON;
- Q: the timer output, that would be ON after ET=PT.

Simple, isn't it?

After creating this structure, we must create this timers and call an end() routine at the end of the program.

For example,

#define MAXT      6
timer t[MAXT];
and inside our program
  t[4].in = !t[5].q;
  t[4].pt = 800;
  t[5].in = t[4].q;
  t[5].pt = 100;
  digitalWrite( MONI_PIN, t[4].q);
This sets timer 4 to start 8 seconds after timer 5 is OFF. Afterwards, timer 5 counts 1 second and both timers go to OFF state and the cycle restarts. The digital output shall blink for 1 second each 8 seconds.

At the end of the loop() section, we must call an end() routine which looks like:
void end() {
  byte i;
 
  // timers
  for (i=0;i<MAXT;i++) {
    if (!t[i].in) {
      t[i].q = false;
      t[i].et = t[i].pt;
    }
    t[i].q = (t[i].in && (t[i].et == 0));
  }
 
   if (millis() > lastTime) {
    lastTime = millis() + 10;
    for (i=0;i<MAXT;i++)
      if (t[i].in && t[i].et>0) t[i].et--; 
  }
}

REMARKS:
  • Time Counters are decreasing. This makes things easier for the processor. This is common in some commercial PLCs.
  • Avoid any "delay" function in loop() section. Otherwise, timers would not behave as expected. 


1 comment:

  1. This is another similar approach to PLC Timers:

    https://groups.google.com/forum/#!topic/alt.microcontrollers.8bit/tGAtmeViuHA

    The main difference relies on the "end()" instance at the end of the "loop()". This one calls "CTU" or "TON" functions each time.

    ReplyDelete