Ein externer Watchdog-Timer ist eine Krücke für arme Entwickler, die kein ordnungsgemäß funktionierendes Programm für Mikrocontroller oder eine stabil funktionierende Schaltung entwickeln können.
Darüber hinaus ist das eingebaute WDT in den meisten modernen Mikrocontrollern verfügbar.
Es gibt jedoch Situationen, in denen Sie mit bestimmten Problemen mit einem fertigen Board oder Modul fertig werden müssen.
Ich habe meine erste WDT gemacht , um
mich mit den seltenen, aber manchmal immer noch auftretenden Hängen des
ESP8266 zu befassen. Darüber hinaus wurde der Soft-Reset damals nicht gespeichert und das ESP-Gehäuse wollte keine Verbindung zu WiFi herstellen. Eine Verzerrung der Stromversorgung mit einem externen WDT löste das Problem.
Das zweite Problem trat mit dem
Elecrow ATMEGA 32u4 A9G GSM-Controller auf . Hier kam es sehr selten zu Einfrierungen der SIM-Karte. (Das gleiche Problem tritt übrigens bei 3G- und 4G-USB-Modems auf). Um dieses Einfrieren zu bekämpfen, müssen Sie die Stromversorgung des SIM-Ke verzerren. Und es scheint, dass sogar das GSM-Modem eine Schlussfolgerung dafür hat, aber diese Funktion ist nicht in der Schaltung des Geräts enthalten. Und um maximale Zuverlässigkeit zu erreichen, musste ich mich erneut an einen externen Wachhund wenden.
Ich habe die Schaltung auf Timer 555 nicht wiederholt. Zu viele Mängel enthüllte sie:
- Große Abmessungen und ziemlich viel Umreifung
- Unbequeme Einstellung der Reaktionszeit mit einem Abstimmwiderstand
- Ziemlich lange Rücksetzzeit (Kondensatorentladung erforderlich)
- Nun, der potenzielle Hang von MK mit einem niedrigen Pegel am Ausgang des Timers, wenn der Timer gerade nicht mehr funktioniert.
- Und ich habe im Internet keine OpenSource-Projekte gefunden, die meinen Anforderungen vollständig entsprachen.
Anforderungen an den neuen WDT
- Geringe Kosten des Geräts, einfache Herstellung und kleine Abmessungen
- Steuerung der periodischen Änderung des Logikpegels 0/1 am Eingang
- Einfache Anpassung der Reaktionszeit (optional eine Auswahl vordefinierter Intervalle)
Eisenentwicklung
Der
ATtiny13-Mikrocontroller wurde als
Hauptmikroschaltung ausgewählt. Seine Fähigkeiten waren mehr als genug für meine Aufgabe. Und der Preis ist unter Berücksichtigung der Reduzierung der Umreifungselemente fast der gleiche wie der des 555-Mikroschaltkreises.

Fünf Schlussfolgerungen MK (RESET beschlossen, nicht zu berühren) wurden wie folgt verteilt:
- Timer-Ausgang
- Eingang zurücksetzen
- Die drei verbleibenden Schlussfolgerungen sind die Antwortzeiten.
Zur Schaltleistung wird ein P-Kanal-MOSFET verwendet. Jedes kompatible Gehäuse ist geeignet, es ist jedoch ratsam, es mit der sogenannten "logischen Steuerungsebene" zu verwenden - das heißt, es öffnet sich vollständig von einer 3-5 V-Niederspannung: IRLML2502, AO3415 usw. Trotz seiner geringen Größe kann dieser Transistor eine Last von 4A steuern. Wenn Sie etwas anderes schalten müssen, können Sie ein 5-V-Relais direkt an diesen Ausgang anschließen.
Die LED leuchtet auf, wenn der Timer aktiviert und das Hauptgerät ausgeschaltet ist.
Der Hauptanschluss zum Anschließen an die Mikrocontroller-Karte verfügt über vier Ausgänge
- Gemeinsamer Bus
- Input - Reset Timer
- + 5V Ausgang (vom Timer gesteuert)
- Eingang + 5V
Zwei Anschlüsse - ICSP-Programmierer und Leistungsbrücken - können nicht auf der Karte installiert werden. Blinken Sie den Mikrocontroller im Voraus im Programmiergerät und stellen Sie die Reaktionszeit mit einem konstanten Jumper ein.
Teileliste
Herstellung
Die Bretter erwiesen sich als klein - 18 × 22 mm. Ich habe zwei Möglichkeiten:
Für einseitige Fertigung durch LUT:


Und für die Bestellung im Werk mit einem verbesserten Design und Übergängen zwischen den Parteien. (Ich werde gelegentlich bei den Chinesen bestellen)


Heimtechnologie gibt so etwas wie diesen Prototyp.



Firmware
Für die Firmware habe ich einen hausgemachten Programmierer verwendet, der auf Arduino Nano basiert

Ich habe in
der Arduino IDE mit installierter Unterstützung für
Attiny13 - MicroCore programmiert . Die neueste Version der IDE hatte Probleme mit dem ArduinoISP-Programmierer, funktionierte jedoch in der Version von Arduino IDE 1.6.13 einwandfrei. Das freundliche Team arduino.cc hatte keine Lust
herauszufinden , was dort
durcheinander gebracht wurde )))

Tinku ist auf einen internen Resonator mit einer Frequenz von 1,2 MHz eingestellt. Das Programm ist einfach - wir konfigurieren die Ein- / Ausgänge, lesen PB2 -PB4 und bestimmen die Antwortzeit, stellen den Timer ein und wechseln in den IDLE-Modus. Entsprechend dem Timer-Interrupt bestimmen wir den Zustand des Steuereingangs. Wenn sich der Status umgekehrt geändert hat, setzen Sie den Zähler zurück. Wenn der Zählerstand die eingestellte Reaktionszeit überschreitet, verzerren wir die Ausgangsleistung.
#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; }
Der gesamte Code passt in 340 Bytes - genau ein Drittel eines Kilobyte Tinky-Speichers. Die Funktion des Timers wird einfach überprüft - abhängig von der Installationszeit - die LED leuchtet regelmäßig für 1 Sekunde auf. Zu diesem Zeitpunkt verschwindet die Ausgangsspannung Vout 5V. Wenn der Eingangskontakt mit einer Frequenz von 1 Sekunde gegen Masse geschlossen ist, wird der Reset nicht durchgeführt und die LED leuchtet nicht auf.
Das WDT-Management im Hauptprogramm ist wie folgt
#define PIN_WDT 5
Das ist alles Alle Quelldateien, Schaltkreise und Leiterplatten können von heruntergeladen werden
Github