How to make the Arduino reliable

Does your Arduino just hang after a few days?

In my experience, it is possible to stop the oscillator of an Arduino (or any CPU) by applying some static energy spikes on it... If this happens, the internal watchdog is of no use (since it needs the oscillator). So, IMHO, the internal watchdog is only good when the software crashes - and I do not write code that crashes (I'd like to think).

If the oscillator stops, powering it down, and then up again, does restart the oscillator.

But I learned that pressing the reset button is also sufficient to start the oscillator up again. So, let's automate this action, and use an external watchdog.

SOT23-5 pinout

Description

The STWD100 watchdog timer circuits are self- contained devices which prevent system failures that are caused by certain types of hardware errors (such as, non-responding peripherals and bus contention) or software errors (such as a bad code jump and a code stuck in loop).

The STWD100 watchdog timer has an input, WDI, and an output, /WDO . The input is used to clear the internal watchdog timer periodically within the specified timeout period, twd. While the system is operating correctly, it periodically toggles the watchdog input, WDI. If the system fails, the watchdog timer is not reset, a system alert is generated and the watchdog output, /WDO , is asserted (for a period of tPW).

The STWD100 circuit also has an enable pin, /EN , which can enable or disable the watchdog functionality. The /EN pin is connected to the internal pull-down resistor. The device is enabled if the /EN pin is left floating.

LD.png BD.png

Datasheet

stwd100.pdf

Variants

I bought the STWD100NYWY3F, which means:

  • Not automotive grade
  • Open drain (active low) output
  • The tWD = 1.6s (watdog kicking timeout)
  • The tPW = 210ms (reset active pulse width)
  • The WDI triggers on high-to-low transition only
  • Package SOT23-5
  • Temperature range: -40 .. +125 °C

The Arduino Nano has an Atmega328P processor, which requires a reset pulse width of minimum 2.5µs for proper operation. Hence, a tPW of 210ms is good.

Recipe for STWD100 with Arduino

Schema test STWD100

Use the schema shown above to connect the Arduino to the STWD100.

The intention of using a STWD100 is to prevent hardware crashes, not (so much) software bugs. So, kicking the watchdog in the loop() suffices.

In the code, start with:

#define _EN   7
#define _WDI  8

Then add the following in the setup():

void setup()
{
    digitalWrite (_EN, HIGH);
    pinMode (_EN, OUTPUT); //Watchdog /EN Enable pin D7
    pinMode (_WDI, OUTPUT); //Watchdog /WDI pin D8
    ...
}

Then in the loop(), enable the watchdog and start kicking it every time the loop is entered:

void loop() {
    digitalWrite (_EN, LOW);    // enable the watchdog here
    digitalWrite (_WDI, HIGH);  // kick the watchdog
    delay(1);                   // you only need 1µs here
    digitalWrite (_WDI, LOW);   // kick the watchdog
    ...
}

The delay of 1ms is overkill, since according to the datasheet, 1µs will suffice. It is better to fill the time by doing something useful (like in the next example).

We only enable the watchdog at the moment the loop() is entered the first time. This way, it works together with the MySensors library. The MySensors long communication delays mainly happen while starting up and establishing a connection with the gateway. The loop() only starts when that is done.

The above is sufficient if your loop() never lasts more than the 1.6s timeout of the STWD100.

In case you have a long calculation or delay in your loop, you may need to kick the watchdog a few more times. In the following example, a CO2 measurement was started, and we need to wait for the result. The measuredelay is 2250ms, so it is broken up in 4 smaller delays:

digitalWrite (_WDI, HIGH);
delay(measureDelay/4);
digitalWrite (_WDI, LOW); // kick watchdog
delay(measureDelay/4);
digitalWrite (_WDI, HIGH);
delay(measureDelay/4);
digitalWrite (_WDI, LOW); // kick watchdog
delay(measureDelay/4);
digitalWrite (_WDI, HIGH);

See also WatchdogSTWD100Test for some complete code examples.

Comments: