Das ATTiny-Projekt wird zurückgesetzt, wenn das Telefon angeschlossen wird

Projekt

Ich bin noch nicht sehr erfahren mit Elektronik und Mikrocontroller-Programmierung. Ich habe kürzlich (aus Versehen) ein paar ATTiny13A-Mikrocontroller gekauft, vorausgesetzt, ich könnte sie mit der Arduino IDE programmieren.

Aufgrund des geringen Speicherplatzes auf diesen Dingen entschied ich mich für ein einfaches Projekt: ein Leselicht, das sich automatisch ausschaltet. Und ich habe mich entschieden, AVR Studio (6.0) anstelle der Arduino IDE zu verwenden.

Die Schaltung ist ziemlich einfach, denke ich. Zwei Knöpfe, um eine halbe Stunde Licht hinzuzufügen, und ein weiterer, um das Licht sofort auszuschalten. Alles wird von einer USB-Steckdose mit Strom versorgt, die etwa 5 V liefert (5,2, habe ich gemessen).

Ich habe die LED vereinfacht. Tatsächlich gibt es 2 LEDs (ich hatte zuerst 3 geplant) und die entsprechenden Widerstände, weshalb ich auch den Widerstand hinzugefügt habe. Auch die Verbindungen zum AVR-Programmer habe ich weggelassen, da sie für die Schaltung selbst nicht relevant sind.

schematisch

Simulieren Sie diese Schaltung – Mit CircuitLab erstellter Schaltplan

Das Licht funktioniert wie es soll. Es brennt 3 Sekunden lang, wenn ich es einstecke. Ich kann es ein- und ausschalten. Und wenn ich es einschalte, brennt es ungefähr eine halbe Stunde, bevor es sich von selbst ausschaltet. Wenn ich vorher weiß, dass ich mehr als eine halbe Stunde Licht haben möchte, kann ich den Knopf mehrmals drücken, um N mal eine halbe Stunde zu bekommen.

So weit, ist es gut.

Problem: unerwünschte Resets

Jetzt ist das Problem, dass es ziemlich empfindlich auf Spitzen oder Einbrüche zu reagieren scheint. Ich habe eine Wandwarze mit zwei Anschlüssen. Wenn das Nachtlicht in einen von ihnen eingesteckt wird und ich mein Telefon in den anderen einstecke, wird das Nachtlicht zurückgesetzt, leuchtet drei Sekunden lang und schaltet sich dann aus. Dies passiert auch meistens, wenn ich das Telefon ausstecke. Dabei spielt es keine Rolle, ob bei mir das Licht an- oder ausgeschaltet war.

Meine Hauptfrage ist also, wie löse ich diese Resets ? Für andere Ratschläge bin ich auch offen.

Ich werde das Programm hier auch als Referenz einfügen. Ich denke, es ist nicht relevant, aber ich habe versucht, Interrupts zu verwenden und den Controller die meiste Zeit im Schlafmodus zu haben, also werde ich es trotzdem posten, nur für den Fall, dass es wichtige Informationen enthält.

/*
 * NachtLampje.c
 *
 * Created: 22-10-2014 19:46:50
 *  Author: GolezTrol
 */ 

#define F_CPU 1200000UL // Sets up the default speed for delay.h 

#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/wdt.h>

volatile int seconds = 3;
int secondsInc = 1800;

void setupLed() {
    DDRB = 1<<DDB0;
}

void updateLed() {
    // Blink for a moment when we're at 15 seconds, so user might prolong.
    if (seconds > 0 && seconds != 15)
        PORTB |= 1<<PB0;
    else
        PORTB &= ~(1<<PB0);
}

void setTimer(int state) {
    if (state) {
        WDTCR |= (1<<WDP2) | (1<<WDP1); // 1sec
        WDTCR |= (1<<WDTIE); // Enable watchdog timer interrupts
    }       
    else {
        WDTCR &= ~(1<<WDTIE); // Disable watchdog timer interrupts
    }   
}

ISR(WDT_vect) {
    // Timer interrupt
    if (seconds == 0) 
      return;

    if (--seconds == 0) {
        setTimer(0);
    }   
    updateLed();
}

ISR(PCINT0_vect){
    // Button interrupt

    // Button 1 = PB3 = Add half an hour of light.
    if (~PINB & 0x08) {
        seconds += secondsInc;
    }

    // Button 2 = PB 4 = Turn off the lights
    if (~PINB & 0x10) {
        seconds = 0;
    }

    // Enable timer, if necessary
    setTimer(seconds > 0);

    // Update the led.
    updateLed();
}

int main(void) {
    setupLed();

    updateLed();

    setTimer(seconds > 0);

    GIMSK = 0b00100000;    // turns on pin change interrupts
    PCMSK = 0b00011000;    // turn on interrupts on pins PB3 and PB4

    sei(); // Enable global interrupts

    // Use the Power Down sleep mode
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    for (;;) {
        sleep_mode();   // go to sleep and wait for interrupt...
    }
}
Ich bin mir nicht sicher, ob es mit dem von Ihnen gemeldeten Problem zusammenhängt, aber Ihrem Schaltplan fehlt ein Strombegrenzungswiderstand an der Basis des Transistors an Pin 5 der MCU. Ist er in der Schaltung vorhanden und haben Sie ihn beim Erfassen des Schaltplans übersehen?
Ich bemerke das erhebliche Weglassen von Entkopplungskondensatoren in diesem Schaltplan. Hast du sie absichtlich weggelassen oder hast du gar keine?
Die LED(s) benötigen auch Strombegrenzungswiderstände. Sind die LEDs in Reihe oder parallel?
@Ricardo Danke. Ich habe diese im Schaltplan ausgelassen, aber sie sind da. Die LEDs sind parallel.
@Majenko-notGoogle Vielen Dank. Die habe ich nicht. Ich habe ein Steckbrett-Arduino gebaut, das diese hatte, aber ich glaube, ich habe nicht ganz verstanden, wofür sie waren, und ich wusste nicht, dass ich sie auch hier brauchte. Ich lese das Dokument, das Ignacio Vazquez-Abrams verlinkt hat, und ich glaube, ich verstehe jetzt den Zweck des Entkopplungskondensators. Jetzt nur noch herausfinden, welchen Wert es haben muss. :)
100 nF direkt am Vcc-Pin und 10 µF am Platineneingang.
Das wird nicht unbedingt viel nützen, ohne auch eine Diode hinzuzufügen ... 10 uF könnten diese Schaltung für einen Moment betreiben, aber nicht, wenn sie das Ladegerät und damit das Telefon mit Strom versorgen muss.
Hast du Zugriff auf ein Oszilloskop?
@Majenko-notGoogle Danke, das werde ich versuchen. Aber zuerst werde ich Kondensatorglättungsschaltungen und -berechnungen lesen , denn zu diesem Zeitpunkt ist es mir ein völliges Rätsel, wie Sie diese Werte ermittelt haben. :)
@GolezTrol Sie sind nur allgemeine Faustregelwerte, die für die meisten Situationen gut genug sind. Es gibt Zeiten, in denen Sie spezifischere Werte (für analoge Schaltungen) verwenden möchten, aber für die grundlegende Entkopplung von MCUs und ähnlichen digitalen Schaltungen sind 100 nF pro Vcc und 10 µF am Platineneingang in Ordnung.
@IgnacioVazquez-Abrams: Spielst du vielleicht auf "AVR042: AVR Hardware Design Considerations" an ?

Antworten (3)

Höchstwahrscheinlich haben Sie einen Spannungsabfall, wenn Sie das Telefon anschließen oder trennen. Sie sollten immer etwas Kapazität zwischen VCC und GND hinzufügen, um die Schaltung weniger anfällig für Spannungsabfälle zu machen. Versuchen Sie, zwei Kondensatoren parallel hinzuzufügen: 10 uF (Elektrolyt) und 100 nF (Keramik oder Folie). Beachten Sie die Polarität des Elektrolyten! Wenn dies nicht hilft, versuchen Sie, weitere Kappen parallel hinzuzufügen.

Und ja, der Transistor sollte mindestens einen Basiswiderstand von 10 Ohm haben.

Bearbeiten: Für Atmel-MCUs finden Sie die korrekten Kondensatorwerte im Datenblatt oder in den Referenzdesigns.

Aber: Vielleicht noch wichtiger sind die Parasiten (ESR, Equivalent Series Resistance). Achten Sie darauf, eine untere ESR-Kappe (Keramik) so nah wie möglich an den Versorgungsstiften der MCU zu platzieren. Im Allgemeinen gilt: Je größer eine Kappe, desto mehr ESR wird sie haben. 100 nF ist ein Wert, der üblicherweise in der Nähe der Versorgungspins (Chipebene) verwendet wird, während 10 uF oder 4,7 uF üblicherweise verwendet werden, um ganze Schaltungsteile zu puffern (Unterschaltungsebene).

Für Ihre Schaltung reicht es sicherlich aus, zwei 100nF parallel zu den Power-Pins hinzuzufügen.

Danke für deine Antwort. Es wird geschätzt. Ihre Ratschläge habe ich auch aus den Kommentaren verstanden. Können Sie mir sagen, wie ich die richtigen Werte für diese Kondensatoren finden kann? Versuch und Irrtum scheint kein guter Weg zu sein, um sie zu bekommen. Kann die Wahl des falschen Werts meine Schaltung in irgendeiner Weise beschädigen?

Ich würde mit einer 100-nF-Keramikkappe so nah wie möglich an den Vcc- und GND-Pins beginnen. Dies ist eine allgemeine Empfehlung für Atmel uC, um mit kleineren Spannungsabfällen und -spitzen fertig zu werden.

Fügen Sie als zweiten Schritt diesen Elektrolyten irgendwo auf der Stromversorgungsleitung hinzu (muss nicht sehr nahe am Chip sein). Sie können mit etwas im Bereich von 10-100 uF beginnen und eines auswählen, das für die Qualität Ihres Netzteils geeignet ist. Das ist rein experimentell.

Im Allgemeinen gilt: Je größer die Kappe, die Sie hinzufügen, desto widerstandsfähiger wird Ihre Schaltung gegen Leistungsverluste, aber länger wird die Abschaltzeit sein, wenn Sie den Stecker ziehen.

Tipp: 100uF, 47uF und ähnliche Kappen können kostenlos von PC-Mainboards, Fernsehgeräten und anderer Desktop-Elektronik gespült werden.

Bitte informieren Sie sich über POR (Power On Reset)-Schaltungen für Atmel-basierte CPUs, Seite 6

http://www.atmel.com/Images/Atmel-2521-AVR-Hardware-Design-Considerations_ApplicationNote_AVR042.pdf

Um die RESET-Leitung vor weiterem Rauschen zu schützen, schließen Sie einen Kondensator vom RESET-Pin an Masse an. Dies ist nicht direkt erforderlich, da der AVR intern über einen Tiefpassfilter verfügt, um Spitzen und Rauschen zu eliminieren, die einen Reset verursachen könnten. Die Verwendung eines zusätzlichen Kondensators ist ein zusätzlicher Schutz. Ein solcher zusätzlicher Kondensator kann jedoch nicht verwendet werden, wenn DebugWIRE oder PDI verwendet werden.