Cão de guarda universal em ATtiny13


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:

  1. Saída do temporizador
  2. Redefinir entrada
  3. 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

  1. Ônibus comum
  2. Entrada - redefinir temporizador
  3. Saída de + 5V (controlada pelo temporizador)
  4. 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 //GPIO ,   WDT bool WDT_flag = false; //    void WDT_begin(){ pinMode(PIN_WDT,OUTPUT); digitalWrite(PIN_WDT,WDT_FLAG); } //   (   1    WDT,  ) void WDT_reset(){ if( WDT_flag)WDT_flag = false; else WDT_flag = true; digitalWrite(PIN_WDT,WDT_FLAG); } 

Só isso. Todos os arquivos de origem, circuitos e placas de circuito podem ser baixados de
Github

Source: https://habr.com/ru/post/pt447004/


All Articles