Arduino stürzt ab - Uno + 74HC595 + Multiplexing

Hallo liebe Community,

wie der Titel schon erahnen lässt stürzt mein Arduino Board ständig ab. Und da ich mir nicht mehr weiterhelfen kann hoffe ich das ihr es könnt :wink:

Ich habe das Problem in meinem Code aber bereits ein wenig eingrenzen können. In den Kommentaren habe ich mal beschrieben was ich meinen

// Uhrzeit einstellen
String timeSettings(char* toSet) {
  
  // Doppelpunkt dauerhaft ein, wenn Einstellungen aktiv
  digitalWrite(dots, HIGH);
  delay(5);  
  if (toSet == "stunden") {

    tmax = 23;
    digNo1 = countUpDown(tmax, tmin, false);
    
    // Bis hier hin funktioniert noch alles
    if(digitalRead(saveButton) == false && bitIsSet == false) {
      AllDispOff();
      delay(200);
      bitIsSet = true;
    }
    
    // Lasse ich "saveButten" los, stürzt mein Arduino ab.
    // Unverständlich für mich ist, dass er nur abstürzt wenn die Passage "Datum einstellen" aktiviert ist.
    // Ausgeklammert bekomme ich keine Probleme
    // Paradox ist, das die Passage aber eigentlich gar nicht abgearbeitet wird!?
    if(digitalRead(saveButton) == true && bitIsSet == true) {
      bitIsSet = false;
      Serial.println("Stunden gesetzt"); 
      schritt = 1;
      countUpDown(tmax, tmin, true);
      hours = digNo1;
    }  
  }
}

// weiterer Code
// ....

void loop() {

  // Uhrzeit einstellen
  if(timeSettingsFinished == false) {
    
    outputDigit(digNo1, digNo2); 
    switch (schritt) {
      case 0:
      timeSettings("stunden");
      break;
      
      case 1:
      timeSettings("minuten");
      schritt = 10;
      break; 
    }
  }

  // Datum einstellen
  // Klammere ich den folgenden Teil aus stürzt mein Arduino nicht ab!!???
  // Obwohl in diesem Moment ja eigentlich nicht ausgeführt
  if(dateSettingsFinished == false) {
    
    outputDigit(digNo1, digNo2);
    switch (schritt) {
      case 10:
      dateSettings("jahre");
      break;
      
      case 11:
      dateSettings("tage");
      break; 
    
      case 12:
      dateSettings("monate");
      schritt = 0;
      break; 
    }  
  }
  
  if(timeSettingsFinished == true && dateSettingsFinished == true) {
    dots_toggle();
    outputDigit(hour(), minute());
  }
  
}

Ich hoffe ihr könnt mir weiterhelfen.

Liebe Grüße

Strings vergleichen geht mit strcmp, nicht mit ==:
http://www.cplusplus.com/reference/cstring/strcmp/

Mit == überprüfst du nur ob die Pointer gleich sind.

Und wieso hat timeSettings() ein String-Objekt als return-Wert, wenn gar nichts zurückgegeben wird?

Ich würde hier aber eher enums verwenden, wenn du aussagekräftige Namen willst. Das ist wesentlich einfacher und bequemer:

enum states { STUNDEN, MINUTEN };

void timeSettings(states state)
{
     if(state == STUNDEN)
     {
	Serial.println("Stunden");
     }
     else
     {
	  Serial.println("Minuten");
     }
}

void loop()
{
     timeSettings(STUNDEN);
}

techmike:
wie der Titel schon erahnen lässt stürzt mein Arduino Board ständig ab.

Wenn der Teil des Codes, den Du nicht vorzeigst, im selben Maße RAM-Speicher für nichts verschleudert, wie die vorgezeigten Code-Abschnitte, dann dürfte der Sketch ein gewaltiges RAM-Speicherproblem haben.

Wenn Du versuchst mehr RAM-Speicher zu verbrauchen als der Controller eingebaut hat, dann läuft der Datenbereich (Heap) in den Rücksprungadressenbereich (Stack) hinein und der RAM wird mehrfach für verschiedene Dinge verwendet: Eine Speicherstelle im RAM kann dann beispielsweise gleichzeitig den Inhalt einer Variablen darstellen und eine Rücksprungadresse, zu der die Programmausführung nach Abarbeitung einer Funktion zurückspringen soll. Und wenn das passiert, ist das dann der Zeitpunkt, ab dem das Programm nicht mehr funktioniert und "durchdreht" oder "sich aufhängt".

Okay,

also erstmal Danke für die Antworten. Das es ein Speicherproblem sein könnte hat sich damit wohl für mich bestätigt.

Wie kann ich denn prinzipiell verhindern das mein Speicher knapp wird? Scheinbar ist mein "Stil" ja falsch. Okay enums wurden erwähnt, String Funktion obwohl kein return Wert dazu.

Was kann man noch machen und gibt es eine Möglichkeit solch Probleme irgendwie zu ermitteln???

Danke schon mal im Voraus :slight_smile:

Leider bekomme ich wenn ich das hier ausprobiere

Ich würde hier aber eher enums verwenden, wenn du aussagekräftige Namen willst. Das ist wesentlich einfacher und bequemer:

enum states { STUNDEN, MINUTEN };

void timeSettings(states state)
{
    if(state == STUNDEN)
    {
Serial.println("Stunden");
    }
    else
    {
  Serial.println("Minuten");
    }
}

void loop()
{
    timeSettings(STUNDEN);
}

folgende Fehlermeldung

sketch_oct05b:2: error: variable or field 'timeSettings' declared void
sketch_oct05b:2: error: 'states' was not declared in this scope

Habe ich was übersehen???

Mhh, ich hatte das in Visual C++ getestet und angenommen, dass es sich auf dem Arduino genauso verhält. Sorry.

Das funktioniert:

void timeSettings(uint8_t state)
{
     if(state == STUNDEN)
     {
	Serial.println("Stunden");
     }
     else
     {
	  Serial.println("Minuten");
     }
}

Kompiliert und läuft auch bei mir in Programmen so. Ein enum setzt die Text Konstanten im Hintergrund nur in Zahlen um (angefangen mit 0 wenn man sonst nichts angibt). Deshalb kann man das mit Integer-Typen gleichsetzen. Statt “uint8_t” kannst du auch “byte” schreiben.

techmike:
Wie kann ich denn prinzipiell verhindern das mein Speicher knapp wird? Scheinbar ist mein “Stil” ja falsch. Okay enums wurden erwähnt, String Funktion obwohl kein return Wert dazu.

Was kann man noch machen und gibt es eine Möglichkeit solch Probleme irgendwie zu ermitteln???

Wie Du mit möglichst wenig RAM-Speicherverbrauch möglichst viel Funktionalität programmieren kannst, hängt vom konkreten Programm ab.

Die eine Sache ist, mit Texten insgesamt sparsam umzugehen, also beispielsweise bei der Übergabe von ein paar verschiedenen Variablen symbolische Konstanten zu verwenden, wie von Serenifly vorgeschlagen, und keine Texte.

Die andere Standardmöglichkeit wären bei Textkonstanten, die sich nie ändern, diese möglichst nur im Programm-Flashspeicher statt im RAM zu halten. Die ist beispielsweise bei allen per print und println ausgegebenen konstanten Texten wie folgt mit dem F-Makro möglich.

Statt:
Serial.println(“Stunden gesetzt”);
Setze:
Serial.println(F(“Stunden gesetzt”));
Schon hast Du durch die Verwendung des F-Makros bei print(ln) die “Anzahl der sichtbaren Zeichen im Text plus 1” an RAM-Speicher eingespart.

Überhaupt bietet es an, wenn das Programm mit vielen Konstanten arbeitet, diese Konstanten im PROGMEM Flashspeicher zu halten:
http://arduino.cc/de/Reference/PROGMEM

Da Du aber immer zusätzliche Funktionen aufrufen mußt, um Konstanten aus dem Progmem herauszuholen, werden die Programme einerseits komplizierter und größer. Bis auf die Verwendung des F-Makros bei print(ln) ist die Verwendung von PROGMEM Konstanten eher was für Fortgeschrittene als für Anfänger.

Den aktuellen freien RAM-Speicher kannst Du Dir im laufenden Programm überwachen, indem Du diese Funktion in Dein Programm hineinkopierst:

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Und dann mal bei Gelegenheit (z.B. im setup oder in anderen Funktionen) den freien Speicher per Serial.println ausgeben läßt:

Serial.println(freeRam());

Hallo Zusammen,

Sorry das ich mich erst jetzt melde.

Das Board stürzt nun nicht mehr ab! Ich danke euch :slight_smile:

Liebe Grüße