Millis -- static in der Funktion oder Global

Hallo Leute,

was ist besser :

Wenn ich Millis für eine Funktion benötige, mache ich dann Global so :

unsigned long previousMillisRandom = 0;
void Random(int Pause, boolean OnlyOne, byte bright) {// das ist dancing

  unsigned long currentMillisRandom = millis();

  strip.setBrightness(bright);

  if ((unsigned long)(currentMillisRandom - previousMillisRandom) >= Pause) {

    strip.setPixelColor(random(Anzahl_Pixel), random(0, 255), random(0, 255), random(0, 255));
    strip.show();
    //delay(Pause);
    if (OnlyOne) {
      strip.clear();

    }
    previousMillisRandom = millis();
  }

}

Oder Static direkt in der Funktion, so :

void Random(int Pause, boolean OnlyOne, byte bright) {// das ist dancing

  unsigned long currentMillisRandom = millis();
  static unsigned long previousMillis = currentMillis;
  
  strip.setBrightness(bright);

  if ((currentMillisRandom - previousMillisRandom) >= Pause) {

    previousMillis = currentMillis;
    strip.setPixelColor(random(Anzahl_Pixel), random(0, 255), random(0, 255), random(0, 255)); // um weiß noch ergänzen für noch mehr farben
    strip.show();
    
    if (OnlyOne) {
      strip.clear();

    }  
  }
}

Hoffe es ist richtig geschrieben alles und ihr versteht was ich meine :slight_smile:

Generell sollten Variablen nur dort sichtbar sein wo sie auch gebraucht werden. Also nur innerhalb der Funktion. Dann kann eine andere Funktion auch eine Variable mit dem gleichen Namen verwenden

Pardon,

void Random(int Pause, boolean OnlyOne, byte bright) {// das ist dancing

  unsigned long currentMillisRandom = millis();
 
  static unsigned long previousMillisRandom = 0;

  strip.setBrightness(bright);

  if ((unsigned long)(currentMillisRandom - previousMillisRandom) >= Pause) {

    strip.setPixelColor(random(Anzahl_Pixel), random(0, 255), random(0, 255), random(0, 255)); 
    strip.show();
    if (OnlyOne) {
      strip.clear();

    }
    previousMillisRandom = millis();
  }
}

Diesen Code anstelle den Letzten, sorry der müsste funktionieren von der Logik her.

Hallo,

habe mal aufgeräumt. Auch die Datentypen beachten. Wenn die nur positiv sein können, dann nimm auch nur unsigned. Speziell casten musst du auch nicht. Wo hast du sowas bei dem Zeitenvergleich schon gesehen?
Wenn du schon für millis eine Zwischenvariable verwendest, dann nutze sie auch, sonst kannste überall millis einsetzen.

Und ja nimm in Funktionen wenn immer möglich lokale Variablen. Das Grundgerüst mit millis und Vergleich kannste jetzt in allen Funktionen verwenden die aller x ms dran sind.

void Random(unsigned int Pause, bool OnlyOne, byte bright)  // das ist dancing
{
  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;

  strip.setBrightness(bright);

  if (currentMillis - previousMillis >= Pause) {
    previousMillis = currentMillis;
    strip.setPixelColor(random(Anzahl_Pixel), random(0, 255), random(0, 255), random(0, 255));
    strip.show();
    if (OnlyOne) {
      strip.clear();
    }
  }
}

Die Antwort scheint mir einfach: Mache global, was Du global benötigst und mache lokal, was Du nur lokal verwendest.

Wenn Du currentMillis in verschiedenen Funktionen verwenden möchtest, dann mache es global und setze es am Anfang von loop. Hingegen previousMillis wirst Du nur lokal verwenden wollen, also lokal festlegen.

Da sich lokale Variablen gegenseitig nichts tun, kannst Du den Namen previousMillis in verschiedenen Funktionen nutzen. Das verlagert die notwendige Kreativität weg von den Variablennamen hin zu einem guten Programm.

Aber frage 25 Leute und Du erhätst 26 Antworten :slight_smile:

Aber aufpassen:
Wenn eine lokale Variable den gleichen Namen wie eine globale Variable hat, kann es zu unvorhersehbaren Fehlern kommen.
Schade, dass der Arduino Compiler keine Warnung ausgibt, wenn eine lokale Variable eine globale überschreibt.
Visual Studio C++ macht das.

freddy64:
Wenn eine lokale Variable den gleichen Namen wie eine globale Variable hat, kann es zu unvorhersehbaren Fehlern kommen.

Ich finde die Effekte lokaler Überdeckung absolut vorhersehbar,
für Unerfahrene sind sie vielleicht unerwartet.

Doc_Arduino:
Speziell casten musst du auch nicht. Wo hast du sowas bei dem Zeitenvergleich schon gesehen?

falls es dich interessiert, das habe ich "früher" mal gehabt und habs noch in einem alten Sketch gefunden:

(extra kein Link, weil ich es heute auch nicht mehr so machen würde)
es wurde dann auch 2014 entsprechend diskutiert...

@TO: überlege dir genau wozu du currentMillis brauchst.
Du hast millis() jederzeit zur Verfügung. Nur in ganz seltenen Fällen brauche ich die currentMillis damit am Ende der Funktion noch immer die Eintrittszeit zur Verfügung steht. Meistens kann ich auf currentMillis verzichten und übernehme einfach millis().
previousMillis verwende ich lokal und daher static. "unvorhersebare" Fehler habe ich dadurch noch nie erhalten. Eher ein sauberes zusammenhalten was zusammen gehört.

@Whandall

Ich finde die Effekte lokaler Überdeckung absolut vorhersehbar,
für Unerfahrene sind sie vielleicht unerwartet.

Wenn ein Programm mehrere kB Quellcode hat und 10+x Programmierer daran arbeiten, wird es schwierig, die Effekte lokaler Überdeckungen vorherzusehen.
Deshalb haben High-End IDE's auch eine bessere Syntax-Colorierung und mehr Compiler Warnungen. Da hängt die Arduino IDE noch Lichtjahre hinterher.
Für µC's ist der Code relativ klein und dadurch auch einigermaßen übersichtlich.
Trotzdem: Aufpassen !!!!!

Wenn ein Programm mehrere kB Quellcode hat und 10+x Programmierer daran arbeiten, wird es schwierig, die Effekte lokaler Überdeckungen vorherzusehen

Das ist schon richtig, aber man sollte sowieso in umfangreichen Programmen die Anzahl globaler Variablen auf ein absolutes Minimum beschränken.

Wer meint, mit einer globalen Variablen zu arbeiten aber stattdessen eine eine lokale verwendet, macht auch noch andere Fehler. :slight_smile:
Im umgekehrten Fall (es gibt eine unbekannte globale Variable) schützt der Compiler die globale Variable. Alles ist gut.

Deshalb deklarieren wir globals mit g + Unterstrich vor dem Namen.
Das kommt aus der Java- und PHP Welt, hat sich aber als nützlich erwiesen.

int g_a ist global
int a kann jederzeit lokal verwendet werden.

freddy64:
Wenn ein Programm mehrere kB Quellcode hat und 10+x Programmierer daran arbeiten, wird es schwierig, die Effekte lokaler Überdeckungen vorherzusehen.

Also wenn bei Dir 10+Programmierer nur mehrere kB Quellcode zusammenbringen, dann löse die Truppe auf.
Für sowas hat man klare Coderegeln und dann sind lokale Überdeckungen überhaupt kein Problem, auch wenn es mehrere MB sind.

Gruß Tommy

Falsch: Global
Falsch: Static Lokal
Richtig: Als Instanz Eigenschaft halten
8) 8) 8)