Watchdog Timer

The STM32WB55 is equipped with a circuit called independent watchdog (abbreviated by IDWG) which acts as a stand-alone counter. We set its maximum starting value and start it.
Once the IDWG is launched, it counts the microseconds, completely independent of the program running, until it reaches zero. It then forces a “reset” of the microcontroller. It is possible to interrupt and restart the IDWG count from its maximum value at any time, from the user program, and prevent this reset.
We understand the interest of this device: if the user program is «crashed» (because of a bug, a faulty sensor, a Wi-Fi module that does not connect, etc.) then it will not «reload» the IDWG before the end of its countdown, and the IDWG will force the system to reboot.
IDWG is implemented in the MicroPython API, and is referred to as Watchdog Timer. This tutorial explains how to implement the watchdog timer in MicroPython.

Required Hardware

The NUCLEO-WB55 board. We will blink the LED1 (blue):

LEDS

MicroPython code

The following script is available in the download area.

The program presented below shows how the Watchdog Timer works. It is programmed to be “fed” every 2 seconds. The main loop “goes around” every second, blinking the blue LED of the NUCLEO-WB55. An interrupt routine allows to delay this loop by 2 seconds after 5 successive presses on the SW1 button. The loop execution time then becomes higher than the Watchdog Timer’s life time, which will therefore restart (RESET software) the NUCLEO-WB55.

Edit the main.py script contained in the NUCLEO-WB55-associated USB disk directory: PYBFLASH.

# Objet of the script :
# Watchdog Timer Demo 
# Reference: https://docs.micropython.org/en/latest/library/machine.WDT.html
# After 5 presses on the SW1 button, the sde script pauses for a duration
# that exceeds the restart threshold imposed by the watchdog.

import pyb # for device access (GPIO, LED, etc.)
from time import sleep_ms # for system breaks

# Global variable that counts the presses on the button
cnt = 0

# SW1 Button Initialization
sw1 = pyb.Pin('SW1')
sw1.init(pyb.Pin.IN, pyb.Pin.PULL_UP, af=-1)

# Interrupt service function for SW1 (cnt increment)
def Press(line):
	global cnt
	cnt += 1

# Attach a Switch Service routine to SW1
irq_1 = pyb.ExtInt(sw1, pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, Press)

# Blue LED Initialization
led_bleue = pyb.LED(3) # LED1 screen printed on the PCB

# Waiting time (ms) before changing LED status
DELAY_LED = const(500)

# Waiting time (ms) before the watchdog restarts the NUCLEO-WB55
WDT_TIMEOUT = const(2000)

# for managing the watchdog
from machine import WDT

# starting the watchdog
wdt = WDT(timeout = WDT_TIMEOUT)

while True:
	
	# recharging the watchdog for WDT_TIMEOUT millisecondss
	wdt.feed()

	if cnt == 5:
		print("Pause for %d seconds" %( WDT_TIMEOUT // 1000 ))
		cnt = 0
		sleep_ms(WDT_TIMEOUT)

	led_bleue.on() # Turns on the LED
	sleep_ms(DELAY_LED) # waiting time=delay

	led_bleue.off() #Turns off the LED
	sleep_ms(DELAY_LED) # waiting time=delay

You can start the script with Ctrl + D on the PuTTY terminal and observe that the LED blinks at a frequency of 1 Hz (one on - off cycle per second). If you then press SW1 5 times, the message “Pause for 2 seconds” is displayed on your terminal, you will then be disconnected from it following the RESET generated by the Wachdog. You will see that the blue LED starts blinking again, which means that the program in *main.py** has been restarted despite the loss of the serial connection with the USB user.