Schrankbeleuchtung - Arduino hängt sich auf

Liebe alle,

ich habe (zunächst stolz) mein erstes Arduino-Projekt zu Ende gebracht: Eine Beleuchtung eines Kleiderschranks mit 2 Türen.
Folgendes Grobkonzept wollte ich umsetzen:

  • Schranktür geht auf (==Schalter schließt) -> Licht geht an (mit fading)
  • Schranktür geht zu -> Licht geht aus (mit fading)
  • Schranktür bleibt offen stehen -> Licht geht nach 12min automatisch aus

Das klappt soweit auch gut - für eine Weile. Nach ca. 1-2 Tagen hängt sich das ganze irgendwie auf: Mal bleibt das Licht an oder aus und nichts reagiert mehr (Schalterbetätigung hat keinen Effekt mehr). Ein Reset des Arduino Nano hilft - für 1-2 Tage :frowning:

Ich kenne mich mit Programmierung nicht sonderlich aus, könnte mir aber vorstellen, dass irgendeine Zahl überläuft oder so?!?! Nur hab ich keinen Schimmer welche oder wo. Hatte gelesen, dass man mit millis nach 48 Tagen evtl. Probleme kriegen kann - aber doch nicht nach 1 Tag?!

Unten mein Sketch. Bitte verzeiht meine deletantische Programmierei. Ich bin mir bewusst, dass man das sehr viel eleganter lösen kann - nur ich vermochte es nicht :wink:
Schalter 1 und 2 sind im Wesentlichen Copy-Paste.

Schon mal 1000 Dank an alle, die sich das hier anschauen!!!!!!

Cheers,
karatebietz

//-----------------------------------------------------
//Schaltkreise 1 und 2 sind identisch und unterscheiden sich nur durch Zahl 1 bzw. 2
//-----------------------------------------------------

#define Transistor1 3 //Transistor für Schaltkreis 1 an PIN 3 angeschlossen (=PWM-Pin)
#define Transistor2 5
#define Schalter1 10   //Schalter für Schaltkreis 1 an Pin 10
#define Schalter2 8


boolean SwitchWasClosed1 = true;    //registriere, ob Schalter schon länger offen ist
boolean SwitchWasClosed2 = true;    

unsigned long startMillis1; //Startzeit für neue Periode
unsigned long startMillis2;
unsigned long startFadeDownMillis1; //Startzeit für Fadingeffekt (Nur bei Licht-Aus)
unsigned long startFadeDownMillis2;

byte brightness1 = 0; //Anfangshelligkeit
byte brightness2 = 0;


//Diese Parameter sind für beide Schaltkreise gleich und bleiben konstant

const unsigned long fadingPeriod = 15; //Verzögerungszeit für Fading - je groesser, desto langsamer
const unsigned long maxPeriod = 720000; //Maximale Leuchtdauer (in ms) -> 12 min
byte maxBrightness = 250; // maximale Helligkeit (255=max)




void setup() {
  // put your setup code here, to run once:

  pinMode(Transistor1, OUTPUT);
  pinMode(Transistor2, OUTPUT);
  pinMode(Schalter1, INPUT_PULLUP);
  pinMode(Schalter2, INPUT_PULLUP);
  startMillis1 = millis(); //initial Startzeit;
  startMillis2 = millis();
  startFadeDownMillis1 = millis();   //initiale Startzeit für downfading (damit es überhaupt losgeht)
  startFadeDownMillis2 = millis();
}




void loop() {
  // put your main code here, to run repeatedly:

  schalter1();    //Durchführung/Überwachung von Schalter 1
  schalter2();    //Durchführung/Überwachung von Schalter 2
}


//___________________________Schalter 1___________________________


void schalter1() {
  if (digitalRead(Schalter1) == LOW)  //Zusatz if-Bedingung wird benötigt um Timer neu zu setzen + Zustand zwischen fading an und fading aus zu unterscheiden (sonst Licht-An-Licht-Aus-Loop)
  {
    if(brightness1 > 5) //wenn Licht vorher an war, fading Licht aus (sonst tue nichts)
    {
      fadeDown1();
    }

    if(brightness1 <= 5)  //Wenn Licht dunkel genug, schalte ganz aus und setze Variablen auf default zurück
    {
    SwitchWasClosed1 = true; // Schalter war zu --> "fading an" Schleife wird als nächstes durchlaufen
    digitalWrite(Transistor1, LOW);  //Setze Transistor auf definierten Wert "0" zurück
    brightness1 = 0; //setze Anfangsbrightness wieder auf 0
    }
  }
    
  else //Wenn Schalter geschlossen wird, mache Licht an
  {
     if(brightness1 <= maxBrightness and SwitchWasClosed1 == true and millis() - startMillis1 >= fadingPeriod) //wenn erfüllt: noch keine mximale Helligkeit + Schalter gerade geöffnet worden + Zeit für nächsten Fading-Schritt
     {
        analogWrite(Transistor1, brightness1); //setze Helligkeit
        brightness1++; //erhöhe Helligkeit (bis Maximum erreicht ist)
        startMillis1 = millis();  //setze aktuelle Zeit als neue Startzeit (um Fading zu erzielen)
     }
     
     
     if(millis() - startMillis1 >= maxPeriod)  //wenn die maximale Wartezeit vorüber ist (Tür ist zu lange offen geblieben), wieder Licht aus (mit fading)
     {
      SwitchWasClosed1 = false;  //Sage, dass Schalter offen stehen geblieben ist -> lasse Licht aus (sonst loop im fading)
      
       fadeDown1();
        
       if(brightness1 <= 5)  //Wenn minimale Helligkeit erreicht, muss Transistor auf LOW gezogen werden, sonst glimmen die LED weiter
       {
         digitalWrite(Transistor1, LOW);
       }

    }
  }
   
 
}


void fadeDown1() //Funktion zum Ausdimmen der LED an Schalter 1
{
  if(millis() - startFadeDownMillis1 >= fadingPeriod and brightness1 > 5)
        {
          analogWrite(Transistor1, brightness1); //setze Helligkeit
          brightness1--; //erhöhe Helligkeit bis Maximum erreicht
          startFadeDownMillis1 = millis();  //setze aktuelle Zeit als neue Startzeit fuer Downfading
          
        }
}



//___________________________Schalter 2___________________________


void schalter2() {
  if (digitalRead(Schalter2) == LOW)  //Zusatz if-Bedingung wird benötigt um Timer neu zu setzen + Zustand zwischen fading an und fading aus zu unterscheiden (sonst Licht-An-Licht-Aus-Loop)
  {
    if(brightness2 > 5) //wenn Licht vorher an war, fading (sonst tue nichts)
    {
      fadeDown2();
    }

    if(brightness2 <= 5)  //Wenn Licht dunkel, schalte ganz aus und setze Variablen auf default zurück
    {
    SwitchWasClosed2 = true; // Schalter war zu --> "fading an" Schleife wird als nächstes durchlaufen
    digitalWrite(Transistor2, LOW);  //Setze Transistor auf definierten Wert "0" zurück
    brightness2 = 0; //setze Anfangsbrightness wieder auf 0
    }
  }
    
  else //Wenn Schalter geöffnet wird, mache Licht an
  {
     if(brightness2 <= maxBrightness and SwitchWasClosed2 == true and millis() - startMillis2 >= fadingPeriod) //wenn erfüllt: noch keine mximale Helligkeit + Schalter grade geöffnet worden + Zeit für nächsten Fading-Schritt
     {
        analogWrite(Transistor2, brightness2); //setze Helligkeit
        brightness2++; //erhöhe Helligkeit bis Maximum erreicht
        startMillis2 = millis();  //setze aktuelle Zeit als neue Startzeit
     }
     
     
     if(millis() - startMillis2 >= maxPeriod)  //wenn die maximale Wartezeit vorüber ist, wieder Licht aus (mit fading)
     {
      SwitchWasClosed2 = false;  //Sage, dass Schalter offen stehen geblieben ist -> lasse Licht aus (sonst loop im fading)
      
       fadeDown2();
        
       if(brightness2 <= 5)  //Wenn minimale Helligkeit erreicht, muss Transistor auf LOW gezogen werden, sonst glimmen die LED weiter
       {
         digitalWrite(Transistor2, LOW);
       }

    }
  }
   
 
}


void fadeDown2() //Funktion zum Ausdimmen der LED
{
  if(millis() - startFadeDownMillis2 >= fadingPeriod and brightness2 > 5)
        {
          analogWrite(Transistor2, brightness2); //setze Helligkeit
          brightness2--; //erhöhe Helligkeit bis Maximum erreicht
          startFadeDownMillis2 = millis();  //setze aktuelle Zeit als neue Startzeit fuer Downfading
          
        }
}

Hi

Der Sketch sieht (nachdem Man STRG+T gedrückt und diverse Leerzeilen entfernt hat) eigentlich ganz gut aus.
Keinerlei Warnungen, keine Strings, kein 'durch die Funktionen gespringe' - kA, was Da schief läuft.

Womit versorgst Du die Elektronik?
(wobei der Arduino bei SPannungseinbruch dann resetten müsste, BOD, oder?)

MfG

Der Sketch sieht eigentlich ganz gut aus.

Ich sehe auch keinen Grund für ein Hängen nach 1...2 Tagen.

Erstaunlich, dass es sich auch im "Licht an" - Zustand aufhängt. Das ist ja nur max. 12 Minuten nach "Tür auf" der Fall. Also eher selten...

Ist es immer nach einer festen Zeit, oder eher nach einer Anzahl Tests?

Ändert sich was, wenn du testweise die Code - Verdopplung mal raus nimmst (Nur 1 Schaltkreis)?
Dass das nicht sehr elegant ist, soll mal kein Thema sein.

Hey,

Danke für die super schnellen Rückmeldungen! :slight_smile:

Die LED-Streifen (insgesamt 10 Stück) werden über ein 24V-Netzteil versorgt. Da zieht sich der Arduino dann (via Step-Down Regler) seine 5V.

Nach dem ersten Aufhängen hatte ich mal die Spannung angeschaut - da hatte der Arduino noch seine 5V...

Die Reduktion auf einen Schaltkreis könnte ich natürlich mal versuchen. Eine Regelmäßigkeit habe ich noch nicht feststellen können. War bislang aber auch erst 3mal - im Versuchsaufbau (auf dem Tisch liegend mit max. 5s Leuchtdauer) ist mir vorher aber auch nix aufgefallen.

Viele Grüße :slight_smile:

Fehler konnte ich leider auch nicht entdecken.

Allerdings hat mich dies:

brightness1--; //erhöhe Helligkeit bis Maximum erreicht

irritiert.
Das ist in beiden down-Funktionen falsch dokumentiert.

Ich verstehe auch nicht, warum du den Transistor zusätzlich über eine digitale Anweisung ausschaltest und das nicht über die "fadeDown"-Funktion erledigst. Damit kannst du doch auch bis auf "0" runter gehen.

Hallo,

jetzt sollte die nächste Frage lauten, wie werden die 5V erzeugt? Womit? Wo sind die 5V angeklemmt?
Am Besten wäre ein präziser und vollständiger Schaltplan.

if(brightness1 <= maxBrightness and SwitchWasClosed1 == true and millis() - startMillis1 >= fadingPeriod) //wenn erfüllt: noch keine mximale Helligkeit + Schalter gerade geöffnet worden + Zeit für nächsten Fading-Schritt

ich würde es mal so

if(brightness1 <= maxBrightness && SwitchWasClosed1 == true && millis() - startMillis1 >= fadingPeriod) //wenn erfüllt: noch keine mximale Helligkeit + Schalter gerade geöffnet worden + Zeit für nächsten Fading-Schritt

versuchen

ardubu:
ich würde es mal so

if(brightness1 <= maxBrightness && SwitchWasClosed1 == true && millis() - startMillis1 >= fadingPeriod) //wenn erfüllt: noch keine mximale Helligkeit + Schalter gerade geöffnet worden + Zeit für nächsten Fading-Schritt

versuchen

Wenn es anders nicht richtig wäre, müsste der Compiler nicht einen Fehler zeigen ?

Ich kenne mich mit Programmierung nicht sonderlich aus, ...

Das musst du nicht sagen. Das sehen wir auch so.

Wenn es anders nicht richtig wäre, müsste der Compiler nicht einen Fehler zeigen ?

Syntaxfehler kann der Compiler leicht bemerken.

Bei logischen Fehlern tut er sich schwerer
Dafür muss das Denkstübchen aktiviert werden

Bei dem Ausdruck würde ich zerlegen empfehlen, und/oder Klammern setzen

Unten mein Sketch. Bitte verzeiht meine deletantische Programmierei. Ich bin mir bewusst, dass man das sehr viel eleganter lösen kann - nur ich vermochte es nicht

Dennoch muss ich dir sagen, was mich an deinem Programm stört.

Ich kann den Code nicht (gut) lesen.

  1. Zu tiefe Verschachtlungen
  2. Zu viele/komplizierte Bedingungen in den Abfragen
  3. Unstrukturierte Daten. (Variablen durchnummerieren ist keine Struktur)

Der Code ist zwar nicht schön, aber eigentlich nicht allzu kompliziert.
Und wenn der mehrere Stunden richtig läuft, ist es eigentlich unwahrscheinlich, dass das beobachtete Verhalten ( Ausgänge ändern sich nicht mehr, bleiben entweder HIGH oder LOW ) an einem Programmierfehler liegt.

Da du Pin 13 (LED_BUILTIN) an deinem Nano nicht benutzt, bau doch da mal ein einfaches Blinken ein, um zu sehen, ob das wenigstens weiterlebt.

void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
   ...
}
void loop () {
   digitalWrite (LED_BUILTIN, ((int)millis() & 0x200) != 0 ); // blinkt mit 1,024 Hz
   ...
}

Hey zusammen!

Danke wieder an alle Antworter :slight_smile:

Ich werde mal einen Schaltkreis im Sketch auskommentieren und auch den PIN 13 aktivieren. Das klingt nach Debugging :slight_smile: (Wenn ich den Netzstecker ziehe und wieder einstecke, ändert das übrigens nichts am Zustand, wenn er hängt...)

  • Als Schaltplan habe ich leider nur eine Amateur-Handskizze - hoffe das hilft euch trotzdem erstmal. (Für jeden Schaltkreis ist nur eine LED repräsentativ eingezeichnet - hier sind eigentlich je 5 Leisten parallel geschalten)

@combie: Ja, dass es arg verschachtelt ist etc, weiß ich - ich konnte es leider nur nicht anders lösen. Scusi

ardubu:
ich würde es mal so

if(brightness1 <= maxBrightness && SwitchWasClosed1 == true && millis() - startMillis1 >= fadingPeriod) //wenn erfüllt: noch keine mximale Helligkeit + Schalter gerade geöffnet worden + Zeit für nächsten Fading-Schritt

versuchen

Implementiere ich auch gern - schadet sicher nix:)

HotSystems:
Fehler konnte ich leider auch nicht entdecken.

Allerdings hat mich dies:

brightness1--; //erhöhe Helligkeit bis Maximum erreicht

irritiert.
Das ist in beiden down-Funktionen falsch dokumentiert.

Ich verstehe auch nicht, warum du den Transistor zusätzlich über eine digitale Anweisung ausschaltest und das nicht über die "fadeDown"-Funktion erledigst. Damit kannst du doch auch bis auf "0" runter gehen.

Ja, hier ist die Doku falsch. Klassischer Strg+C/Strg+V Fehler.
Wenn ich kein "digitalWrite(Transistor1, LOW)" setze, glimmen bei mir die LED immer noch etwas...

Also DANKE schon mal euch allen! - ich berichte, wenn der Arduino wieder hängt (oder eben nicht ;))

karatebietz:
... Das klingt nach Debugging :slight_smile:

Ohje. Ich hoffe, Du kennst gute Flüche.

karatebietz:
... Klassischer Strg+C/Strg+V Fehler.

Programmieren per c+p?!!! Ja, fluchen sollst Du (müssen)!

SCNR

Gregor

karatebietz:
.....

  • Als Schaltplan habe ich leider nur eine Amateur-Handskizze - hoffe das hilft euch trotzdem erstmal. (Für jeden Schaltkreis ist nur eine LED repräsentativ eingezeichnet - hier sind eigentlich je 5 Leisten parallel geschalten)
    .....

Das kann daran liegen, dass du nicht bis auf 0 (NULL) runter dimmst, sondern bei 5 aufhörst.
Warum verwendest du nicht anstatt der NPN-Transistoren die N-Mosfets ?

Die sind spannungsgesteuert und haben dadurch Vorteile gegenüber den NPN.

  • Als Schaltplan habe ich leider nur eine Amateur-Handskizze - hoffe das hilft euch trotzdem erstmal. (Für jeden Schaltkreis ist nur eine LED repräsentativ eingezeichnet - hier sind eigentlich je 5 Leisten parallel geschalten)

Das könnte dein Problem sein. Je nach Stromverstärkung der Transistoren, werden evtl. die Ausgänge des Arduino überlastet.
Also nimm einen Mosfet.
Z.B. den IRLD024. Allerdings kenne ich deinen Strom nicht, musst du prüfen.

Bei dem Schaltplan fehlen mir die Bauteilwerte/Bezeichnungen.
Ein interessanter Wert: Basisstrom

Zu den Schaltern/Tastern
Bei kurzen Kabeln, reichen meist die eingebauten Pullup.
Bei längeren Kabeln verwendet man niederohmigere.

Stichwort: Antennenwirkung


Notnagel:
Wenn das Programm wirklich hängt, dann kann dir der WDT die Party retten.

Grundsätzlich:
Unterbinde Störungen an der Quelle.

Hi

karatebietz:
(Wenn ich den Netzstecker ziehe und wieder einstecke, ändert das übrigens nichts am Zustand, wenn er hängt...)

DAS liest sich aber nicht nach einem Arduino-Hänger - nach einer Spannungswiederkehr muß der Arduino 'neu booten' und mit dem Sketch von Vorne anfangen, also bei DIr dann wohl Hochdimmen, da die Türen (noch) offen sind.

Spaßeshalber einen Kondensator am Arduino zwischen +5V und GND einsetzen?

MfG

Hey folks!

Kurzes Update von mir:

Mit nur einem Schaltkreis und "and" durch "&&" Ersetzung ist genau das gleiche Problem wieder aufgetreten. Wieder nach ca. 1.5 Tagen (genau kann ich es nicht sagen, da ich zwischendurch auf Arbeit bin ;))
Zuvor hatte ich den Schalter relativ oft in verschiedenen Intervallen betätigt - ohne Ergebnis. D.h. das ganze ist wohl ziehmlich sicher ein Zeitproblem?!

PIN 13 hat dabei nicht mehr geleuchtet, d.h. da lief nix mehr beim Arduino Nano...

Ein kurzes Resetknopfdrücken und alles lief wieder 1a :confused:

postmaster-ino:
HiDAS liest sich aber nicht nach einem Arduino-Hänger - nach einer Spannungswiederkehr muß der Arduino 'neu booten' und mit dem Sketch von Vorne anfangen, also bei DIr dann wohl Hochdimmen, da die Türen (noch) offen sind.

Spaßeshalber einen Kondensator am Arduino zwischen +5V und GND einsetzen?

Ist das, um Spannungsschwankungen abzufangen?! Welche Kondensatorgröße würdest Du da empfehlen?
(Mal ganz kindlich naiv gefragt: Wieso hilft hier ein "Reset" beim Arduino, wenn der Arduino kurzzeitig zu viel/wenig Spannung sieht? Und ein Netzsteckerziehen nicht?!)

Danke euch! (mal wieder :slight_smile: )

Da wir noch keine Bauteilwerte haben, können wir schlecht was dazu sagen.

Also bitte Bauteildaten liefern.

Ist der gepostete Sketch noch aktuell ?

Hallo,

wird wohl dann eher an der Spannungsversorgung liegen. Nur leider sagst du nicht wie du deinen Nano versorgst. Wie genau und womit erzeugst du die 5V aus den 24V? Welche Leistung hat das Netzteil und welche Leistung haben die LED Streifen? Verkabelung? Klingeldraht oder armdicke Kupferschienen?

Beim Reset wird die Versorgungsspannung anscheinend ausreichend stabil sein. Beim Stecker raus/rein eben nicht.

@TO
Ist es jetzt so schwer, die nötigen Informationen zuliefern ?
Wie sollen wir helfen, wenn du die Fragen nicht beantwortest ?
Du sitzt allein vor deiner merkwürdigen Schaltung.

Ich hätte da mal eine naive Hardware-Frage an die Experten:
Verschiebt der TO nicht mit den INPUT_PULLUP für die Schalter den GND für den Step-Down-Regler?

Wer weiß, was der dann damit macht - vielleicht stellt er die Arbeit ein. Das würde zumindest das Erlöschen der BUILTIN-LED im Fehlerfall erklären.

Gruß Walter