Alarm-Timerzeit mit Taster erhöhen/senken

Hallo zusammen,
ich bin gerade am tüfteln und komme an meine Grenzen.
Vielleicht kann mir jemand hier ein paar Tipps geben und mich bei ein paar Hürden unterstützen.

Ich möchte an einem Alarm-Timer die Zeiteinstellung per Up/Down-Taste in vorgegebenen Schrittweiten (10sec) verändern. Den Code habe ich schon soweit, dass ich dies an einem 4 Digit Display anzeige und im Seriellen Monitor auch ausgegeben wird. (Natürlich auch der Ausgang geschaltet wird). Zusätzlich habe ich eine Begrenzung der Zeiteinstellung, so dass nur Zeiten von 10 - 600 Sek. möglich sind. Wenn nun am AlarmIn (A0) ein Signal (3,3V) ansteht soll die eingestellte Zeit ablaufen und den OutputAlarm (A3) high schalten bis die Zeit abgelaufen ist.

Mein Problem ist nun, die ablaufende Zeit am Seriellen Monitor und am 4 Digit anzuzeigen!

Wenn der Alarmeingang low ist und eine Einstellung an der Vorgabe gemacht wird, soll diese am Display angezeigt werden. Nach ca. 5sec. soll dann aber das Display auf die Alarmzeit umschalten und bei AlarmIn low den Wert 0 anzeigen. Wenn nun der AlarmIn high wird, soll die eingestellte Zeit angezeigt werden und ablaufen bis der Wert 0 erreicht ist.
(im Seriellen Monitor soll dann auch die Alarmzeit (Ablauf) angezeigt werden!)

Hierzu der bis jetzt geschriebene Code:

/*
Arduino Nano V3
AlarmTasterTimer für LED Steuerung 
per Tastendruck einen vordefinierten Zeit-Wert(Schrittweite)erhöhen oder senken.
mit Display 4-Digit
*/

// Include für das Display:
#include <TM1637Display.h> 

// PINs des Displays:
const int CLK = 6;                //Set the CLK pin connection to the display
const int DIO = 7;                //Set the DIO pin connection to the display

// Display initialisieren:
TM1637Display display(CLK, DIO);  //set up the 4-Digit Display.
// Noch Display-Zustände definieren:
uint8_t all_on[] = { 0xff, 0xff, 0xff, 0xff };
uint8_t all_off[] = { 0x00, 0x00, 0x00, 0x00 };


// Konstante Variablen
const byte alarmIn = A0;   
const byte tasterUpPin = A1; // Pin für Taster 1
const byte tasterDownPin = A2; // Pin für Taster 2
const byte outputAlarm = A3; // Pin für Alarmausgang

// Variablen
int schrittweite = 10; // Variable für die Schrittweite pro Tasterdruck des Zeit Wertes
int alarmTime = 300;     // Variable für die Timerfunktion
int tasterUpStatus = 0; // Variable zum speichern des Tasterstatus
int tasterDownStatus = 0; // Variable zum speichern des Tasterstatus

void setup() {

// Setup des Displays:
display.setBrightness(0xb2);    // set the diplay to (ca.70% 0xb2) (maximum 0xff) brightness
// Testweise fünfmal alle Segmente kurz anzeigen:
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);

Serial.begin(9600); // Setzt die Baudrate für die Ausgabe am Serial Monitor auf 9600
Serial.print("Grundeinstellung-Zeit :"); Serial.println(alarmTime); Serial.print(" \t\n");

//Serial.print("outputAlarm");

pinMode(alarmIn, INPUT_PULLUP); // Setzt den Pin des alarmIn als Eingang mit Pullup-Widerstand
pinMode(tasterUpPin, INPUT_PULLUP); // Setzt den Pin des tastersUp als Eingang mit Pullup-Widerstand
pinMode(tasterDownPin, INPUT_PULLUP); // Setzt den Pin des tastersDown als Eingang mit Pullup-Widerstand
pinMode(outputAlarm, OUTPUT); // Setzt den Pin des Led-Relais als Ausgang

}

void loop () {
  timeSet();
  alarmTimerLed();
}

void alarmTimerLed(){
  static uint32_t previousMillis = 0;  
  if (digitalRead(alarmIn) == LOW) 
  {
    digitalWrite(outputAlarm, HIGH);
    previousMillis = millis();         
  }
    if (millis() - previousMillis > alarmTime * 1000UL && digitalRead(outputAlarm) == HIGH)  
  {
    digitalWrite(outputAlarm, LOW);
  }
Serial.print("aktuell Zeit :"); Serial.println(alarmTime); Serial.print(" \t\n");
//Serial.print("Alarm Zeit :"); Serial.println(alarmIn); Serial.print(" \t\n");
}


void timeSet() {
  tasterUpStatus = digitalRead(tasterUpPin); // TasterPinUp lesen und Status speichern
  tasterDownStatus = digitalRead(tasterDownPin); // TasterPinDown lesen und Status speichern

  // Wenn Taster Up gedrückt wird, dass der Wert um die "Schrittweite" erhöht wird
  if(tasterUpStatus == HIGH) {
  alarmTime = alarmTime + schrittweite;
  delay(100);
}

  // Wenn Taster Down gedrückt wird, dass der Wert um die "Schrittweite" gesenken wird
  if(tasterDownStatus == HIGH) {
  alarmTime = alarmTime - schrittweite;
  delay(100);

  // Die ausgegebene alarmTime wird auf den Bereich zwischen 10 bis 600 Sekunden begrenzt
  if(alarmTime >= 610) {
  alarmTime = 600;
  }

  if(alarmTime <= 0) {
  alarmTime = 10;
  }
}

// alarmTime auf Display ausgeben:
display.showNumberDec(alarmTime, false);  // Darstellung in Sekunden

    
//digitalWrite(outputAlarm, alarmTime); // Gibt den alarmTime Wert am LedPin aus

// Gibt den alarmTime Wert im seriellen Monitor aus
//Serial.print(alarmTime); Serial.print(alarmIn);
//Serial.println(outputAlarm);
}

wäre super wenn mir hier jemand helfen kann!

Danke euch schon mal.
Gruß Max

Du hast doch schon ein if / else . Wenn du je nach Fall unterschiedliche Anzeigen willst, bau sie doch dort ein ?
Eventuelle zusätzliche Schwierigkeiten mit dem Display klärst du besser erst , wenn das Einfache gelöst ist (Zwei kleine Probleme sind weniger als ein großes)

Hallo,
also ganz hab ich dein Problem nicht verstanden. Du hast doch die Stelle an der Dein Timer abgelaufen ist und der OutputAlarm auf LOW geschaltete wir.
Da willst Du jetzt etwas auf dem Display anzeigen und etwas auf dem Monitor ausgeben ?

Wenn Du mit eine einfache Lösung haben willst dann mach das einfach mit einem delay().
Sowas in der Art

if (millis() - previousMillis > alarmTime * 1000UL{
   digitalWrite(outputAlarm, LOW);
   Serial.println("Zeit abgelaufen");
   // 0 auf dem display anzeigen
   display.schow....
   delay(5000);
}

Hallo, und danke erst mal für euere Antwort, aber ich glaube es ist noch nicht ganz klar, was ich machen möchte...

  1. die Zeit welche nach AlarmIn ablaufen soll (AlarmTime), wird sowohl am Display als auch am SM angezeigt. Das funktioniert soweit; auch die Einstellung erhöhen oder senken.

  2. wenn dann eine AlarmIn high ansteht, schaltet der OutputAlarm auf high und bleibt, bis die AlarmTime abgelaufen ist.

  3. nun wollte ich genau diesen Wert (Ablaufende Zeit) auf dem Display ablaufen lassen, solange der OutputAlarm noch high ist oder zwischenzeitlich etwas an der AlarmTime neu eingestellt wird.
    Parallel sollte die Ablaufende Zeit auch am SM angezeigt werden.

Bis jetzt zeigt das Display und der SM nur den eingestellten VorgabeWert an...

Gruß Max

Hallo,
eventuell lässt Du Deine Anzeige einfach rückwärts laufen. Wenn Du startest wird die Anzeige von 0 auf den Zeitwert gesetzt und läuft dann einfach rückwärts ab bis sie wieder auf 0 ankommt. Du musst dann halt nur dann wenn Du den Zeitwert einstellen willst die Anzeige umschalten. Eventuell zus. Schalter "Eingabemodus". Auch Sinnvoll eine Anzeige mit zwei Zeilen "Sollwert" / "Aktualwert".
Heinz

millis() - previousMillis >= alarmTime * 1000UL

Die abgelaufende Zeit ist (millis() - previousMillis)/1000, während die verbleibende Zeit alarmTime - ((millis() - previousMillis) / 1000) ist. (Ist das sprachlich richtig?). Ein Testprogramm zur Veranschaulichung nur mit SM:

// Konstante Variablen
const byte alarmIn = A0;
const byte tasterUpPin = A1; // Pin für Taster 1
const byte tasterDownPin = A2; // Pin für Taster 2
const byte outputAlarm = A3; // Pin für Alarmausgang

// Variablen
int schrittweite = 10; // Variable für die Schrittweite pro Tasterdruck des Zeit Wertes
int alarmTime = 300, anzeige = 0;     // Variable für die Timerfunktion
int tasterUpStatus = 0; // Variable zum speichern des Tasterstatus
int tasterDownStatus = 0; // Variable zum speichern des Tasterstatus

void setup() {
  Serial.begin(9600); // Setzt die Baudrate für die Ausgabe am Serial Monitor auf 9600
  Serial.print("Grundeinstellung-Zeit :"); Serial.println(alarmTime); Serial.print(" \t\n");

  pinMode(alarmIn, INPUT_PULLUP); // Setzt den Pin des alarmIn als Eingang mit Pullup-Widerstand
  pinMode(tasterUpPin, INPUT_PULLUP); // Setzt den Pin des tastersUp als Eingang mit Pullup-Widerstand
  pinMode(tasterDownPin, INPUT_PULLUP); // Setzt den Pin des tastersDown als Eingang mit Pullup-Widerstand
  pinMode(outputAlarm, OUTPUT); // Setzt den Pin des Led-Relais als Ausgang

}

void loop () {
  timeSet();
  alarmTimerLed();
}

void alarmTimerLed() {
  static uint32_t previousMillis = 0;
  if (digitalRead(alarmIn) == LOW)
  {
    digitalWrite(outputAlarm, HIGH);
    previousMillis = millis();
  }
  if (millis() - previousMillis >= alarmTime * 1000UL && digitalRead(outputAlarm) == HIGH)
  {
    digitalWrite(outputAlarm, LOW);
  }
  if (digitalRead(outputAlarm) && (alarmTime - ((millis() - previousMillis) / 1000) != anzeige)) {
    anzeige = alarmTime - ((millis() - previousMillis) / 1000);
    Serial.print("(millis() - previousMillis) / 1000: "); Serial.print((millis() - previousMillis) / 1000);
    Serial.print("\tanzeige: "); Serial.println(anzeige);
  }
}


void timeSet() {
  tasterUpStatus = !digitalRead(tasterUpPin); // TasterPinUp lesen und Status speichern
  tasterDownStatus = !digitalRead(tasterDownPin); // TasterPinDown lesen und Status speichern

  // Wenn Taster Up gedrückt wird, dass der Wert um die "Schrittweite" erhöht wird
  if (tasterUpStatus == HIGH) {
    alarmTime = alarmTime + schrittweite;
    delay(100);
  }

  // Wenn Taster Down gedrückt wird, dass der Wert um die "Schrittweite" gesenken wird
  if (tasterDownStatus == HIGH) {
    alarmTime = alarmTime - schrittweite;
    delay(100);

    // Die ausgegebene alarmTime wird auf den Bereich zwischen 10 bis 600 Sekunden begrenzt
    if (alarmTime >= 610) {
      alarmTime = 600;
    }

    if (alarmTime <= 0) {
      alarmTime = 10;
    }
  }
}

Tut das in erster Näherung, was Du möchtest?

Moin agmue,
danke für die Unterstützung... werde das mir nachher mal anschauen und testen.
Melde mich dann.

Wünsche euch eine guten Start in den Tag :coffee: :coffee: :coffee: :sleeping: :sleeping: :sleeping:

Hallo agmue,

habe nun deine Code mal getestet und ihn noch ein bisschen verändert.

die Anzeige am SM ist nun schon mal so, wie ich mir das vorgestellt hatte.
(zählt brav den eingestellten Wert nach einem Start herunter bis 0)

Wie kann ich nun das noch auf mein Display bringen.
Hier wird bis jetzt nur der eingestellte Wert angezeigt und bleibt auf diesem stehen.

// alarmTime auf Display ausgeben:
display.showNumberDec(alarmTime, false);  // Darstellung in Sekunden

Hier würde ich gerne beim Einstellen und wenn kein Alarm ansteht der Einstellwert (alarmTime) anzeigen. Wenn dann aber eine Start (alarmIn) erfolgt, soll das Display auf den ablaufenden Wert (Anzeige) umschalten bis dieser 0 ist und nach 5 bzw. 3 sek. dann wieder den Einstellwert (AlarmTime) anzeigen.

ist sowas möglich?

Gruß Max

Hallo,
dazu benötigst Du z.B eine zweite Zeitverzögerung die Du startest wenn der AlarmOutput auf LOW geschaltete wird. Für die Ausgabe auf dem Display nutzt Du dann eine If..Abfrage.

Heinz

ungesteste

void alarmTimerLed() {
  static uint32_t previousMillis = 0;
  static uint32_t startdisp=0; // neue Zeile 
  if (digitalRead(alarmIn) == LOW)
  {
    digitalWrite(outputAlarm, HIGH);
    previousMillis = millis();
  }
  if (millis() - previousMillis >= alarmTime * 1000UL && digitalRead(outputAlarm) == HIGH)
  {
    digitalWrite(outputAlarm, LOW);
    
  }
  if (digitalRead(outputAlarm) && (alarmTime - ((millis() - previousMillis) / 1000) != anzeige)) {
    anzeige = alarmTime - ((millis() - previousMillis) / 1000);
    //Serial.print("(millis() - previousMillis) / 1000: "); Serial.print((millis() - previousMillis) / 1000);
    Serial.print("\tanzeige: "); Serial.println(anzeige);
  }
// ab hier neu
 if (digitalRead(outputAlarm) == HIGH) startdisp = millis(); // Zeit festhalten

  if (millis()-startdisp >=3000){
  display.showNumberDec(alarmTime, false);  // Darstellung in Sekunden
  }
  else{
display.showNumberDec(anzeige, false);  // Darstellung in Sekunden
  }
}

Das kann man so machen, aber ich finde ja, es ist Zeit für eine kleine Schrittkette :slightly_smiling_face:

Eine Schrittkette mit switch/case hilft zumindest mir, so einen Ablauf übersichtlicher zu gestalten (getestet mit Nano):

// Konstante Variablen
const byte alarmIn = A0;
const byte tasterUpPin = A1; // Pin für Taster 1
const byte tasterDownPin = A2; // Pin für Taster 2
const byte outputAlarm = A3; // Pin für Alarmausgang
const uint16_t ANZEIGEZEIT = 3000;

// Variablen
int schrittweite = 10; // Variable für die Schrittweite pro Tasterdruck des Zeit Wertes
int alarmTime = 10;     // Variable für die Timerfunktion
int tasterUpStatus = 0; // Variable zum speichern des Tasterstatus
int tasterDownStatus = 0; // Variable zum speichern des Tasterstatus

void setup() {
  Serial.begin(9600); // Setzt die Baudrate für die Ausgabe am Serial Monitor auf 9600
  Serial.print("Grundeinstellung-Zeit: "); Serial.println(alarmTime); Serial.print(" \t\n");

  pinMode(alarmIn, INPUT_PULLUP); // Setzt den Pin des alarmIn als Eingang mit Pullup-Widerstand
  pinMode(tasterUpPin, INPUT_PULLUP); // Setzt den Pin des tastersUp als Eingang mit Pullup-Widerstand
  pinMode(tasterDownPin, INPUT_PULLUP); // Setzt den Pin des tastersDown als Eingang mit Pullup-Widerstand
  pinMode(outputAlarm, OUTPUT); // Setzt den Pin des Led-Relais als Ausgang
}

void loop () {
  timeSet();
  alarmTimerLed();
}

void timeSet() {
  tasterUpStatus = !digitalRead(tasterUpPin); // TasterPinUp lesen und Status speichern
  tasterDownStatus = !digitalRead(tasterDownPin); // TasterPinDown lesen und Status speichern

  // Wenn Taster Up gedrückt wird, dass der Wert um die "Schrittweite" erhöht wird
  if (tasterUpStatus == HIGH) {
    alarmTime = alarmTime + schrittweite;
    delay(100);
  }

  // Wenn Taster Down gedrückt wird, dass der Wert um die "Schrittweite" gesenken wird
  if (tasterDownStatus == HIGH) {
    alarmTime = alarmTime - schrittweite;
    delay(100);

    // Die ausgegebene alarmTime wird auf den Bereich zwischen 10 bis 600 Sekunden begrenzt
    if (alarmTime >= 610) {
      alarmTime = 600;
    }

    if (alarmTime <= 0) {
      alarmTime = 10;
    }
  }
}

void alarmTimerLed() {
  uint32_t jetzt = millis();
  static uint32_t vorhin = 0;
  static uint16_t restzeit = 0;
  enum struct Schritte {WARTEN, ZAEHLEN, ANZEIGE};  // Benennung und Numerierung der Schritte der Schrittkette
  static Schritte schritt = Schritte::WARTEN;

  switch (schritt) {
    case Schritte::WARTEN:
      if (!digitalRead(alarmIn)) {
        digitalWrite(outputAlarm, HIGH);
        vorhin = jetzt;
        restzeit = alarmTime;
        Serial.print("\tRestzeit: "); Serial.println(restzeit);
        schritt = Schritte::ZAEHLEN;
      }
      break;
    case Schritte::ZAEHLEN:
      if (jetzt - vorhin >= 1000) {
        vorhin += 1000;
        restzeit--;
        Serial.print("\tRestzeit: "); Serial.println(restzeit);
        if (restzeit == 0) {
          vorhin = jetzt;
          digitalWrite(outputAlarm, LOW);
          schritt = Schritte::ANZEIGE;
        }
      }
      break;
    case Schritte::ANZEIGE:
      if (jetzt - vorhin >= ANZEIGEZEIT) {
        Serial.print("\nGrundeinstellung-Zeit: "); Serial.println(alarmTime); 
        schritt = Schritte::WARTEN;
      }
      break;
  }
}

Mein Fokus liegt auf alarmTimerLed().

Hallo zusammen,
nun habe ich auch noch ein bisschen probiert und habe auch eine Lösung für die Displayausgabe gefunden.

Nach dem Start wir das DP auf 300 gestellt und wartet auf einen alarmIn.
wenn ich dann Einstellungen Up/Down mache, wir der Wert von 300 in 10er-Schritten erhöht oder gesenkt.
Sobald nun ein alarmIn ansteht, schaltet das DP auf anzeige und die eingestellte Zeit zählt rückwärts bis 0 und der outputAlarm (Relais) schaltet wieder aus... genau so wollte ich es haben.

Hier der angepasste Codeabschnitt:

void alarmTimerLed() {
  static uint32_t previousMillis = 0;
  if (digitalRead(alarmIn) == LOW)
  {
    digitalWrite(outputAlarm, HIGH);
    previousMillis = millis();
  }
  
  if (millis() - previousMillis >= alarmTime * 1000UL && digitalRead(outputAlarm) == HIGH)
  {
    digitalWrite(outputAlarm, LOW);
  }
  
  if (digitalRead(outputAlarm) && (alarmTime - ((millis() - previousMillis) / 1000) != anzeige)) 
  {
    anzeige = alarmTime - ((millis() - previousMillis) / 1000);
    Serial.print("(millis() - previousMillis) / 1000: "); Serial.print((millis() - previousMillis) / 1000);
    Serial.print("\tanzeige: "); Serial.println(anzeige);
  }

 
  if (digitalRead(outputAlarm) == LOW) {
  display.showNumberDec(alarmTime, false);  // Darstellung der eingestellten alarmTime in Sekunden
  }
  
  if (digitalRead(outputAlarm) == HIGH) {
  display.showNumberDec(anzeige, false);  // Darstellung der anzeige (ablaufZeit) nach alarmIn, in Sekunden
  }
}

Herzlichen Dank erst mal hier an dieser Stelle an euch; :+1: :ok_hand:
der Code hat mir die Augen :roll_eyes: geöffnet und den Erfolg gebracht.

Leider gefällt mir die Ausgabe am SM noch nicht so ganz:
Im void Setup gebe ich am SM eigentlich nur Anfangstext aus:

void setup() {
  
// Setup des Displays:
display.setBrightness(0xb2);    // set the diplay to (ca.70% 0xb2) (maximum 0xff) brightness
// Testweise 3mal alle Segmente kurz anzeigen:
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);

 
Serial.begin(9600); // Setzt die Baudrate für die Ausgabe am Serial Monitor auf 9600
Serial.print("Grundeinstellung-Zeit/in Sek.: "); Serial.println(alarmTime);
Serial.print("Schrittweite einstellbar in 10Sek. zwischen 10 und 600"); Serial.print(" \t\n"); Serial.print(" \t\n");

  pinMode(alarmIn, INPUT_PULLUP); // Setzt den Pin des alarmIn als Eingang mit Pullup-Widerstand
  pinMode(tasterUpPin, INPUT_PULLUP); // Setzt den Pin des tastersUp als Eingang mit Pullup-Widerstand
  pinMode(tasterDownPin, INPUT_PULLUP); // Setzt den Pin des tastersDown als Eingang mit Pullup-Widerstand
  pinMode(outputAlarm, OUTPUT); // Setzt den Pin des Led-Relais als Ausgang

}

void loop () {
  timeSet();
  alarmTimerLed();
}

Nun habe ich verschiedene Dinge versucht.
Was bis jetzt funktioniert sind die zwei If-Anwesungen in der Funktion timeSet.
Allerdings läuft dann im SM der Eintrag "Aktuell eingestellte Zeit: " mit alarmTime und wird nur durch einen alarmIn mit der ablaufenden "anzeige" unterbrochen...

SM

void timeSet() {
  tasterUpStatus = digitalRead(tasterUpPin); // TasterPinUp lesen und Status speichern
  tasterDownStatus = digitalRead(tasterDownPin); // TasterPinDown lesen und Status speichern

  // Wenn Taster Up gedrückt wird, dass der Wert um die "Schrittweite" erhöht wird
  if(tasterUpStatus == HIGH) {
  alarmTime = alarmTime + schrittweite;
  delay(100);
  }
  
  // Wenn Taster Down gedrückt wird, dass der Wert um die "Schrittweite" gesenken wird
  if(tasterDownStatus == HIGH) {
  alarmTime = alarmTime - schrittweite;
  delay(100);
  }
  
  // Die ausgegebene alarmTime wird auf den Bereich zwischen 10 bis 600 Sekunden begrenzt
  if(alarmTime > 600) {
  alarmTime = 600;
  }

  if(alarmTime < 10) {
  alarmTime = 10;
  }
  
  if(tasterUpStatus == HIGH) {
  Serial.print("Aktuell eingestellte Zeit: "); Serial.println(alarmTime);
  }

  if(tasterDownStatus == HIGH) { 
  Serial.print("Aktuell eingestellte Zeit: "); Serial.println(alarmTime);
  }
}

mir persönlich würde es nun einfach besser gefallen, wenn im SM nur einmal die "Aktuell eingestellte Zeit" aufführen würde und nur bei Änderung eine Anpassung erfolgt. Bei einem AlarmIn kann dann der SM abwärts zählen bis 0 erreicht ist.

Habt ihr vielleicht hierzu noch einen Tipp oder eine Idee?

Hier nochmal de komplette Code, wie e jetzt gerade besteht:

/*
  Arduino Nano V3
  AlarmTasterTimer für LED Steuerung
  per Tastendruck einen vordefinierten Zeit-Wert(Schrittweite)erhöhen oder senken.
  mit Display 4-Digit
*/

// Include für das Display:
#include <TM1637Display.h>

// PINs des Displays:
const int CLK = 6;                //Set the CLK pin connection to the display
const int DIO = 7;                //Set the DIO pin connection to the display

// Display initialisieren:
TM1637Display display(CLK, DIO);  //set up the 4-Digit Display.
// Noch Display-Zustände definieren:
uint8_t all_on[] = { 0xff, 0xff, 0xff, 0xff };
uint8_t all_off[] = { 0x00, 0x00, 0x00, 0x00 };

// Konstante Variablen
const byte alarmIn = A0;
const byte tasterUpPin = A1; // Pin für Taster 1
const byte tasterDownPin = A2; // Pin für Taster 2
const byte outputAlarm = A3; // Pin für Alarmausgang

// Variablen
int schrittweite = 10; // Variable für die Schrittweite pro Tasterdruck des Zeit Wertes
int alarmTime = 300, anzeige = 0;     // Variable für die Timerfunktion
int tasterUpStatus = 0; // Variable zum speichern des Tasterstatus
int tasterDownStatus = 0; // Variable zum speichern des Tasterstatus

void setup() {
  
// Setup des Displays:
display.setBrightness(0xb2);    // set the diplay to (ca.70% 0xb2) (maximum 0xff) brightness
// Testweise 3mal alle Segmente kurz anzeigen:
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);
display.setSegments(all_on);
delay(100);
display.setSegments(all_off);
delay(100);

 
Serial.begin(9600); // Setzt die Baudrate für die Ausgabe am Serial Monitor auf 9600
Serial.print("Grundeinstellung-Zeit/in Sek.: "); Serial.println(alarmTime);
Serial.print("Schrittweite einstellbar in 10Sek. zwischen 10 und 600"); Serial.print(" \t\n"); Serial.print(" \t\n");

  pinMode(alarmIn, INPUT_PULLUP); // Setzt den Pin des alarmIn als Eingang mit Pullup-Widerstand
  pinMode(tasterUpPin, INPUT_PULLUP); // Setzt den Pin des tastersUp als Eingang mit Pullup-Widerstand
  pinMode(tasterDownPin, INPUT_PULLUP); // Setzt den Pin des tastersDown als Eingang mit Pullup-Widerstand
  pinMode(outputAlarm, OUTPUT); // Setzt den Pin des Led-Relais als Ausgang

}

void loop () {
  timeSet();
  alarmTimerLed();
}

void alarmTimerLed() {
  static uint32_t previousMillis = 0;
  if (digitalRead(alarmIn) == LOW)
  {
    digitalWrite(outputAlarm, HIGH);
    previousMillis = millis();
  }
  
  if (millis() - previousMillis >= alarmTime * 1000UL && digitalRead(outputAlarm) == HIGH)
  {
    digitalWrite(outputAlarm, LOW);
  }
  
  if (digitalRead(outputAlarm) && (alarmTime - ((millis() - previousMillis) / 1000) != anzeige)) 
  {
    anzeige = alarmTime - ((millis() - previousMillis) / 1000);
    Serial.print("(millis() - previousMillis) / 1000: "); Serial.print((millis() - previousMillis) / 1000);
    Serial.print("\tanzeige: "); Serial.println(anzeige);
  }

 
  if (digitalRead(outputAlarm) == LOW) {
  display.showNumberDec(alarmTime, false);  // Darstellung der eingestellten alarmTime in Sekunden
  }
  
  if (digitalRead(outputAlarm) == HIGH) {
  display.showNumberDec(anzeige, false);  // Darstellung der anzeige (ablaufZeit) nach alarmIn, in Sekunden
  }
}


void timeSet() {
  tasterUpStatus = digitalRead(tasterUpPin); // TasterPinUp lesen und Status speichern
  tasterDownStatus = digitalRead(tasterDownPin); // TasterPinDown lesen und Status speichern

  // Wenn Taster Up gedrückt wird, dass der Wert um die "Schrittweite" erhöht wird
  if(tasterUpStatus == HIGH) {
  alarmTime = alarmTime + schrittweite;
  delay(100);
  }
  
  // Wenn Taster Down gedrückt wird, dass der Wert um die "Schrittweite" gesenken wird
  if(tasterDownStatus == HIGH) {
  alarmTime = alarmTime - schrittweite;
  delay(100);
  }
  
  // Die ausgegebene alarmTime wird auf den Bereich zwischen 10 bis 600 Sekunden begrenzt
  if(alarmTime > 600) {
  alarmTime = 600;
  }

  if(alarmTime < 10) {
  alarmTime = 10;
  }
  
  if(tasterUpStatus == HIGH) {
  Serial.print("Aktuell eingestellte Zeit: "); Serial.println(alarmTime);
  }

  if(tasterDownStatus == HIGH) { 
  Serial.print("Aktuell eingestellte Zeit: "); Serial.println(alarmTime);
  }
}


Bei meinem Programm ist das so:

Grundeinstellung-Zeit: 10

Restzeit: 10
Restzeit: 9
Restzeit: 8
Restzeit: 7
Restzeit: 6
Restzeit: 5
Restzeit: 4
Restzeit: 3
Restzeit: 2
Restzeit: 1
Restzeit: 0

Grundeinstellung-Zeit: 10

Könnte hier der Unterschied liegen?

  tasterUpStatus = !digitalRead(tasterUpPin); // TasterPinUp lesen und Status speichern
  tasterDownStatus = !digitalRead(tasterDownPin); // TasterPinDown lesen und Status speichern

das sind nur die !-Zeichen vor dem digitalRead...

...werde ich später mal noch testen... jetzt knurrt gerade der Magen! :wink:

melde mich wenn ich es getestet habe!

Na da ist aber noch ne Menge Potenzial.
Ich hab mal geraten:
So sieht meine Deklaration aus:


// PINs des Displays:
const uint8_t CLK = 6;                //Set the CLK pin connection to the display
const uint8_t DIO = 7;                //Set the DIO pin connection to the display

// Display initialisieren:
TM1637Display display(CLK, DIO);  //set up the 4-Digit Display.
// Noch Display-Zustände definieren:
uint8_t all_on[] = { 0xff, 0xff, 0xff, 0xff };
uint8_t all_off[] = { 0x00, 0x00, 0x00, 0x00 };

// Konstante Variablen
const uint8_t alarmIn = A0;
const uint8_t tasterUpPin = A1; // Pin für Taster 1
const uint8_t tasterDownPin = A2; // Pin für Taster 2
const uint8_t outputAlarm = A3; // Pin für Alarmausgang

// Variablen
uint8_t schrittweite = 10; // Variable für die Schrittweite pro Tasterdruck des Zeit Wertes
uint16_t alarmTime = 300, anzeige = 0;     // Variable für die Timerfunktion
bool tasterUpStatus = 0; // Variable zum speichern des Tasterstatus
bool tasterDownStatus = 0; // Variable zum speichern des Tasterstatus

Du hast mindestens ein Problem, da der Code nicht fehlerfrei kompiliert:

81:85: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (digitalRead(outputAlarm) && (alarmTime - ((millis() - previousMillis) / 1000) != anzeige)) 

Dann ist Dein Gesamtkonstrukt irgendwie nicht nachvollziehbar. Es sieht sehr nach zusammenkopiert und auf gut Glück umgearbeitet aus.

Versuch mal einen Teilersatz mit dem hier:

void timeSet()
{
  const uint32_t bouncetime = 100;
  static uint32_t lastmillis = 0;
  bool tasterUpStatus = false;
  bool tasterDownStatus = false;
  if (millis() - lastmillis > bouncetime)
  {
    // Wenn Taster Up gedrückt wird, dass der Wert um die "Schrittweite" erhöht wird
    if (!digitalRead(tasterUpPin)) // TasterPinUp lesen und Status speichern
    {
      alarmTime = alarmTime + schrittweite;
      lastmillis = millis();
      tasterUpStatus = true;
    }
    // Wenn Taster Down gedrückt wird, dass der Wert um die "Schrittweite" gesenken wird
    else if (!digitalRead(tasterDownPin)) // TasterPinDown lesen und Status speichern
    {
      alarmTime = alarmTime - schrittweite;
      lastmillis = millis();
      tasterDownStatus = true;
    }
  }
  // Die ausgegebene alarmTime wird auf den Bereich zwischen 10 bis 600 Sekunden begrenzt
  if (alarmTime > 600)
  {
    alarmTime = 10;
  }
  else if (alarmTime < 10)
  {
    alarmTime = 600;
  }
// einmalige Ausgabe
  if (tasterUpStatus || tasterDownStatus)
  {
    Serial.print("Aktuell eingestellte Zeit: "); Serial.println(alarmTime);
    tasterUpStatus = false;
    tasterDownStatus = false;
  }
}

ungetestet.

Ja, die invertieren, weil Du ja INPUT_PULLUP verwendest, also gegen GND schaltest.

In C++ gibt es verschiedene Ausdrucksarten für ein und dieselbe Sache:

if (digitalRead(outputAlarm) == LOW) {
...
if (!digitalRead(outputAlarm)) {

Weil ich faul bin, bevorzuge ich die kurze Variante.

Hallo,

danke für die Unterstützung; und klar gibt es immer Potenzial nach oben...je nachdem wieviel Zeit man in ein Projekt steckt und wie lange man schon sich mit solchen Themen befasst.

Für meinen Teil bin ich noch ganz am Anfang und es ist mein 2tes oder 3tes Projekt das ich versuche zum Laufen zu bekommen.

Auch hier liegst du nicht ganz daneben, klar ist hier einiges zusammen kopiert...
dennoch versuche ich dann auch den Code zu verstehen und ggf. auf meine Bedürfnisse anzupassen... ich denke das macht auch Sinn, da man so relativ schnell versteht und lernt wie und wann man gewisse Dinge anwendet bzw. wie man anstehende Aufgaben löst.
Leider gibt es noch viele und große Wissenslücken um nun alles gleich perfekt zu lösen, aber das ist auch nicht unbedingt der Anspruch... erst möchte ich, dass das Projekt funktioniert und ich versehe, was ich wo mache (programmiere).

Ich werde die Funktion "timeSet" wie von dir vorgeschlagen, mal ersetzen, testen und versuchen zu verstehen; ggf. werde ich dann mit Fragen mich wieder melden.

Auf jeden Fall danke ich für die Unterstützung...

OK, ich habe nun deine Version der "timeSet" eingebaut; funktioniert natürlich tadellos! :+1:

"musste auch feststellen, dass ich die Up/Down Richtung vertauscht hatte, also bei Up in Richtung Down gezählt wurde und umgedreht... :face_with_hand_over_mouth:

Allerding habe ich nun noch die Situation, dass wenn ich mit der Down Taste bei dem Wert von 10 angekommen bin, der Zähler überspringt und wieder bei 600 anfängt; umgedreht natürlich auch.

Eigentlich sollte 10 die untere Begrenzung sein und 600 die Obere, also (10 Sekunden und 10 Minuten).

Hast du hier noch eine Tipp, wo ich dies beeinflussen kann?
Dachte eigentlich, dass dies an dieser Stelle geregelt wird???

...habe die Lösung gefunden... meinen alten Code und deinen verglichen... und nun angepasst!

...so funktioniert es wie ich mir das vorgestellt hatte! :smiley:

Ich danke dir ganz herzlich für die Unterstützung... werde nun versuchen die geänderte "timeSet" zu zerpflücken und zu verstehen... :face_with_monocle: :nerd_face:

Das war beabsichtigt :slight_smile:

Na geht doch mit Dir.

Gut gemacht.

Das kommt - irgendwann sogar von ganz allein.
Aber mit den ersten Versuchen habe ich mich auch lange schwer getan ... :wink:

Ich habe in meinem Gehirn gespeichert, es sollte >= sein, damit die korrekte Zeit abläuft. Ist das wegen alarmTime += schrittweite; anders?