Zeit sekündlich ausgeben - nach 10 wieder auf 1

Hallo,
habe ein Beispiel aus dem Forum etwas abgewandelt:

unsigned long SecondsRunning() //https://forum.arduino.cc/index.php?topic=224649.0
{ static unsigned long secondsCounted=0;
  static unsigned long prevMillis=0;
  while( millis() - prevMillis >= 1000){      
    secondsCounted++;
    prevMillis += 1000;  
  }
  return secondsCounted;
}


void setup() {
  Serial.begin(9600);
}

unsigned long lastSeconds, thisSeconds;


void loop() {
  for (int n=1; n < 11; n++){
  thisSeconds=SecondsRunning();
  if (thisSeconds == lastSeconds +1)
  {
    lastSeconds+=1;
    Serial.println(n);
  } 
  
}
}

Ziel ist, die Sekunden zyklisch von 1 bis 10 auf dem Monitor auszugeben. Nach 10 solls wieder mit 1 weitergehen.

Warum geht das nicht so? Auf dem Monitor werden "zufällige" Zahlen angezeigt, etwa so:
4
9
4
4
9
8
3
1
6
4
9
4
3
8
6
1
10
Irgendwo muss ein Knoten im Gehirn sein, aber wo?

-richard

Ich tippe auf falsche Variablendefinition.

Und der Fehler ist in Zeile 42 des geheimgehaltenen Teils des Sketches

Deine for-Schleife ist das Problem. Die Laufvariable 'n' hat absolut nichts mit den vergangenen Sekunden zu tun.
Die for-Schleife läuft immer ohne Verzögerung durch. Hast Du innerhalb deiner 10 Durchläufe zufällig einen Sekundensprung, dann wird der momentane Laufwert von 'n' ausgegeben - das hat aber nichts mit den Sekunden zu tun. Ist die for-Schleife durchgelaufen, geht es mit loop() gleich wieder von vorne los.

Dein 'Knoten' dürfte darin liegen, dass Du meinst, ein Durchlauf der Schleife würde 1 Sek. dauern. Das ist aber nicht der Fall - da ist nichts was den Durchlauf bremst.

@ MicroBahner: Einleuchtend. Sorry für den Kurzschluss in meinen Synapsen...

Und eine geheime Zeile gibts nicht... Den Rest krieje mer später...

-richard

Hallo,

ich hab noch nicht genau verstanden was du willst, die Sekunden kannst Du ja nicht anzeigen hast ja keine Uhr.

Was Du kannst : jede Sekunde einen Zähler von 0 an um 1 erhöhen bis er 11 werden will, dann setzt Du ihn aber gleich wieder auf 0 zurück.
Zudem hast du im setup 2 Variablen deffiniert. Diese sind allerdings nur innerhalb des Setup bekannt. Wenn sie global sein sollen, was ich vermute , müssen sie ausserhalb einer Funktion deffiniert werden . Eigendlich macht man das immer ganz am Anfang.

Schau dir die Beispiele aus der IDE an.

while( millis() - prevMillis >= 1000){

}

ist auch denkbar schlecht , das ergibt eine Schleife in der das Programm festhängt, mach ein if daraus .

Heinz

Hallo,

man baut sich einen Sekundentimer und nimmt ihn als Eventtrigger. Jedes Event löst ein Inkrement aus.

byte count {1};

void setup() {
  Serial.begin(9600);
}


void loop()
{

  if (jedeSekunde() )
  {
    Serial.println(count);
    count++;
    if (count > 10)
    {
      count = 1;
    }
  }

}


bool jedeSekunde() 
{ 
  static unsigned long lastMillis = 0;
  unsigned long ms = millis();
  bool state = false;
    
  if (ms - lastMillis >= 1000)
  {
    lastMillis = ms;
    state = true;
  }

  return state;
}

Warum geht das nicht so?

Weiß nicht....
Habe mir das nicht genauer angeschaut... ist mir zu kompliziert.
z.B. die ganzen Schleifen... wozu?

Aber ich kann dir zeigen, wie das bei mir in etwa aussehen könnte.

struct
{
  unsigned long  timestamp = 0;
  byte           sec       = 1;
   
  void operator()(Print &printer)
  {
    if( millis() - timestamp >= 1000)
    {
      timestamp += 1000;
      printer.println(sec); 
      sec %= 10;
      sec++;
    }
  }
} runner;



void setup() { Serial.begin(9600);}
void loop()  { runner(Serial);    }

:grin: Fetischisten dürfen aus dem struct gerne ein class machen :grin:

Danke für Eure freundlichen Hinweise. Post #6 scheint mir am elegantesten, aber da ich mich bei Strukturen auf noch dünnerem Eis als sonst bewege, versuche ich erst Mal den Hinweis aus #5 umzusetzen.
Vielen Dank!

combie:
:grin: Fetischisten dürfen aus dem struct gerne ein class machen :grin:

Würde ich auf jeden Fall empfehlen :slight_smile: :slight_smile:

r_a_mueller:
... da ich mich bei Strukturen auf noch dünnerem Eis als sonst bewege...

Hier geht's auch um Klassen. Da musst Du dich ein wenig mit OOP befassen. Bei C++ kann man das (leider) ein wenig verschleiern :wink: .

Programmieren habe ich gelernt zur Zeit von Pascal - noch bevor Objektorientierung Einzug hielt. In der Zwischenzeit doch vieles vergessen, erst nach der Rente wieder damit angefangen. Deshalb seht mir bitte einiges nach :wink:

In "normaler" Demo-Programmierung macht combies Beispiel dies:

void setup() { Serial.begin(9600);}

unsigned long  timestamp = 0;
byte            sec      = 1;

void loop()  { 
    if( millis() - timestamp >= 1000) {
      timestamp += 1000;
      Serial.println(sec++);
      if (sec > 10) sec = 1;  // 1 .. 10
    } 
}

Der Rest ist, für ein Demo-Beispiel zumindest, Firlefanz.

..hier ist was schief gelaufen ..

mit der Falle := --> = und = --> ==

Gruß Tommy

r_a_mueller:
Programmieren habe ich gelernt zur Zeit von Pascal - noch bevor Objektorientierung Einzug hielt. In der Zwischenzeit doch vieles vergessen, erst nach der Rente wieder damit angefangen. Deshalb seht mir bitte einiges nach :wink:

Dann dürfte einfaches C ohne OO doch überhaupt kein Problem für dich sein.
Ulli

Ich denke, ich komme auch so allmählich wieder rein...

Tommy56:
mit der Falle := --> = und = --> ==

Nö, das hab ich kapiert. Es gab ja auch mal "let" um Werte zuzuweisen (ich glaube in Basic?), genauso wie := wohl eher von historischem Interesse.

Nicht ganz. z.B. die interne Sprache der ORACLE-Datenbank (PL/SQL) arbeitet mit :=

Gruß Tommy

r_a_mueller:
Deshalb seht mir bitte einiges nach :wink:

Ach, da mache dir mal nicht zuviele Gedanken....

Andererseits:
Mit Arduino stehst du mit beiden Beinen in der OOP.
Das kann man versuchen auszublenden, hilft aber wenig.
Den nutzen tut man es sowieso.

Alleine Serial, EEPROM, Wire und die ganzen anderen Libs...
Nahezu alle in C++.

combie:
Mit Arduino stehst du mit beiden Beinen in der OOP.

Man merkt es nur nicht - zumindest nicht gleich am Anfang :grinning:
( und so Einige wahrscheinlich nie ... )