Suche timer ohne millis()

mastershredder:
hab ich nun mal rein kopiert. Die könnte fast funktionieren.

Da ist nur eine Sache: Ich drücke den Button es zählt hoch, wunderbar. Dann beim zweiten Mal sind es unterschiedliche ZEITEN wo NICHTS passiert bis es weiter läuft.

Hmmm... kannst Du mal ein Foto vom Aufbau machen?
Ich hab ne Ahnung, muss mir da aber noch den tatsächlichen Aufbau antun...

mastershredder:
paulpaulson Der Sketch aus deiner Restekiste sieht auch interessant aus. Aber da hätte ich ein paar Fragen. Habe sie als Kommentar in den Sketch geschrieben.

t // Forum: Suche timer ohne millis()

// Autor: paulpaulson
// Sketch aus der Restekiste

struct ENTPRELLEN {
 unsigned long zeitStempel;
 unsigned long zeitDauer = 20;
};

ENTPRELLEN entprellen;

struct TASTER {
 int pin = 2;
 bool status = HIGH;
};

TASTER taste;

void setup() {

pinMode(taste.pin, INPUT_PULLUP);
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.begin(9600);
 Serial.print(F("und los geht´s mit Taster an Pin ")), Serial.println(taste.pin);
}

void loop() {

static unsigned long jetztZeit;
 static unsigned long startZeit;
 static bool anzeige;
 
 jetztZeit = millis();

// Was übergiebst du da für einen Wert du Teilst doch da durch 0 oder nicht?
 digitalWrite(LED_BUILTIN,jetztZeit/500%2);
 
 bool buttonGelesen = digitalRead(taste.pin);

if (jetztZeit - entprellen.zeitStempel >= entprellen.zeitDauer) {
     entprellen.zeitStempel = jetztZeit;
   
   if (taste.status != buttonGelesen) taste.status = buttonGelesen;
   
   if (!taste.status) {
     
     if (!anzeige) anzeige = true, startZeit = jetztZeit; }
     
  // Zu welchem if Block gehört dieses else, zum obersten?  
 else {
     if (anzeige) anzeige = false, Serial.print((jetztZeit - startZeit)/60000), Serial.println(" min");
   }
 }
}

 // Zu welchem if Block gehört dieses else, zum obersten?  
zum
if (!taste.status)
 // Was übergiebst du da für einen Wert du Teilst doch da durch 0 oder nicht?
die Variable jetztZeit enthält den Rückgabewert von der millis() Funktion
dieser Wert wird durch 500 (msec) geteilt und modulo 2 bewertet. Das Ergebnis kann nur 1 oder 0 zur Ansteuerung der LED sein, die dann mit 1 Hz blinkt.

@ my_xy_projekt Weiß nicht wie ich hier ein Foto einfügen soll. Aber hier Dropbox - Error

Mir ist aber noch etwas aufgefallen:
Da fehlt ja noch die zweite Überprüfung der laststate die ist ja beim zweiten Mal drücken LOW.

if (buttonSig == LOW) { // Taste gedrückt?
  
    if (laststate == HIGH) { // Vorher nicht gedrückt?
    
      laststate = LOW;    // Setze Startzustand
      startmillis = millis();
    }

    else {
      laststate = HIGH;      
    }
        
    if (millis() - startmillis > tik) { // Zeit läuft?
      tik += intervall;
      min++;
      sevseg.setNumber(min);

@ paulpaulson Ah ok Danke.

mastershredder:
Weiß nicht wie ich hier ein Foto einfügen soll.

https://forum.arduino.cc/index.php?topic=148850.0
Punkt 8. NICHT 9!

Hallo ich melde mich zurück, sorry aber ich wahr unverhofft über das Wochenende weg.

Ich bin aber auf dem besten Weg das Rätsel zu lösen :smiley: .

Nur ich habe was festgestellt das mich noch in den Wahnsinn treibt :stuck_out_tongue_closed_eyes: .

Es geht darum, dass der Arduino nicht CHECKT ob ich jetzt zum 1ten oder zum 2ten mal den Button gedrückt habe. Ich habe Tausend Variationen versucht. IF IF, IF ELSE IF, IF ELSE, jetzt habe ich es mit einer && Verknüpfung es will nicht funktionieren. Es wird immer beim ersten drücken gleich 2 ausgewählt.

#include <SevSeg.h>

SevSeg sevseg;

  int button = 2;     //Button pull up  
  int buttonSig = 0;  //Button pull up

  bool laststate = HIGH;
  
  
void setup() {
  
  byte digitPins[]={3,4};
  byte segmentPins[]={6,7,8,9,10,11,12,13};
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool disableDecPoint = true;  

  sevseg.begin(COMMON_ANODE,2,digitPins,segmentPins,updateWithDelays,disableDecPoint);
  sevseg.setBrightness(90);
  pinMode(button, INPUT);       //Button pull up
  digitalWrite(button, HIGH);   //Button pull up  

  Serial.begin(9600);
  
}


void loop() {    
  
  buttonSig = digitalRead(button);
     
  
  if (buttonSig == LOW && laststate == HIGH) { // Taste gedrückt?         
  
      laststate = LOW;    // Setze Startzustand       

      sevseg.setNumber(1);     
      Serial.println("Botton zum: 1ten mal gedrückt");               
     }

            

 else if (buttonSig == LOW && laststate == LOW) {
          
          sevseg.setNumber(2);          
          Serial.println("Botton zum: 2ten mal gedrückt");
    }    
 
  
  sevseg.refreshDisplay();
}

Hab' ich da was falsch verstanden, oder geht es nicht auch darum, die Zeiten von mehreren Tastendrücken aufzuaddieren - also nicht nur eine einfache Stoppuhr - eher ein Betriebsstundenzähler ( oder besser Betriebsminutenzähler :wink: ). Und was ist in den Betriebspausen. Ist da der Arduino komplett abgeschaltet ( sonst saugt der ja auch den Akku leer ). Dann müsste die aufaddierte Zeit ja auch noch im EEPROM gespeichert werden.

Hallo
für "einmal", "zweimal" oder "n-mal" gibt es Zähler, die können das gut machen. :slight_smile:

mastershredder:
Nur ich habe was festgestellt das mich noch in den Wahnsinn treibt :stuck_out_tongue_closed_eyes: .

Nene - Du schaffst es hier den Wahnsinn auszurufen.
Stückwerk, dann nicht mal um die unnötigen Leerzeilen etc gekürzt.
Nu wär es vielleicht a der Zeit das mal komplett zu machen...

// Forensketch
// basiert auf: https://forum.arduino.cc/index.php?topic=731437.msg4928344#msg4928344
// ungetestet
#include <SevSeg.h>

SevSeg sevseg;
int button = 2;     //Button pull up
int buttonSig = 0;  //Button pull up

void setup()
  {
  byte digitPins[] = {3, 4};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool disableDecPoint = true;
  sevseg.begin(COMMON_ANODE, 2, digitPins, segmentPins, updateWithDelays, disableDecPoint);
  sevseg.setBrightness(90);
  pinMode(button, INPUT_PULLUP);       //Button pull up
  Serial.begin(9600);
  }

void loop()
  {
  sevseg.setNumber(readTaste());
  sevseg.refreshDisplay();
  }
int readTaste() {
  static int disp = 1;
  const int maxdisp = 2;
  static unsigned long lastmillis = millis();
  const unsigned long bouncetime = 25; // in ms
  static bool laststate = HIGH;
  if (millis() - lastmillis > bouncetime) { // prellen der Taste unterdrücken
    if (!digitalRead(button) && laststate) {   // Taste gedrückt?
      lastmillis = millis();    // Zeit merken
      laststate = !laststate;   // Tastendruck merken
      disp++;                   // hochzählen
      if (disp > maxdisp){      // begrenzen
        disp = 1;
        }
      }
    else
    if (digitalRead(button)){   // Taste losgelassen?
      laststate = HIGH;         // zurücksetzen
      }
    }
  return disp;                  // zurückgeben
  }

Stückwerk, dann nicht mal um die unnötigen Leerzeilen etc gekürzt.

Das habe ich, dass ich mehr Übersicht habe. bin noch nicht so geübt in dem Gedränge.

Zum Sketch: Ich weiß zwar nicht was der genau machen soll, aber wenn ich ihn starte steht zuerst 1 da, wenn ich dann paar mal drücke steht irgendwann dann 2 da. Also ich muss immer ein paar mal drücken dann ändert sich die Zahl mal von 1 auf 2 oder umgekehrt.

für "einmal", "zweimal" oder "n-mal" gibt es Zähler, die können das gut machen

OK. Wo bekomme ich so einen her? Oder ist das was my_xy_projekt mir geschickt hat so etwas?

also nicht nur eine einfache Stoppuhr

Doch schon; Starte Zeit, halte Zeit, Zeit läuft weiter.

mastershredder:
Zum Sketch: Ich weiß zwar nicht was der genau machen soll, aber wenn ich ihn starte steht zuerst 1 da, wenn ich dann paar mal drücke steht irgendwann dann 2 da. Also ich muss immer ein paar mal drücken dann ändert sich die Zahl mal von 1 auf 2 oder umgekehrt.

Nein nicht ein paar mal.
Das zählen geht im 50 25 millisekundentakt - so schnell kannst Du die Taste gar nicht bedienen.
Sollte Dir das zu langsam sein, ändere "bouncetime".
Das lässt sich sogar einfach mit einem Stück Draht zwischen GND und PIN2 ausprobieren:

12:35:56.957 -> 1
12:35:57.023 -> 2
12:35:57.454 -> 1
12:35:57.752 -> 2
12:35:58.250 -> 1
12:35:58.548 -> 2
12:35:58.814 -> 1
12:35:58.980 -> 2
12:35:59.112 -> 1
12:35:59.244 -> 2
12:35:59.311 -> 1
12:35:59.344 -> 2
12:35:59.742 -> 1
12:35:59.776 -> 2
12:35:59.875 -> 1
12:35:59.941 -> 2
12:36:00.074 -> 1
12:36:00.140 -> 2
12:36:00.206 -> 1
12:36:00.339 -> 2
12:36:00.471 -> 1
12:36:00.604 -> 2
12:36:00.637 -> 1

Deine Frage war:

jetzt zum 1ten oder zum 2ten mal den Button gedrückt habe.

Ich bin davon ausgegangen, das Du die Anzeigen umschalten willst.
Also Start mit: 1
einmal gedrückt: 2
nochmal gedrückt: 1
Das das auch funktioniert, - anders als von Dir beschrieben - kannst Du einfach mit einer seriellen Ausgabe austesten, indem Du nur auf dem SerMon ausgibst.
Genau der selbe Sketch wie oben - nur Ausgabe nicht auf den Displays:

// Forensketch
// basiert auf: https://forum.arduino.cc/index.php?topic=731437.msg4928344#msg4928344
// getestet - Ausgaben siehe oben
// #include <SevSeg.h>

// SevSeg sevseg;
int button = 2;     //Button pull up
int buttonSig = 0;  //Button pull up

void setup()
{
  byte digitPins[] = {3, 4};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool disableDecPoint = true;
  //  sevseg.begin(COMMON_ANODE, 2, digitPins, segmentPins, updateWithDelays, disableDecPoint);
  //  sevseg.setBrightness(90);
  pinMode(button, INPUT_PULLUP);       //Button pull up
  Serial.begin(115200);
}

void loop()
{
  //  sevseg.setNumber(readTaste());
  //  sevseg.refreshDisplay();
  readTaste();
}
int readTaste() {
  static int disp = 1;
  const int maxdisp = 2;
  static unsigned long lastmillis = millis();
  const unsigned long bouncetime = 25; // in ms
  static bool laststate = HIGH;
  if (millis() - lastmillis > bouncetime) { // prellen der Taste unterdrücken
    if (!digitalRead(button) && laststate) {   // Taste gedrückt?
      lastmillis = millis();    // Zeit merken
      laststate = !laststate;   // Tastendruck merken
      disp++;                   // hochzählen
      if (disp > maxdisp) {     // begrenzen
        disp = 1;
      }
      Serial.println(disp);   // Ausgabe:
    }
    else if (digitalRead(button)) { // Taste losgelassen?
      laststate = HIGH;         // zurücksetzen
    }
  }
  return disp;                  // zurückgeben
}

Mit einer vernüftigen Beschreibung, was Du tatsächlich willst, wäre das viel einfacher!

Es geht darum, dass der Arduino nicht CHECKT ob ich jetzt zum 1ten oder zum 2ten mal den Button gedrückt habe. Ich habe Tausend Variationen versucht. IF IF, IF ELSE IF, IF ELSE, jetzt habe ich es mit einer && Verknüpfung es will nicht funktionieren. Es wird immer beim ersten drücken gleich 2 ausgewählt.

Du wolltest nicht mit 2 anfangen.
Jetzt willst Du nicht mit 1 anfangen.
Und nu?

PS: Kannst natürlich auch alles rundrum selber machen und nur zählen. Ersetze loop und readTaste:

void loop()
{
  //  sevseg.setNumber(readTaste());
  //  sevseg.refreshDisplay();
  static int zaehler = 0;
  if (readTaste()) {
    zaehler++;
    Serial.print(F("Zaehler: "));
    Serial.println(zaehler);
  }
}
bool readTaste() {
  static unsigned long lastmillis = millis();
  const unsigned long bouncetime = 25; // in ms
  static bool laststate = HIGH;
  bool tastendruck = LOW;
  if (millis() - lastmillis > bouncetime) {   // prellen der Taste unterdrücken
    if (!digitalRead(button) && laststate) {  // Taste gedrückt?
      lastmillis = millis();                  // Zeit merken
      laststate = !laststate;                 // Tastendruck merken
      tastendruck = HIGH;
      Serial.print(F("Taste gedrückt?: "));
      Serial.println(tastendruck);            // Ausgabe:
    }
    else if (digitalRead(button)) {           // Taste losgelassen?
      laststate = HIGH;                       // zurücksetzen
    }
  }
  return tastendruck;                         // zurückgeben
}

mastershredder:
Doch schon; Starte Zeit, halte Zeit, Zeit läuft weiter.

Ok, dann habe ich es falsch verstanden. Für mich hatte es sich eher nach einem 'Betriebsminutenzähler' angehört.

Du wolltest nicht mit 2 anfangen.
Jetzt willst Du nicht mit 1 anfangen.
Und nu?

Eigentlich will ich mit gar nichts anfangen. Erst ist nichts dann wenn ich einmal drücke will ich die Bedingung 1 und wenn ich das 2te mal drücke will ich die Bedingung 2.

mastershredder:
Eigentlich will ich mit gar nichts anfangen. Erst ist nichts dann wenn ich einmal drücke will ich die Bedingung 1 und wenn ich das 2te mal drücke will ich die Bedingung 2.

Und wenn zum dritten Mal gedrückt wird?

Und wenn zum dritten Mal gedrückt wird?

Im original auch wieder zur 2ten Bedingung. Also es ist eigentlich egal wie oft man drückt, nach dem 1ten mal wird immer wieder die 2Bedingung aufgerufen "Zeit weiterlaufen".

mastershredder:
nach dem 1ten mal wird immer wieder die 2Bedingung aufgerufen "Zeit weiterlaufen".

so:?

void loop()
{
  sevseg.refreshDisplay();
  static int zaehler = 0;
  if (readTaste()) {
    zaehler++;
    Serial.print(F("Zaehler: "));
    Serial.println(zaehler);
  }
  if (zaehler != 0)
  {
    if (zaehler > 2) zaehler = 2;
    sevseg.setNumber(zaehler);
  }
}
bool readTaste() {
  static unsigned long lastmillis = millis();
  const unsigned long bouncetime = 25; // in ms
  static bool laststate = HIGH;
  bool tastendruck = LOW;
  if (millis() - lastmillis > bouncetime) {   // prellen der Taste unterdrücken
    if (!digitalRead(button) && laststate) {  // Taste gedrückt?
      lastmillis = millis();                  // Zeit merken
      laststate = !laststate;                 // Tastendruck merken
      tastendruck = HIGH;
      Serial.print(F("Taste gedrückt?: "));
      Serial.println(tastendruck);            // Ausgabe:
    }
    else if (digitalRead(button)) {           // Taste losgelassen?
      laststate = HIGH;                       // zurücksetzen
    }
  }
  return tastendruck;                         // zurückgeben
}

Hier ist mal noch mein Aufbau:

Und um das Problem mit der "Zeitfunktion" zu lösen, habe ich überlegt; Ich habe hier eine Bibliothek gefunden
GitHub - PaulStoffregen/Time: Time library for Arduino diese stellt eine Uhr zur Verfügung. Dort kann ich die Zeit starten, stoppen, speichern, setten. Man hat einen gleichbleibenden Ablauf(halt eine fertige Uhr) und eine menge Funktionen mit den man was machen kann.

Jetzt ist halt nur das Problem mit der Button Funktion. Was für mich auch voll unlogisch ist; Warum spring ich direkt beim 1ten mal drücken auf die 2? Die laststate Variable steht doch schon von Anfang an auf HIGH ich kann doch niemals auf 2 springen.

Ich weiß auch nicht ob ich das so ganz mit der loop() verstehe. Ich bin halt einen Sequentiellen Ablauf von Softwareprogrammierung gewohnt (Java oder Python).

mastershredder:
Und um das Problem mit der "Zeitfunktion" zu lösen, habe ich überlegt; Ich habe hier eine Bibliothek gefunden

Ich weiß auch nicht ob ich das so ganz mit der loop() verstehe.

Ich habe bisher noch immer keinen Code gesehen.
Du kommst hier ständig mit Fragmenten.
Für das letzte Fragment habe ich Dir mehrere Lösungsmöglichkeiten geliefert.
Aber jetzt bin ich auch am Ende.

Auf meinen letzten Post vom 10.3. hast Du einfach mal still geschwiegen. Heute drehe ich mich im Kreis.
Kann man machen.

Ich habe das Problem gefunden dank deiner Ausgabe auf der Seriellen

// Forensketch
// basiert auf: https://forum.arduino.cc/index.php?topic=731437.msg4928344#msg4928344
// getestet - Ausgaben siehe oben
// #include <SevSeg.h>

// SevSeg sevseg;
int button = 2;     //Button pull up
int buttonSig = 0;  //Button pull up

void setup()
{
  byte digitPins[] = {3, 4};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool disableDecPoint = true;
  //  sevseg.begin(COMMON_ANODE, 2, digitPins, segmentPins, updateWithDelays, disableDecPoint);
  //  sevseg.setBrightness(90);
  pinMode(button, INPUT_PULLUP);       //Button pull up
  Serial.begin(115200);
}

void loop()
{
  //  sevseg.setNumber(readTaste());
  //  sevseg.refreshDisplay();
  readTaste();
}
int readTaste() {
  static int disp = 1;
  const int maxdisp = 2;
  static unsigned long lastmillis = millis();
  const unsigned long bouncetime = 25; // in ms
  static bool laststate = HIGH;
  if (millis() - lastmillis > bouncetime) { // prellen der Taste unterdrücken
    if (!digitalRead(button) && laststate) {   // Taste gedrückt?
      lastmillis = millis();    // Zeit merken
      laststate = !laststate;   // Tastendruck merken
      disp++;                   // hochzählen
      if (disp > maxdisp) {     // begrenzen
        disp = 1;
      }
      Serial.println(disp);   // Ausgabe:
    }
    else if (digitalRead(button)) { // Taste losgelassen?
      laststate = HIGH;         // zurücksetzen
    }
  }
  return disp;                  // zurückgeben
}

Gerade das was ich vorher gesagt habe Stichwort"Sequentiell" und "loop()".

Wenn ich den Button beim ersten mal drücke GEHT es auch erst auf 1 nur da (Ich sage jetzt mal wie ich mir das denke) das Ganze halt im Kreis dreht "loop" Wird während ich noch drücke wieder geprüft und da die laststate dann schon auf LOW gesetzt wurde springe ich auf 2.

mastershredder:
Ich habe das Problem gefunden dank deiner Ausgabe auf der Seriellen

Gut so.

Den Rest kann ich nicht nachvollziehen.
Der Code ist von mir - der liefert beim start 1 beim nächsten mal Taste drücken wird aufaddiert usw.

Willst Du eh nicht.
Also zurück auf meinen Post 4:26 Uhr - und dann komm mit DEINEM(!) Code!