Zeiteinstellung bei einer Uhr

Liebe Arduinoisten,

sehr viel habe ich bisher aus dem Forum gelernt. Es ist außerordentlich hilfreich und erweitert den Horizont.

Jetzt bin ich an einem Punkt angelangt, wo ich einen Tipp brauche.

Bei meiner BCD-Uhr schaffe ich es nicht, die Zeit einstellen zu können, damit sie “richtig” weiterläuft.

Ich zähle die Netzpulse und stelle diese mit 13 10-mm-LED’n dar.

Zwei weitere 5 mm-LED’n blinken im Sekundentakt und zeigen an, dass die Uhr “läuft”.

Mit drei Tastern stelle ich die Zeit ein ( Stunden-+, Minuten-Minus, Minuten-+), und da liegt mein Problem.

Wenn ich z.B. auf Stunden-+ drücke, zeigt meine Uhr die geänderte Zeit an, aber wenn ich die Taste wieder

loslasse, geht sie auf die unveränderte Zeit zurück.

Ich bitte um einen Tipp, wie ich dieses Problem in den Griff bekomme.

In meinem Programm habe ich die Anzeige der Zeit weggelassen, nur die Ansteuerung der Sekunden-LED’n ist

aufgeführt. Zur Zeit ist bei mir die IDE 1.8.8 im Einsatz.

Viele Grüße
bolsak.

Forum-Uhr.ino (3.86 KB)

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Deine Variablen second, minute, hour werden jedesmal aus Tic neu berechnet. da nutzt es nichts, sie temporär zu verändern. Besser du änderst jeweils die zentrale Variable

   uint32_t Tic; //20 msec-Pulse seit Mitternacht

um die entsprechende Anzahl.

(deleted)

Liebe Arduinoisten,

nach einigen Recherchen hoffe ich, jetzt den Quelltext in richtigem Format liefern zu können?

Viele Grüße
bolsak.

/* Forum-Uhr.ino
    nach topic=350791: <ArduinoClock>
  Gewinnung der Zeit aus den Netz-Pulsen
  Anzeige mit einem MAX7219 + 15 LED'n
  Darstellen der Zeit mit 13 LED'n im BCD-Format
  2 Sekunden-LED zeigen an, dass die Uhr "läuft".

*/

byte SekLEDo;           // Sekunden-LED oben
byte SekLEDu;           // dito unten

const byte LinePin   = 14;     // vom Optokoppler
const byte SwitchPin = 15;     // Taster zum Einstellen
const byte Bell      =  9;     // für einen Gong/Lautsprecher

#include <LedControl.h>
#include <binary.h>
LedControl lc = LedControl(11,12,10,1);

bool Now, Last;
uint32_t Tic;                              // Netzpulse
uint32_t AllSeconds;
static uint16_t second, minute, hour;

 uint16_t SetTime;                        // Zeiteinstellung
 bool PinState,LastPinState;
uint32_t PinDebounceTime;

void GetPulse() {
  Now = digitalRead(LinePin);
  if (Now == 1 && Last == 0)
  {
    Tic ++;
  }
             Last = Now;
}

void setup() {
  Serial.begin(115200);
  Serial.println(" ============================================= ");
  Serial.println(" ======== Forum-Uhr.ino ====================== ");
  Serial.println(" ============================ 3.5.20 ========= ");
  pinMode(LinePin, INPUT);
  pinMode(SwitchPin, INPUT);
  pinMode(Bell, OUTPUT);

  lc.shutdown(0,false);            // Anzeige ein!
  lc.setIntensity(0,12);
  lc.clearDisplay(0);
  lc.setScanLimit(0,1);           // für 2 Reihen der Matrix

//Tic=2800;         //Start 50 sec
//Tic=8700;         //  00:02:54         Stunde=50*60*60=180000
//Tic=199000;       // 01:06:20
//Tic=4319000;      // 23:59:40 h

}

void loop() {
  GetPulse();

  //uint32_t AllSeconds  = 10*Tic;                // Schnelllauf
  uint32_t AllSeconds    = Tic / 50;              // Normalgang
  uint16_t Seconds       = AllSeconds % 3600;
  second   = Seconds % 60;
  minute   = Seconds / 60;
  hour     = AllSeconds / 3600;
  if (hour >= 24)  {
    Tic = 0;
    lc.clearDisplay(0);
  }

  SetTime = analogRead(SwitchPin);   // für 3 Taster
  bool Status = false;
  uint32_t PinDebounceTime = 50;
  bool PinState = false;                      // Entprellen
  bool LastPinState = false;

  // analoge Taster-Werte:
  // hour+ = 600-610,    min- = 835-844,    min+ = 930-936

  //  ================================== Zeit einstellen ======================

  if (SetTime > 100 ) {                           // Taste gedrückt???
                         PinState = true; Status=true;
    if (PinState != LastPinState )  {             // ???
      if (millis() - PinDebounceTime)
      {
        if (SetTime > 605 && SetTime < 612 )                            
        {
          hour = hour+1;                 // Stunden+
        }                                                        

        if ((SetTime > 835) && (SetTime < 845) && (minute != 0))
        {
          minute--;                                          // Minuten-
        }

        if ((SetTime > 930) && (SetTime < 940))
        {
          minute++ ;                                         // Minuten+
        }
        LastPinState = PinState;
        PinDebounceTime = millis();
        PinState=false;  Status=false;
      }
    }      
}     //                          Ende Einstellen

  // ===================================== Sekunden-Blinken mit 0,5 Hz 

  if (second % 2 == 0) {
    lc.setLed(0, 1, 5, true); lc.setLed(0, 1, 6, false);    // LED oben
  }
  else
  {
    lc.setLed(0, 1, 5, false);   lc.setLed(0, 1, 6, true);  // LED unten
  }
  // ==================================================================
  
  Serial.print("  Forum-Uhr:    ");
  if (hour < 10) {   Serial.print("0");  }  Serial.print(hour);
  Serial.print(":");
  if (minute < 10) {  Serial.print("0");   } Serial.print(minute);
  Serial.print(":");
  if (second < 10) {  Serial.print("0");    }  Serial.print(second);
  Serial.print("     SetTime = ");  Serial.print(SetTime);
//Serial.print("    minute ");  Serial.print(minute);
//Serial.print(" second  ");  Serial.print(Status);//second);//Tic);
  Serial.println();

} // Taste gedrückt???

bolsak:
nach einigen Recherchen hoffe ich, jetzt den Quelltext in richtigem Format liefern zu können?

Supi.
Ok Du hast den Hinweis von Peter-CAD-HST noch nicht eingearbeitet

Ab Zeile 91 fängst Du an hour und minute zu verändern.
Das bleibt solange gültig, bis loop() wieder von vorne beginnt.
In Zeile 68/69 weist Du hour und minute wieder die Werte aus AllSeconds zu.

Du musst also nicht nur hour / minute ändern, sondern auch dementsprechend zu Tic aufaddieren bzw. subtrahieren.

In Zeile 110 kommentierst Du Ende Einstellung.
Ich würde zwischen Zeile 109 und 110 eine neue Zeile einbauen und an der Stelle tic aus den Werten hour, minute, second neu berechnen.

Liebe Arduinoisten,

ich bitte Euch noch einmal um Hilfe.

Zuerst möchte ich mich bei <michael_x> und <my_x_y_project> für die Antworten bedanken.

Mein jetziges Programm gewinnt die Zeit nach einer anderen Methode, den umständlichen Algorhthmus habe ich
verworfen. Mein derzeit gültiges Programm ist <Forum-Uhr-1.ino>.

Beim alten Programm war es so:
Wenn ich nach den Vorschlägen die Addition, z.B.einer Stunde, in umrechne und die zu den bisherigen
dazu zähle, dann “flutschen” so lange Stunden in die Berechnung, wie ich den Taster
drücke. Dito ist es bei den Minuten.
Lange Rede kurzer Sinn, ich kann keine einzelne Stunde oder Minute addieren oder subtrahieren.

Deshalb habe ich es mit einer anderen Zeitauswertung versucht. Jetzt zähle ich die Sekunden und leite daraus
die Minuten und Stunden ab. Aber:
ich habe den gleichen Effekt! Auch hier die Stunden oder Minuten solange in die Anzeige, wie ich den
Taster drücke.

Meine Frage an Euch ist: wie schaffe ich es, EINE Minute oder Stunde bei EINEM Tastendruck einstellen zu können?

Ich habe noch eine weitere Frage:

In meinem Programm mache ich in Zeile 112 die Erhöhung der Stunde um Eins mit dem üblichen Ausdruck

<hour++;> In dieser Form bemängelt der Compiler die Schreibweise:

< operation on ‘hour’ may be undefined [-Wsequence-point] > und die Erhöhung der Stunde klappt nicht.Aber die

Minuten bearbeite ich mit der gleichen Routine, und dort geht es (und es gibt keine Fehlermeldung).

Wenn ich dagegen schreibe <hour=hour+1;> , dann akzeptiert der Compiler diese Anweisung und es funktioniert.

Welches <C+±Geheimnis> steckt hinter dieser Merkwürdigkeit?

Ich habe Arduino 1.8.8 im Einsatz.

Ich wünsche Euch allen einen entspannten Feiertag.

Herzliche Grüße
bolsak.

/* Forum-Uhr-1.ino
    nach topic=350791: <ArduinoClock>
  Gewinnung der Zeit aus den Netz-Pulsen
  Anzeige mit einem MAX7219 + 15 LED'n
  Darstellen der Zeit mit 13 LED'n im BCD-Format
  2 Sekunden-LED zeigen an, dass die Uhr "läuft".

*/

byte SekLEDo;           // Sekunden-LED oben
byte SekLEDu;           // dito unten

const byte LinePin   = 14;     // vom Optokoppler
const byte SwitchPin = 15;     // Taster zum Einstellen
const byte Bell      =  9;     // für einen Gong/Lautsprecher

#include <LedControl.h>
#include <binary.h>
LedControl lc = LedControl(11, 12, 10, 1);

static uint8_t second, minute, hour;               // CatchPulse
uint32_t FlankUp = 0; uint32_t FlankDown = 0;
uint32_t PreviousFlankUp;
uint32_t Tic;
bool up = false;

uint16_t SetTime;                        // Zeiteinstellung
bool PinState, LastPinState;
uint32_t PinDebounceTime;


void setup() {
  Serial.begin(115200);
  Serial.println(" ============================================= ");
  Serial.println(" ======== Forum-Uhr-1.ino ==================== ");
  Serial.println(" =========================== 20.5.20 ========= ");
  pinMode(LinePin, INPUT);
  pinMode(SwitchPin, INPUT);
  pinMode(Bell, OUTPUT);

  lc.shutdown(0, false);           // Anzeige ein!
  lc.setIntensity(0, 12);
  lc.clearDisplay(0);
  lc.setScanLimit(0, 1);          // für 2 Reihen der Matrix

}


//==========================================================

void CatchPulse() {       // nach topic = 285146
  uint16_t Pulse = digitalRead(LinePin);
  if (Pulse)
  { if (!up)
    {
      up = true;
    }
  }
  else {
    if (up)  {
      up = true;
      if (up == true) {
        Tic ++;
      }


      if (Tic % 50 == 0)   {
        second++;
      }
      if (second > 59)     {
        minute++;
        second = 0;
      }
      if (minute > 59)     {
        hour++;
        minute = 0;
      }
      if (hour > 24)       {
        hour = 0;
        Tic = 0;
      }

      PreviousFlankUp = FlankUp;
      up = false;
    }
  }

} //                                       Ende CatchPulse

void loop() {

  CatchPulse();
  lc.clearDisplay(0);

  SetTime = analogRead(SwitchPin);            // für 3 Taster
  uint32_t PinDebounceTime = 50;
  bool PinState = false;                      // Entprellen
  bool LastPinState = false;

  // analoge Taster-Werte:
  // hour+ = 600-610,    min- = 835-844,    min+ = 930-936

  //  ================================== Zeit einstellen ======================

  if (SetTime > 100 ) {                           // Taste gedrückt???
    PinState = true;
    if (PinState != LastPinState )  {
      if (millis() - PinDebounceTime)
      {
        if (SetTime > 605 && SetTime < 612 )
        {
          hour = hour+1;                                // Stunden+
        }

        if ((SetTime > 835) && (SetTime < 845) && (minute != 0))
        {
          minute--;                                          // Minuten-
        }

        if ((SetTime > 930) && (SetTime < 940))
        {
          minute++ ;                                         // Minuten+
        }
        LastPinState = PinState;
        PinDebounceTime = millis();
        PinState = false; // Status=false;
      }
    }
  }     //                          Ende Einstellen

  // ===================================== Sekunden-Blinken mit 0,5 Hz

  if (second % 2 == 0) {
    lc.setLed(0, 1, 5, true); lc.setLed(0, 1, 6, false);    // LED oben
  }
  else
  {
    lc.setLed(0, 1, 5, false);   lc.setLed(0, 1, 6, true);  // LED unten
  }
  // ==================================================================

  Serial.print("  Forum-Uhr:    ");

  if (hour < 10) {
    Serial.print('0');
  }
  Serial.print(hour); Serial.print(":");
  if (minute < 10) {
    Serial.print('0');
  }
  Serial.print(minute); Serial.print(":");
  if (second < 10) {
    Serial.print('0');
  }
  Serial.print(second);
  Serial.print("  ST = "); Serial.print(SetTime);
  Serial.print("          Durchlauf "); Serial.print(Tic);
  Serial.println();
}

Auch hier die Stunden oder Minuten solange in die Anzeige, wie ich den
Taster drücke.

Meine Frage an Euch ist: wie schaffe ich es, EINE Minute oder Stunde bei EINEM Tastendruck einstellen zu können?

Klar. Du willst nicht zählen, wenn der Taster gedrückt ist, sondern wenn der Zustand wechselt. Z.B. von gedrückt nach losgelassen. Und das ohne Prellen.
Dazu brauchst du den Zustand im vorigen Zyklus.

So wie du es schon mit Tic machst.

Und wenn der Taster länger gedrückt ist, kannst Du ja nach 3 Sekunden langsam fortlaufend zählen, weitere 5 Sekunden später das Tempo erhöhen - sind auch nur verschiedene Status seit dem Zeitpunkt, wo der Knopf gedrückt wurde.

bolsak:
Beim alten Programm war es so:
Wenn ich nach den Vorschlägen die Addition, z.B.einer Stunde, in umrechne und die zu den bisherigen
dazu zähle, dann “flutschen” so lange Stunden in die Berechnung, wie ich den Taster
drücke. Dito ist es bei den Minuten.
Lange Rede kurzer Sinn, ich kann keine einzelne Stunde oder Minute addieren oder subtrahieren.

Das war so gedacht, das Du tic komplett neu berechnest, wenn Du die Taste drückst.

Ich glaube auch, das Dein debounce nicht das macht, was Du willst.
Aktuell kein Board zur Verfügung, daher mal zusammenkopiert und umgebaut nur die Routine für die Tasten - versuch mal, ob das geht.

int SetTime;
byte SwitchPin = 15;
static uint8_t second, minute, hour;
uint32_t lastmillis = 0;
uint32_t PinDebounceTime = 50;
bool PinState = false;

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

void loop()
  {
  SetTime = analogRead(SwitchPin);            // für 3 Taster
  // analoge Taster-Werte:
  // hour+ = 600-610,    min- = 835-844,    min+ = 930-936
  //  ================================== Zeit einstellen ======================
  if (SetTime > 100 && !PinState)                              // Taste gedrückt???
    {
    PinState = true;
    Serial.print("Taste gedrückt: ");
    Serial.println(SetTime);
    if (millis() - lastmillis > PinDebounceTime)
      {
      Serial.println("Taster wird ausgewertet: ");
      if (SetTime > 605 && SetTime < 612)
        {
        hour = hour + 1;                            // Stunden+
        }
      if ((SetTime > 835) && (SetTime < 845) && (minute != 0))
        {
        minute--;                                          // Minuten-
        }
      if ((SetTime > 930) && (SetTime < 940))
        {
        minute++ ;                                         // Minuten+
        }
      lastmillis = millis();
      Serial.print("Werte neu: ");
      Serial.print(hour);
      Serial.print("\t");
      Serial.println(minute);
      }
    }
  else
    {
    PinState = false; // Status=false;}
    }
  //                          Ende Einstellen
  // ===================================== Sekunden-Blinken mit 0,5 Hz
  }

@my_xy_projects:

Vielen Dank für Deine Hilfe. Ich habe das Programm ausprobiert.

Auch mit Deinem Code erhöhen sich die Stunden und Minuten kontinuierlich, und das MUSS auch so sein,

denn jedesmal, wenn loop() durchlaufen wird und die Bedingung 605 && SetTime <612> zutrifft,

dann wird die Variable erhöht.

Merke: Der Rechner macht das, was ich ihm sage, nicht, was er soll, denn er kann nicht denken!

Ich habe eine Idee und den Lötkolben schon bereit gelegt.

Wie kann ich den im Forum eingeblendeten Programmtext per Tastatur in meine IDE kopieren?

Einen Hinweis, wie das zu machen ist, habe ich bislang nicht im Forum entdecken können.

Ich wünsche Dir ein schönes Wochenende.

Viele Grüße bolsak.

Hi

Oberhalb auf das 'Select' klicken - markiert den ganzen Inhalt.
STRG+C (copy)
In der Arduino-IDE ein neues Projekt erstellen, dort Alles markieren (STRG+A) und das eben kopierte einfügen (STRG+V).

MfG

PS: Alternativ rechte Maustaste 'Kopieren'/'Einfügen'

bolsak:
@my_xy_projects:

Vielen Dank für Deine Hilfe. Ich habe das Programm ausprobiert.
Auch mit Deinem Code erhöhen sich die Stunden und Minuten kontinuierlich, und das MUSS auch so sein,

Ich hab mal über meinen Code gesehen,

Änder die Zeile:

  PinState = false; // Status=false;}

in

  if (SetTime<100) PinState = false;

Damit ist die Bedingung für das Rücksetzen des Merkers erst erfüllt, wenn keine Taste gedrückt.
Hab erst abend wieder Umgebung. Dann kann ich ggfls. direkt nochmal draufsehen.

[edit]
Der Code würde das tun, was Du willst. Auf’m Nano getestet. Allerdings ist der Code nicht schön.

Wenn aufgeräumt stehen bei mir 2006/209 Bytes mit den seriellen Ausgaben und Berichtigung im Stunden- und Minutenteil. Es geht auch noch kleiner.

Liebe Arduionisten,

ich melde mich noch einmal in meiner Angelegenheit, die Zeit bei meiner BCD-Uhr einstellen zu können.

Bislang hatte ich keinen Erfolg, weil ich noch immer nicht mein Problem im Griff habe, den per Taster
geänderten Wert permanent in das Programm eintragen zu können.

Mein folgendes kleines Programm zeigt Euch, was ich meine:

wenn ich mit einem Tastendruck erhöhe oder vermindere, dann nimmt wieder den
Ursprunglwert an, wenn ich die Tasten loslasse.

Wer hat einen Tipp für mich?

Vielen Dank im Voraus. bolsak

/*TASTER.ino     soll einen dauerhaften Wert liefern, der mit
   einem Taster vermehrt/vermindert wird. Denn wenn ich den
   Taster loslasse, geht der Wert zurück. Wie mache ich ihn
   permanent?
*/

const byte buttonPin2 = 2;    // the pin that the pushbutton is attached to
const byte buttonPin3 = 3;    // the pin that the pushbutton is attached to

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);

  Serial.println(" ==========================================");
  Serial.println(" ============ TASTER.ino ==================");
  Serial.println(" ============================== 19.6.20 ===");
}

void loop() {
  byte Value = 44;

  bool  Plus = !digitalRead(buttonPin2);
  bool Minus = !digitalRead(buttonPin3);

  if (  Plus == true) {
    Value++;
  }
  if  (Minus == true) {
    Value--;
  }


  Serial.print(" bP2 : ");      Serial.print(Plus);
  Serial.print(" bP3 : ");      Serial.print(Minus);
  Serial.print("    Value = "); Serial.println(Value);


}

Wie oft wird loop aufgerufen?
Und jedesmal wird value = 44; gesetzt.

Zudem: Wenn Du die 44 ins Setup geschoben hast, wird bei jedem Durchlauf hochgezählt UND jeder Bounce mitgezählt.

Liebe Arduinoisten,

vielen Dank an <michael_x> und <my_xy_project>.

Ich habe mein Problem “noch nicht rüber gebracht”, mit anderen Worten Euch nicht klar machen können.

Den Wert will ich an mein Programm übergeben, um damit die Zeit einzustellen. Dies geschieht in vier Schritten:

Stunden-Zehner, Stunden-Einer, Minuten-Zehner und Minuten-Einer.

Meine Schwierigkeit ist die, dass ich keinen Weg weiß, wie ich den eingestellten Wert, z.B. 43, an das Programm übergeben

kann, wenn ich die Taste wieder loslasse.

Wie gebe ich den reduzierten Wert (43) an das Programm, damit ich die Einstellung der Uhrzeit fortsetzen kann?

Für einen Tipp wäre ich Euch sehr dankbar.

Herzliche Grüße bolsak.

Hi

Wenn man die Variable STATIC macht, wird Diese mit einmalig 44 erstellt und bleibt erhalten.
Somit kann man dann per Knöpschedrügge den Wert hoch und runter bringen.
Ob Das aber den gewünschten Effekt zeigt - loop() dürfte den Tastendruck einige zig Mal die Sekunde erkennen - und entsprechend schnell zählen.

MfG

PS: WER übergibt die Zahl WIE?
Wohin soll die neu eingestellte Zahl 'übergeben' werden?
So Alles in Allem ist Dein Konzept noch nicht sonderlich schlüssig.

static behält den Wert über das Ende der Funktion hinaus. Dann braucht es noch eine Verzögerung nach Art des Nachtwächters, kennst Du vom Mitlesen.

Versuche es mal so:

/*TASTER.ino     soll einen dauerhaften Wert liefern, der mit
   einem Taster vermehrt/vermindert wird. Denn wenn ich den
   Taster loslasse, geht der Wert zurück. Wie mache ich ihn
   permanent?
*/

const byte buttonPin2 = 2;    // the pin that the pushbutton is attached to
const byte buttonPin3 = 3;    // the pin that the pushbutton is attached to

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);

  Serial.println(" ==========================================");
  Serial.println(" ============ TASTER.ino ==================");
  Serial.println(" ============================== 19.6.20 ===");
}

void loop() {
  uint32_t jetzt = millis();
  static uint32_t vorhin = jetzt;
  const uint32_t intervall = 200;
  static byte Value = 44;

  if (jetzt - vorhin >= intervall) {
    vorhin = jetzt;
    bool  Plus = !digitalRead(buttonPin2);
    bool Minus = !digitalRead(buttonPin3);

    if (  Plus == true) {
      Value++;
    }
    if  (Minus == true) {
      Value--;
    }

    Serial.print(" bP2 : ");      Serial.print(Plus);
    Serial.print(" bP3 : ");      Serial.print(Minus);
    Serial.print("    Value = "); Serial.println(Value);
  }
}

agmue:
Versuche es mal so:

Geht nur einmal.
+