Arduino One-shot timer

A recurring task that comes up in machine control or experimenting with Arduino is turning an output on for a fixed time, then shutting the output off. In electronics, the circuit that does this is called a One-Shot Multivibrator. A multivibrator is a circuit that switches between two states – On (or High) and Off (or Low). A one-shot multivibrator does this once. ItsĀ  normal state may be off, but when triggered, it switches on for a period of time and then back off.

We use the same name to describe code or an Arduino sketch that performs this one-shot function. Typically there is an input like a pushbutton that is monitored and a digital output that will execute the one-shot function when the pushbutton is active.

A retriggerable one-shot is a version where triggering it again before the time is up causes the time to be extended. So, say the one shot output would be on for 10 seconds, pushing the button in our example three times would result in a total output On time of 30 seconds. A non-retriggerable one-shot ignores the triggering input while the output is active.

Here is code for a basic non-retriggerable one-shot Arduino timer.

// Project sponsor: N/A
// Email:
// Creator: Cedar Lake Instruments LLC
// Date: April 2018
// Description:
// Demonstrate one-shot logic with Arduino
// Arduino pins
// 2 – Digital trigger input. Pull LOW to trigger one shot
// 3 – Cancel one shot timer (output goes LOW)
// 13 – One shot output (goes HIGH for one shot time)
#define TRIGGER 2
#define CANCEL 3
#define OUT 13

// *** U S E R A D J U S T M E N T S ****************
// One shot time in milliseconds
#define DELAY 6000

int _timeout = 0;

void setup()
   pinMode(OUT, OUTPUT);
   digitalWrite(OUT, LOW);

void loop()
   // One shot triggers on high->low transition of TRIGGER pin
   if ((digitalRead(TRIGGER) == LOW) &&
   (digitalRead(CANCEL) == HIGH))
      _timeout = DELAY;
      digitalWrite(OUT, HIGH);

   // Hold output High until timeout or cancel pressed
   while (_timeout– > 0 && (digitalRead(CANCEL) == HIGH))
   digitalWrite(OUT, LOW);

   // Hold here until inputs inactive
   while ((digitalRead(TRIGGER) == HIGH) &&
   (digitalRead(CANCEL) == HIGH));