Forum: Mikrocontroller und Digitale Elektronik Countdown timer


von Dominik W. (dominik_wa)



Lesenswert?

Hi,
ich würde noch einmal kurz eurer Hilfe und Erfahrung brauchen.
Mein Programm läuft soweit super, nur in den Minusbereich zählt er mir 
nicht richtig bzw. ich kann hier keine Grenze von -60 sec einstellen.
Er zählt mir also immer bis zu der -9 hoch und dann erhöht er mir erst 
die Minuten. Wenn ich es so wie in dem Positiven Bereich versuche zu 
programmieren wird das ignoriert. Was mache ich den Falsch??


Ich wäre euch dankbar über diverse Hilfestellung!
vg dome

PS. das wäre mein Programmausschnitt um den es sich in meinem Programm 
dreht!


void stepDown()                                       //Timer-Logik
{if(countFlag && !negativFlag)
  {if (Sec > 0)
   {Sec -= 1;
   //delay(1000);
   }
  else
    if(Min>0)
       {Sec = 59;
        Min -= 1;
        //delay(1000);
        } // evtl zu """ =-"""""  umdrehen
     }
     if(countFlag&& negativFlag)
     {    if(Sec<=0)
            {Sec--;

            }else
       if(Min<=0)
        { Min--;
       Sec=00;
        }
     }

}   // ende StepDown

von Gcc (Gast)


Lesenswert?

Die Logik in diesem Abschnitt ist zu hoch für mich. Was soll denn da 
passieren? So wie's da steht, passiert gar nix mit min und sec, wenn die 
grösser als 0 sind, wenn kleiner als 0, dann zählt sec einfach bis zum 
anschlag runter. Btw: deine einrückungen sind katastrophal.
1
   if(countFlag&& negativFlag)
2
   {    
3
      if(Sec<=0)
4
      {
5
         Sec--;
6
      } else
7
         if(Min<=0)
8
         { 
9
           Min--;
10
           Sec=00;
11
         }
12
   }

von Dominik W. (dominik_wa)


Lesenswert?

@ Gcc :

Das war nur ein Versuch, um zu sehen wie es mir angezeigt wird.
Bzw. habe wieder von vorne angefangen da mir es nicht richtig in
den negativen Bereich ging. (und ja es soll auch nur runter zählen in 
den Abschnitt, im positiven Bereich gibt es keine Probleme mehr).

Aber so ging es leider auch nicht.
Wenn ich unter "0" bin, dass es mir ab 60sec die Minuten um eins 
Hochzählt bis z.B. "-9".In welche Richtung denke ich verkehrt?


if(countFlag&& negativFlag)
     {delay(100);
      if(Sec<=0)
       {if(Sec<60*-1)
         {Sec--;}
         else if(Sec==59)
           { Min--;
             Sec=0;}
        }
     }

von Gcc (Gast)


Lesenswert?

Was soll denn da passieren? Jetzt werden Sec nur dann runtergezählt, 
wenn < -59, der else-zweig  mit wenn Sec == +59 wird nie erreicht, weil 
Man da nur hingelangt, wenn Sec <= 0.
Ziemlich sinnfrei wenn du mich fragst. Dir ist schon bewusst, dass bei 
neg. zahlen z.b. -60 grösser ist als -61, oder? Und das irgendwas mal 
-1 eine neg. zahl ergibt?

Und deine formatierung ist immer noch katastrophal...

von Gcc (Gast)


Lesenswert?

Und erklär doch mal in klartext, was "stepDown" in Abhängigkeit von 
negativFlag und countFlag eigentlich machen soll. Mir ist das ein 
rätsel.

von dominik (Gast)


Lesenswert?

<Dir ist schon bewusst, dass bei neg. zahlen z.b. -60 grösser ist als 
-61>

richtig das ist mir schon bewusst, habe es leider auch zu spät gesehen.

<Und deine Formatierung ist immer noch katastrophal...>

das mag sein, bin ja noch am Programm Anfang sowie in der 
"Einarbeitung-phase".Aber dann sag doch nicht nur was schlecht ist 
sondern , sei so gut und gib mal bitte ein konstruktives Beispiel wie es 
nach deiner Meinung besser ausschauen würde!

Stepdown stellt nur eine eigene Funktion zum runter Zählen der 
eingegebenen Zahl dar!(in pos.und neg.Bereich)
Dafür nutze ich die zwei boolean Variablen countflag ist auch für den 
Start und runterzählen im pos.Bereich ....da, negativFlag ist die 
variable zum runter zählen ins negat. damit auch die Pause um die 
"NULLSTELLEN" sicher gewährleistet sind und es mir somit komplett auf 
Null runter zählt und dann weiter.
Sonst hatte ich immer das Problem das es mir gleich wieder hochgezählt 
hat oder sonstiges gezählt wurde was es nicht sollte!

Aber wie gesagt über konstruktive Vorschläge oder Verbesserungen bin ich 
immmer offen, da ich dann natürlich was aus der "Praxis" dazu lernen 
darf!

Aber ansonsten sehe ich schon,dass ich wohl in dem Bereich nochmal bei 
null anfangen darf.

vg Dome

ps. sorry für die verspätete Mail, aber der Lehrnstress hat mich wieder.

von Bastian W. (jackfrost)


Lesenswert?

Hi,

nimm doch einfach eine int16_t Variable für den Counter und rechne nur 
in Sekunden. Und dann wandelst du den Counter mit
1
int8_t Min = Counter / 60;
2
int8_t Sec = Counter % 60;

um. Wenn du mehr als 127 Minuten hast musst du da auch nen 16 Bit signed 
Int nehmen.

Damit wird deine Stepdown Logic einfacher.

Gruß JackFrost

von Gcc (Gast)


Lesenswert?

dominik schrieb:
> Aber dann sag doch nicht nur was schlecht ist
> sondern , sei so gut und gib mal bitte ein konstruktives Beispiel wie es
> nach deiner Meinung besser ausschauen würde!

Nur mal so als Ideensammlung
1. Sinnvolle Kommentare
   - Was macht das gesamte Programm aus Nutzersicht?
   - Was machte eine Funktion/Nebeneffekte
   - Was steht in eine Variablen/Wertebereich/Fehlerbedingungen
   - "Beginn XXX" / "Ende XXX" sind ziemlich sinnfrei.
2. Einrückung immer gleich Verschachtelungsebene
3. Verständlicher, lesbarer Code
   Dieser Punkt ist natürlich extrem individuell und von pers.
   Vorlieben geprägt. Muss man nicht so machen, und wenn, dann
   auch nicht dumpf anwenden. Ist halt Geschmackssache
   a. möglichst wenig globale Variablen
   b. möglichst geringe Komplexität/Verschachtelungstiefe, bei mehr
      als 3 Ebenen neue Funktion spendieren
   c. keine Funktion länger als eine Bildschirmseite
   d. Code so aufbauen, wie man "denken" würde
   e. Ausdrücke so einfach wie möglich, Invarianten ausklammern
   f. Entscheidende Codestellen sofort kommentieren!
4. Robuster Code
   Das nimmt die meiste Zeit in Anspruch
   a. UserInput kann und wird denkbar bescheuert sein
   b. alle Sonderfälle abfangen & behandeln
   c. Laufzeitfehler erkennen und behandeln
   d. Ununterbrechbarkeit / "gefühlte Nebenläufigkeit" durch ISRs

von Gcc (Gast)


Lesenswert?

Die Funktionsweise von StepDown habe ich leider immer noch nicht 
verstanden. Klar ist, die zählt eine Zeit runter. Was ab 00:00 passieren 
soll, ist mir immer noch schleierhaft. ich vermute mal, es soll einfach 
mit neg. Vorzeichen weitergezählt werden, also so:

..., 00:01, 00:00, -00:01, -00:02, ..., -00:59, -01:00, -01:01

Dh man zählt Min und Sec im negativen Bereich einfach wieder hoch.
Neg. Vorzeichen wird in der Flagvariablen "negativFlag" angezeigt.
Dann könnte stepDown so aussehen
1
// Timer-Logik: Zählt eine Zeit in den globalen Variablen Min und Sec um eine sekunde runter
2
// diese Zeit kann positiv oder negativ sein. 
3
// Das Vorzeichen wird in der globalen Var. "negativFlag" gehalten 
4
void stepDown(void)
5
{
6
  // Nicht zählen, wenn Zähler noch nicht über countFlag freigegeben
7
  if(!countFlag ) return;
8
9
  // Wenn aktuelle Zeit 00:00 ist, "negativFlag" setzen und im negativen Bereich weiterzählen
10
  if ( Min==0 && Sec==0 ) negativFlag = true;
11
12
  if (negativFlag) {
13
     // Im negativen Bereich zählen: Sec und Min einfach hochzählen
14
     // Zählart: -00:01, -00:02, ..., -00:59, -01:00, -01:01, ...
15
     ++Sec;
16
     if ( Sec > 59 ) {
17
        Sec = 0;
18
        Min++;
19
     }
20
  } else {
21
     // Im positiven Bereich zählen: Sec und Min einfach runterzählen
22
     // Zählart: 01:01, 01:00, 00:59, ..., 00:01, 00:00
23
    if ( Sec > 0 ) {
24
       Sec--; 
25
    } else {
26
       // Min=0 wird oben abgefangen, dh Min hier immer > 0
27
       Min--;
28
       Sec=59;
29
    }
30
  }
31
32
}   // ende StepDown

von Peter D. (peda)


Lesenswert?

Bastian W. schrieb:
> nimm doch einfach eine int16_t Variable für den Counter und rechne nur
> in Sekunden.

Sehe ich auch so. Diese ganze Unterteilerei, da sieht doch keiner mehr 
durch.
Und dann sind negative Zeiten auch kein Problem mehr. Einfach ein '-' 
anzeigen und dahinter den Betrag der Zeit:
1
  char sign = ' ';
2
  if( time < 0 ){
3
    sign = '-';
4
    time = 0 - time;
5
  }
6
  printf( "%c%02u:%02u\n", sign, time/60, time%60 );

von Gcc (Gast)


Lesenswert?

Dazu müsste er jedoch sein restliches Programm ebenfalls überarbeiten. 
So weit ich das ganze verstanden habe, lässt der TO da einen Countdown 
mit Presetmöglichkeit für Min und Sek auf ner 7Seg-Anzeige/Startampel 
laufen.

von DominikW. (Gast)


Angehängte Dateien:

Lesenswert?

super danke an euch alle für die gute Unterstützung.
Damit lässt sich doch mein Programm schon optimieren.

@Gcc: Danke auch für die Ideensammlung und ja ich soll darf 4*7 
Segmentanzeigen verwenden (siehe Link vom Conrad), die ich über einen 
NPN Transistoren ansteuern werde. Das gesamte Packet wird auf einer 
passenden  Platine zusammengelötet bzw. erstellt.

Die mehr Volt liefert mir ein Powerbank Akku der bis zu 12V/19V Output 
hat.

https://www.conrad.de/de/7-segment-anzeige-rot-57-mm-82-v-4-v-ziffernanzahl-1-kingbright-sc23-12ewa-160067.html?sc.ref=Product%20Details


Die Anzeige sieht also 4stellig aus.
0.0.0.0.
und zählt z.B. vom max Wert 90 min runter 8.9.5.9./ 8.9.5.8.,.......

und im neg. Bereich -.2.-.2., -.2.-.3.,-.2.-.4........

Ich dachte in neg. Bereich zu gehen ist leichter und besser ersichtlich 
für den Referenten der auf diese "Uhr" schaut, als wenn ich von 0.0.0.0.
wieder anfangen würde hoch zu zählen.

Ich werde es moregn gleich mal ausprobieren.

vielen dank nochmal für eure Hilfe.

Allerdings hätte ich noch eine Frage da das Programm nach erreichen der 
Endzeit sich wahrscheinlich nicht von alleine zurücksetzen wird, so dass 
man gleich aufs neue eine Zeit anstellen kann, hättet ihr mir da noch 
eine kleine Hilfe wie ich einen Resetbutton noch programmieren könnte??

vg dome

von W.S. (Gast)


Lesenswert?

Dominik W. schrieb:
> Mein Programm läuft soweit super, nur in den Minusbereich zählt er mir
> nicht richtig

DominikW. schrieb:
> Die Anzeige sieht also 4stellig aus.
> 0.0.0.0.
> und zählt z.B. vom max Wert 90 min runter 8.9.5.9./ 8.9.5.8.,.......

Du schreibst extrem wirr, so daß es einem schwerfällt, den eigentlichen 
Sinn hinter deinen ganzen Programmierversuchen zu erkennen.

Also, soll das ne Art Eieruhr werden, die die verstrichene Zeit in 
Minuten und Sekunden herunterzählt?

Falls ja, dann brauchst du irgend einen System-Timer (sprich Interrupt), 
der dir pro Sekunde ein Ereignis beliebiger Art liefert. Was für ein 
Ereignis, ist erstmal egal, Hauptsache daß du es im Grundprogramm 
erkennst, dann aus der Zeitvorgabe und der aktuellen Systemzeit die 
Differenz bildest und diese als Dezimalausgabe auf deinem Display 
darstellst. Und wenn die Zeit um ist, soll das Ganze dann wohl nen 
Pieeeeep abgeben und dann auf 00.00 verharren, bis es das nächste Mal 
gestartet wird.

Ist das so?

Also schreib mal etwas konkreter, was du eigentlich vorhast.

W.S.

von dominik (Gast)


Lesenswert?

hi W.S.

Ok ich versuch mich jetzt mal zu bessern:)
Also man kann das so als "Eieruhr /Countdown Timer" bezeichnen!
Es wird in Präsentationen/ Vorträgen für den Vortragenden benötigt.

Genaue Zeit Darstellung wird dann mit vier einzelnen ca. 58mm großen
7- Segmentanzeigen dargestellt. Das Zeit Format wird in
Min (die ersten 2Segmente) und in
Sec (die letzten zwei Segmente) dargestellt.

Die eingestellte Zeit soll hinunter zählen.
 > alles über 2 Minuten wird mit einer Grünen LED dargestellt.
 >zwischen 2 Min und 0 Min sowie 0 Sec ist es Gelb.
 >(Dank der Hilfe von Gcc bin ich von meinen " in den neg. Bereich 
zählen "
  weg gekommen und zähle jetzt einfach wieder hoch.)
  Bei erreichen von 0 Min && 0 Sec  wird das wieder hochzählen mit rotem
  Signal dargestellt.
 >Eine entsprechende Pause wird mit einer Blauen LED realisiert.


>>>>>>>>>??
Die letzte Frage war eben, ob es eine vernünftigen Weg in dem Programm 
gibt, meine laufenden Countdown zu stoppen und alle Anzeigen auf "NULL" 
zu setzen und diese wieder gleich neu Programmieren/einstellen könnte? 
(z.B. wenn der Vortragende festgestellt hat,dass er hat eine falsche 
Präsentationszeit eingestellt hat und die Zeit läuft schon, dass er 
diesen Fehler einfach wieder mit einer neuen Zeiteingabe beheben könnte! 
)

Ich habe mich schon an dem Interrupt ("1") versucht nur leider,
mag er mir den noch gar nicht so, sodass er mir einmal alles auf Null 
setzt (was zwar richtig ist) nur danach wird nicht erkannt ob ich im 
Hochzähl-Modus war oder im Hinunterzähl-Modus.

Das heißt er zählt von z.B. 02:00 runter 1:59, 1:58,....
Interrupt-Taster wird gedrückt Anzeige ist 00:00 + Rote LED leuchtet nur 
wenn ich jetzt danach 05:00 (5 Min) einstelle zählt es mir nicht runter 
sondern eben hoch!
 SOLL zustand 05:00, 04:59, 04:58,..
 IST zustand  05:00, 05:01, 05:02,.. 05:03,....
>>>>>>>>??

Neben zu habe ich in der alten Nachricht nur mal die dafür (meiner 
Ansicht nach) noch Entscheiden Materialien angehängt. Eben die 7 Segment 
variante und ein NPN Transistor( von den 8 st. wo ich für die Eingänge 
brauche) damit ich auch die 8,8 V schalten kann.( bis jetzt sind bei 
meinem Model nur die kleinen Simulations-Segmente in betrieb)

Oder würdet ihr mir eher zu einen Comp. Treiber raten bzw. muss die 
gemeinsame Kathode auch ein Transistor PNP bekommen?

Hoffe jetzt wurde es klarer welche Aufgabe bzw. an welchen Versuch ich 
arbeite!
Danke nochmal für die vielen Informationen

Vg Dome

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.