10 Minute External Watchdog for MCU (eg. ESP32 / ESP8266)

by Rob__S in Circuits > Arduino

36 Views, 0 Favorites, 0 Comments

10 Minute External Watchdog for MCU (eg. ESP32 / ESP8266)

testing.jpg

This project shows 2 different examples of circuits for an external watchdog, namely one based on a PIC10F200 (a small microcontroller), and one based on a 555-Timer-Chip.

Watchdog: PIC10F200 (a Small Microcontroller)

program_pcb.jpg
programming.jpg

This uses a single PIC10F200 8pin DIL-Chip, and does not normally require any additional components.

It is connected to 3.3V power (drawing about 250uA), Ground, the ESP32-reset-pin, and a single ESP32-GPIO to provide the "feed-watchdog" signal.

(If the 250uA is too high, then it is probably possible to reduce the curent to ~0.1uA if you redesign the software to SLEEP the PIC10F200.)


Note that if triggered, the PIC10F200 will pull-down the ESP32's reset pin for 2 seconds to reset the ESP32. It is capapble of sinking/sourcing upto 20mA from/to the ESP32's reset-pin.

Most MCUs only need 0.5mA or less sink/source to reset. However, if more than 20mA if needed, you will need to add a NPN-transistor and base-resistor to pull-down the reset pin.

If your MCU does not have a reset pin available, then you will instead need to add a P-type-MOSFET on the ESP32's power supply and use the watchdog to turn that off/on instead.


The code for the PIC10F200 is shown below:


#pragma config WDTE = ON // Watchdog Timer (WDT enabled)
#pragma config CP = OFF // Code Protect (Code protection off)
#pragma config MCLRE = OFF // Master Clear Enable (GP3/MCLR pin fuction is digital I/O, MCLR internally tied to VDD)

#include <xc.h>

#define _XTAL_FREQ 4000000

void trigger_reset(void);
_Bool look_for_toggle(void);

uint8_t stat=0; // pin_mask;

void main(void) {
__asm("MOVWF OSCCAL"); // move w to reg-OSCCAL
CLRWDT();

#define OPTION_default (unsigned char)~0b00100000 // no-T0CS
#define OPTION_signal (unsigned char)~0b01100000 // no-T0CS & Pullups-ON-ALL-INPUTS
OPTION = OPTION_default;

#define TRIS_default (unsigned char)0b1111 // All Input
#define TRIS_trigger (unsigned char)0b1110 // Output=GP0
TRIS = TRIS_default;
GPIO = 0b0000; // all off
#define i_max 212 // 0.95*3*211/60=10.07mins
// #define i_max 11 // 0.95*3*11=30esconds

#define pin_mask 0b1000 // GPIO 3
for (;;) {
uint8_t i;
for (i=0;i<i_max;i++) {
if (look_for_toggle()) break; // read GP3
if (look_for_toggle()) break; // read GP3
if (look_for_toggle()) break; // read GP3
}
if (i==i_max) {trigger_reset(); stat=pin_mask;} // as pulled high
else {
if (stat) stat=0; else stat=pin_mask;
OPTION = OPTION_default; // no-pullups
}
}
}

_Bool look_for_toggle(void) {
CLRWDT(); // watchdog will trigger after 18*128=2304ms
__delay_ms(950); // 0.95*3*211/60=10.02mins // max is 50463ms
return ((GPIO&pin_mask)!=stat); // read GP3
}

void trigger_reset(void) {
TRIS = TRIS_trigger; // GPIO=output will start LOW
CLRWDT();
__delay_ms(1000);
CLRWDT();
__delay_ms(1000);
TRIS = TRIS_default; // return all GPIO to input
OPTION=OPTION_signal; // Pullups-ON-ALL-INPUTS and no-T0CS
}


I used the "Microchip MPLAB X IDE v6.20" with the "XC8 (C-compiler)", with a "PicKit 3.5 programmer" (a clone of the Microchip PicKit 3).

The ESP32 needs to toggle the PIC10F200-GPIO-3 once in a while (gaps between 1second and 10minute ) and if not the PIC10F200-GPIO-0 will be pulled down for 2seconds to reset the ESP32.

Note that the ESP32 can tell if it has been reset by the PIC10F200 by reading the PIC10F200-GPIO-3 at boot: a high indicates that the watchdog has triggered.


The Arduino-Test-Code running on the ESP32 (demonstrating watchdog-feeding, watchdog-triggering, and also reading-the-watchdog-triggered-signal) is attached below ("External-PIC10F200-Watchdog-Demo_Sketch.ino"). This demo code gives the following output:

Power-On Boot
Feed-Watchdog: gap between feeds should be somewhere between 1s(to be recognised) -> 10minutes
Feed-Watchdog: gap between feeds should be somewhere between 1s(to be recognised) -> 10minutes
Triggering Watchdog:
....................................... 1min
....................................... 2min
....................................... 3min
....................................... 4min
....................................... 5min
....................................... 6min
....................................... 7min
....................................... 8min
....................................... 9min
....................................... 10min
.
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x4010f000, len 3408, room 16…

*** Watchdog Re-Boot ***
Feed-Watchdog: gap between feeds should be somewhere between 1s(to be recognised) -> 10minutes


Watchdog: Using a 555-Timer-Chip

schematic.jpg

This uses a "ICM7555" CMOS Timer Chip. The schematic / components are shown above (4x Resistors, 2x Capacotors, 1x Diode) (exc. pullup on output).

It is connected to 3.3V power (drawing about 75uA), Ground, the ESP32-reset-pin, and a single ESP32-GPIO to provide the "feed-watchdog" signal.


Note that if triggered, the 555 will pull-down the ESP32's reset pin for about 6 seconds to reset the ESP32.

It is capapble of sinking/sourcing probably upto about 200mA (dependent on chip) from/to the ESP32's reset-pin.

To "feed-the-watchdog", the ESP32 needs to pulse/pull the "BAT43" terminal to ground for about 1.5s, and then either return it to HIGH or open-circuit (set to INPUT or INPUT_PULLUP).

The if above watchdog-pulse is not sent in under ~10minutes the 555 will time-out and pull it's output down for ~6seconds.

Note that with this circuit the ESP32 can NOT tell if it has been reset by the watchdog or not.


This watchdog is not as good as the PIC10F200 one, because if the ESP32 PULLs(OUTPUT) the BAT43 pin LOW and leaves it there, the 555-Watchdog will never trigger.

[Which is why it's perhaps better to return the GPIO to INPUT Or INPUT_PULLUP (rather than OUPUT-HIGH) in between watchdog-pulses.]

(Note that if the ESP32 is using "pinMode(WATCHDOG_PIN,INPUT)" the above shown external pullup on the INPUT is necessary to ensure the BAT43 remains off as pin-6 charges to ~2.2V)

The Arduino-Test-Code running on the ESP32 (demonstrating watchdog-feeding, watchdog-triggering, and also reading-the-watchdog-triggered-signal) is attached below ("External-555-Watchdog-Demo_Sketch.ino"). This demo code gives the following output:

Boot-Up
Feed-Watchdog: gap between feeds should be less than ~10minutes
Feed-Watchdog: gap between feeds should be less than ~10minutes
Triggering Watchdog:
....................................... 1min
....................................... 2min
....................................... 3min
....................................... 4min
....................................... 5min
....................................... 6min
....................................... 7min
....................................... 8min
....................................... 9min
....................................... 10min
.
ets Jan 8 2013,rst cause:2, boot mode:(3,7)
load 0x4010f000, len 3408, room 16…

Boot-Up
Feed-Watchdog: gap between feeds should be less than 10minutes

Photo of Prototype 555-Timer-Watchdog

555_pcb.jpg