Tuesday, June 03, 2008

WDT: Watchdog Timer

I am now addicted to PIC Microcontroller projects. Last week, I just completed a prototype of my GPS controlled digital clock. The clock was running very nice and ,of course, it is one of the most accurate clock in the country :). I was very happy with it and thinking of putting more features to the clock. But... when I saw the clock this morning, I was shocked!. The clock was not running! it stopped last night around 00:23:xx . So, I pressed the reset button and the clock came back. Now, it is running happily (waiting for another Freeze in the future :p )

But, there are some questions. Why my clock stopped? Will it happend again? How to overcome the problem?. After google around, I think I found a potential answers to the questions. I was thinking that microcontrollers are just electronics devices that will work as they promise as long as you provide power to them. But, I was wrong. PIC Microcontrollers can Hang Up or Freeze just like your computers. So, my clock can Freeze just like my PC :) .

Will it happend again?
Yes, it will happend again but nobody knows when.

How to overcome the problem?
Now, the hero is WDT or Watchdog Timer. It just like a dog who keeps comming to see the PIC every certain period of time. If the PIC can kick the dog (by clearing WDT register with CLRWDT command), the dog will go back and will come to see the PIC again next time. But if the PIC cannot kick the dog (the PIC is engaging infinity loop or just freezing), the dog will reset the PIC. One nice thing is that you don't have to wait until the dog comes before you can can kick it. You can kick the dog anytime you want but you have to make sure that you kick it before it resets the PIC. By using WDT, I think I can make my clock running helthly without human reset when it hang up.

How to use WDT?
I am no expert on PIC. So, I will show what I did and explain what I understand.

  1. Set CONFIG word to enable WDT

  2. I use mikroC compiler, so I uncheck the default WDT_OFF = $3FFB and check _WDT_ON = $3FFF

  3. In the code I set up 2 functions: FeedDog() and KickDog()

  4. void FeedDog(){ //Setting WDT
    OPTION_REG = 0x0F; //0b00001111 = Prescalar 1:128 .. reset every 2.3 sec. please consult data sheet for other presacalars
    asm{CLRWDT} //Clear WDT

    void KickDog(){
    asm{ CLRWDT } //Clear WDT before the dog resets the PIC

  5. Placing FeedDog() and KickDog() in the main program

  6. I put FeedDog() around the begining of the program to set up WDT and put KickDog() wherever I think the dog will come. If the program is very long, I can put KickDog() in many places as I want if I think the dog will come after that line of code. It is upto me to calculate where to put the KickDog(). In my case, the dog keeps comming every 2.3 sec so I have to kick the dog before 2.3 sec after each kick. My clock update every second, so if it freeze and cannot kick the dog in 2.3 sec the PIC will be reset.
    Putting KickDog() in the wrong place can make your program running incorrectly. Please be careful.

    void main(){
    .. Set up program ..
    .. Set up some more things..

    .. Do tasks ..
    ...Do tasks..


To be revised with images and more details