diff --git a/examples/C/README.md b/examples/C/README.md
index fbc1fab4..d28c1f47 100644
--- a/examples/C/README.md
+++ b/examples/C/README.md
@@ -1,7 +1,7 @@
# C Examples
* [Patterns](src/patterns/README.md): Common communication patterns.
* [Deadlines](src/deadlines/README.md): Uses of deadlines in Lingua Franca.
-* [Car Brake](src/car-brake/README.md): Sketch of ADAS system illustrating CAL theorem.
+* [Car Brake](src/car-brake/README.md): Sketch of ADAS system illustrating the CAL theorem.
* [Rosace](src/rosace/README.md): Aircraft controller illustrating periodic systems with multiple periods.
* [Simulation](src/simulation/README.md): Using Lingua Franca for simulation.
* [Keyboard](src/keyboard/README.md): Responding to keyboard input using ncurses.
@@ -12,4 +12,5 @@
* [Shared Memory](src/shared-memory/README.md): Using shared memory to exchange large data objects between federates.
* [Train Door](src/train-door/README.md): Train door controller from a verification paper.
* [Distributed](src/distributed/README.md): Basic federated hello-world examples.
-* [Leader Election](src/leader-election/README.md): Federated fault-tolerant system with leader election.
\ No newline at end of file
+* [Watchdog](src/watchdog/README.md): Federated illustration of watchdogs.
+* [Leader Election](src/leader-election/README.md): Federated fault-tolerant system with leader election.
diff --git a/examples/C/src/watchdog/README.md b/examples/C/src/watchdog/README.md
new file mode 100644
index 00000000..c788c153
--- /dev/null
+++ b/examples/C/src/watchdog/README.md
@@ -0,0 +1,27 @@
+# Watchdog -- Reacting to Absent Inputs
+
+The LF deadline handlers react to inputs that are late.
+What if you want to react the fact that an input has _not_ arrived by a certain time?
+The deadline construct, by itself, will not do this.
+It does not react until an input actually arrives.
+
+The watchdog construct provides a mechanism for this.
+A watchdog is started using `lf_watchdog_start` at some logical time _t_.
+It will expire at _physical_ time _t_ + _W_, where _W_ is the watchdog delay,
+unless it gets restarted with `lf_watchdog_start` or stopped using `lf_watchdog_stop`
+before that physical time elapses.
+
+When a watchdog expires, two things happen. First, the watchdog handler is invoked.
+Second, an event identified by the name of the watchdog is scheduled at the earliest
+available tag (typically the current tag plus one microstep).
+The watchdog handler is invoked asynchronously, and therefore has limited access
+to the reactor's infrastructure, such as inputs and outputs.
+However, the scheduled watchdog event can trigger an ordinary reaction
+which has full access to the state variables and inputs and outputs of the reactor.
+
+
+
+
+ | Watchdog.lf: Illustration of the use of the watchdogs in LF. |
+
+
\ No newline at end of file
diff --git a/examples/C/src/watchdog/Watchdog.lf b/examples/C/src/watchdog/Watchdog.lf
new file mode 100644
index 00000000..8d0db5ef
--- /dev/null
+++ b/examples/C/src/watchdog/Watchdog.lf
@@ -0,0 +1,114 @@
+/**
+ * @brief Demonstration of watchdogs in LF.
+ *
+ * This program has a periodic source that triggers events every 500 ms, but where every fourth
+ * event is delayed before being delivered to the downstream Watcher. This delay models either
+ * communication or computation time.
+ *
+ * The Watcher has a deadline of 200 ms. It wants to see events within 200 ms of their logical time,
+ * but, because of the delay every fourth event, the deadline will be violated. The deadline
+ * violation handler is invoked in this case, but it is only invoked after the event arrives, which
+ * is late. What if we need to react to the deadline violation sooner, e.g. in order to drive an
+ * actuator?
+ *
+ * To handle this, the Watcher includes watchdog named "dog" that triggers if any input event is
+ * more than 250 ms late.
+ *
+ * @author Benjamin Asch
+ * @author Edward A. Lee
+ */
+target C {
+ timeout: 5 s
+}
+
+reactor SometimesSlowSource {
+ output out: int
+ timer t(500 ms, 500 ms) // Offset ameliorates startup time.
+ state count: int = 1
+
+ reaction(t) -> out {=
+ if (self->count % 4 == 0) {
+ // Be slow.
+ lf_sleep(MSEC(300));
+ }
+ lf_set(out, self->count++);
+ =}
+}
+
+reactor Watcher {
+ input in: int
+ output out: int
+ state count: int = 1
+ logical action a(500 ms)
+
+ watchdog dog(750 ms) {=
+ instant_t p = lf_time_physical_elapsed();
+ lf_print("******** Watchdog timed out at elapsed physical time: " PRINTF_TIME, p);
+ =}
+
+ reaction(in) -> dog, out {=
+ // Reset the watchdog. The next event is expected in 500 ms.
+ // This watchdog will trigger if the event does not arrive within 750 ms from now,
+ // or is more than 250 ms late.
+ lf_watchdog_start(dog, 0);
+ lf_print("Watchdog started at physical time " PRINTF_TIME, lf_time_physical_elapsed());
+ lf_print("Will expire at " PRINTF_TIME, lf_time_logical_elapsed() + MSEC(750));
+ lf_set(out, in->value);
+ self->count++;
+ =} deadline(200 ms) {=
+ // This input is more than 200 ms late. It must have been from the slow cycles.
+ lf_print("Watcher received late input %d. Ignoring it.", in->value);
+ =}
+
+ reaction(dog) -> a {=
+ // Note that this reaction will trigger at the earliest available tag, which
+ // will be one microstep later than the most recent input or watchdog violation.
+ lf_print("******** Watchdog triggered. Scheduling output for next logical time.");
+ // Use a logical action so that the logical time of the output aligns.
+ lf_schedule(a, 0);
+ =}
+
+ reaction(a) -> out, dog {=
+ lf_print("******** Backup output being produced.");
+ lf_set(out, self->count++);
+ // Start another watchdog cycle in case the very next input is also delayed.
+ lf_watchdog_start(dog, 0);
+ lf_print("Watchdog started at physical time " PRINTF_TIME, lf_time_physical_elapsed());
+ lf_print("Will expire at " PRINTF_TIME, lf_time_logical_elapsed() + MSEC(750));
+ =}
+
+ reaction(shutdown) -> dog {=
+ lf_watchdog_stop(dog);
+ =}
+}
+
+reactor Checker {
+ input in: int
+ state count: int = 1
+
+ reaction(in) {=
+ lf_print("Checker received %d at logical time " PRINTF_TIME
+ " and physical time " PRINTF_TIME, in->value,
+ lf_time_logical_elapsed(),
+ lf_time_physical_elapsed());
+ if (in->value != self->count) {
+ lf_print_error_and_exit("Expected %d", self->count);
+ }
+ self->count++;
+ =}
+
+ reaction(shutdown) {=
+ if (self->count < 10) {
+ lf_print_error_and_exit("Received %d inputs. Expected at least 10.", self->count);
+ }
+ =}
+}
+
+federated reactor {
+ s = new SometimesSlowSource()
+ w = new Watcher()
+ c = new Checker()
+
+ s.out -> w.in
+ w.out -> c.in
+}
diff --git a/examples/C/src/watchdog/img/Watchdog.png b/examples/C/src/watchdog/img/Watchdog.png
new file mode 100644
index 00000000..3bb720f5
Binary files /dev/null and b/examples/C/src/watchdog/img/Watchdog.png differ