Um cronômetro externo de vigilância é uma muleta para desenvolvedores ruins que não conseguem desenvolver um programa que funcione adequadamente para microcontroladores ou um circuito de funcionamento estável.
Além disso, o WDT embutido está disponível na maioria dos microcontroladores modernos.
Mas há momentos em que você precisa lidar com uma placa ou módulo finalizado com certos problemas.
Fiz meu primeiro WDT a lidar com os raros, mas ainda ocorrendo, trava do ESP8266. Além disso, a reinicialização suave não foi salva e o gabinete do ESP não quis se reconectar ao WiFi. Distorcer a energia com um WDT externo resolveu o problema.
O segundo problema surgiu com o
controlador Elecrow ATMEGA 32u4 A9G GSM . Aqui, ocorreram muito raramente congelamentos do cartão SIM. (A propósito, o mesmo problema ocorre com os modems USB 3G e 4G). Para combater esse congelamento, você precisa distorcer o poder do SIM-ke. E parece que até o modem GSM tem uma conclusão para isso, mas esse recurso não está incluído no circuito do dispositivo. E para alcançar a máxima confiabilidade, tive que recorrer a um cão de guarda externo.
Não repeti o circuito no timer 555. Demasiadas falhas que ela revelou:
- Grandes dimensões e bastante cintas
- Configuração inconveniente do tempo de resposta com um resistor de sintonia
- Tempo de reset bastante longo (é necessária a descarga do capacitor)
- Bem, o potencial travamento do MK com um nível baixo na saída do timer, quando o timer simplesmente para de funcionar.
- E não encontrei projetos OpenSource na Internet que atendessem totalmente aos meus requisitos.
Requisitos para o novo WDT
- Baixo custo do dispositivo, facilidade de fabricação e pequenas dimensões
- Controle da mudança periódica do nível lógico 0/1 na entrada
- Ajuste simples do tempo de resposta (como opção, escolha de intervalos predefinidos)
Desenvolvimento de ferro
O
microcontrolador ATtiny13 foi escolhido como o microcircuito principal. Suas capacidades foram mais que suficientes para a minha tarefa. E o preço, considerando a redução dos elementos de cintagem, é quase o mesmo que o de 555 microcircuitos.

Cinco conclusões MK (RESET decidiu não tocar) foram distribuídas da seguinte forma:
- Saída do temporizador
- Redefinir entrada
- As três conclusões restantes são os tempos de resposta.
Para comutação de energia, um MOSFET de canal P é usado. Qualquer gabinete compatível é adequado, mas é aconselhável utilizá-lo com o chamado "nível de controle lógico" - isto é, ele abre completamente a partir de uma baixa tensão de 3-5V: IRLML2502, AO3415, etc. Apesar de seu tamanho pequeno, este transistor é capaz de controlar uma carga de 4A. Se você precisar trocar de outra coisa, pode conectar diretamente um relé de 5V a esta saída.
O LED acende quando o timer é ativado e a unidade principal é desligada.
O conector principal para conectar à placa do microcontrolador tem quatro saídas
- Ônibus comum
- Entrada - redefinir temporizador
- Saída de + 5V (controlada pelo temporizador)
- Entrada + 5V
Dois conectores - o programador ICSP e os jumpers de potência não podem ser instalados na placa. Pisque o microcontrolador no programador com antecedência e defina o tempo de resposta com um jumper constante.
Lista de peças
Fabricação
As pranchas eram pequenas - 18 × 22 mm. Eu espalhei duas opções:
Para fabricação de um lado pela LUT:


E para pedidos na fábrica com um design e transições aprimorados entre as partes. (Vou pedir dos chineses, na ocasião)


A tecnologia doméstica fornece algo parecido com este protótipo.



Firmware
Para firmware, usei um programador caseiro baseado no Arduino Nano

Programei no
Arduino IDE com suporte instalado para o
Attiny13 - MicroCore . A versão mais recente do IDE teve problemas com o programador ArduinoISP, mas funcionou bem na versão do Arduino IDE 1.6.13. A equipe amigável arduino.cc não queria
descobrir o que havia de
errado lá em
cima )))

Tinku sintonizado para funcionar a partir de um ressonador interno com uma frequência de 1,2 MHz. O programa é simples - configuramos as entradas / saídas, lemos PB2-PB4 e determinamos o tempo de resposta, ajustamos o temporizador e entram no modo IDLE. De acordo com a interrupção do timer, determinamos o estado da entrada de controle. Se o estado mudou para o oposto, redefina o contador. Se as leituras do contador excederem o tempo de resposta definido, distorcemos a potência de saída.
#define F_CPU 1200000UL #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> boolean pb1_state; volatile uint16_t pb1_count; // TIMER0 ISR(TIM0_OVF_vect){ pb1_count++; } int main(){ // PB0 DDRB |= (1 << PB0); // pinMode(PB0, OUTPUT); PORTB &= ~(1 << PB0); // digitalWrite(PB0, LOW);} // PB1 DDRB &= ~(1 << PB1); // pinMode(PB1, INPUT_PULLUP); PORTB |= (1 << PB1); // PB2 DDRB &= ~(1 << PB2); // pinMode(PB2, INPUT_PULLUP); PORTB |= (1 << PB2); // PB3 DDRB &= ~(1 << PB3); // pinMode(PB3, INPUT_PULLUP); PORTB |= (1 << PB3); // PB4 DDRB &= ~(1 << PB4); // pinMode(PB4, INPUT_PULLUP); PORTB |= (1 << PB4); // PB2,PB3,PB4 ( ) (, = TM/4 ) uint16_t TM = 0; bool pb2 = false; bool pb3 = false; bool pb4 = false; if( PINB & (1 << PINB2) )pb2 = true; if( PINB & (1 << PINB3) )pb3 = true; if( PINB & (1 << PINB4) )pb4 = true; if( pb2 == true && pb3 == true && pb4 == true )TM = 4; // 1 else if( pb2 == false && pb3 == true && pb4 == true )TM = 8; // 2 else if( pb2 == true && pb3 == false && pb4 == true )TM = 20; // 5 else if( pb2 == false && pb3 == false && pb4 == true )TM = 40; // 10 else if( pb2 == true && pb3 == true && pb4 == false )TM = 80; // 20 else if( pb2 == false && pb3 == true && pb4 == false )TM = 120; // 30 else if( pb2 == true && pb3 == false && pb4 == false )TM = 240; // 60 else if( pb2 == false && pb3 == false && pb4 == false )TM = 480; // 120 pb1_count = 0; pb1_state = false; // ADC PRR = (1<<PRADC); // shut down ADC // TIMSK0 = (1<<TOIE0); // TIMER0 TCCR0B = (1<<CS02) | (1<<CS00); // 1/1024 // MCUCR &= ~(1<<SM1); // idle mode MCUCR &= ~(1<<SM0); // idle mode MCUCR |= (1<<SE); sei(); while(1) { // asm("sleep"); // TIMSK0 &= ~ (1<<TOIE0); // TIMER0 // PB1 bool pb1 = false; if( PINB & (1 << PINB1) )pb1 = true; // , if( pb1 != pb1_state )pb1_count = 0; pb1_state = pb1; // if( pb1_count >= TM ){ PORTB |= (1 << PB0); // digitalWrite(PB0, HIGH);} _delay_ms(1000); // PORTB &= ~(1 << PB0); // digitalWrite(PB0, LOW);} pb1_count = 0; // } TIMSK0 = (1<<TOIE0); // TIMER0 sei(); } return 0; }
Todo o código cabe em 340 bytes - exatamente um terço de um kilobyte de memória minuciosa. A operação do temporizador é verificada simplesmente - dependendo do tempo de instalação - o LED acende periodicamente por 1 segundo. Neste momento, a tensão Vout de saída 5V desaparece. Se o contato de “entrada” for fechado ao terra com uma frequência de 1 segundo, a redefinição não será realizada e o LED não acenderá.
O gerenciamento WDT no programa principal é o seguinte
#define PIN_WDT 5
Só isso. Todos os arquivos de origem, circuitos e placas de circuito podem ser baixados de
Github