Calendar

March 2019
M T W T F S S
« Dec    
 123
45678910
11121314151617
18192021222324
25262728293031

Categories

Active supporter of WikiPedia
Support Wikipedia

Geocaching

Profile for uwezi

A tiny watchdog

In a recent quick-and-dirty project with a Wemos D1 mini clone I had some problems with the reliability of the code. The ESP8266 contains two watchdogs which have the sole purpose to reset the chip if the firmware ever should get stuck. Previously I experienced these watchdogs to be too aggressive, but this was not the case now.

In this project I send sensor data directly to an MySQL database using Chuck Bell’s library, but once in a while the code would get stuck. From a debug LED I know that this happens while executing the MySQL INSERT query. How is this possible? Well, the watchdogs must be fed somehow in spite of the code hanging, and there is no built-in timeout either.

On Facebook it was suggested to build an external watchdog. This evening I now finally considered first to use a 74HC123 monostable as a trigger for the reset of the ESP8266 if the debug LED stops blinking. But then I reconsidered and grabbed an ATtiny13A out of my box and wrote a small program.

The watchdog timeout time can be set externally by means of the three pins PB[2:0] as a three bit number, where the actual time is (n*2+1) seconds, i.e. between 1 s and 15 s. Triggering the watchdog is done by toggling the pin PB3, each transition 0-1 and 1-0 restarts the internal timeout.

/*
 * 20181206_tiny13_watchdog.c
 *
 * Created: 2018-12-06 21:48:06
 * Author : uwezi
 */


#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile int8_t timeout, count;

ISR(PCINT0_vect)
{
  count = timeout;  
}

ISR(TIM0_COMPA_vect)
{
  count --;
  if (count <= 0)
  {
    count = timeout;
    PORTB &= ~(1 << PB4);
    _delay_ms(200);
    PORTB |= (1 << PB4);
  }
}

int main(void)
{
  DDRB   = (1 << PB4);
  PORTB  = (1 << PB4) | (1 << PB3) | (1 << PB2) | (1 << PB1) | (1 << PB0);
 
  timeout  = (((PINB & 0b111) << 1) + 1) * 4;
  count    = timeout;
 
  PCMSK  = (1 << PCINT3);
  GIMSK  = (1 << PCIE);
 
  OCR0A  = 243;   // 4 Int/s
  TCCR0A = (1 << WGM01) | (0 << WGM00);
  TCCR0B = (0 << WGM02)
         | (1 << CS02) | (0 << CS01) | (1 << CS00);
  TIMSK0 = (1 << OCIE0A);
 
  sei();      

  while (1)
  {
    timeout  = (((PINB & 0b111) << 1) + 1) * 4;
    _delay_ms(500);
  }
}

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>