Forum: Mikrocontroller und Digitale Elektronik Stoppuhr TASTER


von Timothy K. (time226)


Angehängte Dateien:

Lesenswert?

Hallo miteinander ich hätte da eine frage,

wie kann ich bei meinem bestehenden Arduino Programm für eine Stoppuhr 
zwei Taster verwenden. Einen zum Reseten des Programms, also das die 
Zeit bei null wieder beginnt. Den anderen zum Starten bzw. zum Stoppen 
der Stoppuhr.

Danke schon mal im Vorraus

von Einer K. (Gast)


Lesenswert?

Timothy K. schrieb:
> Den anderen zum Starten bzw. zum Stoppen der Stoppuhr.
Ein Taster mit 2 Funktionalitäten....

Das ist ein klassischer einfacher endlicher Automat.
Ein ganz einfacher, mit 2 Zuständen.
Darum wird hier ein Zustandsmerker von Nöten sein.
Und sicherlich auch der ein oder andere Zeitmerker.


Timothy K. schrieb:
> Einen zum Reseten des Programms, also das die
> Zeit bei null wieder beginnt.
Geschenkt....
Dazu reichts, den Automaten in den Start Zustand zu versetzen.

von Timothy K. (time226)


Lesenswert?

Und wie schreibe ich das in mein programm?

von Frank L. (hermastersvoice)


Lesenswert?

ich finde dafür die Tastatur immer ganz praktisch...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Eines vorneweg: es ist eine sehr unsaubere Sache, millis() in einer 
Programmschleife mehrmals auslesen, weil der millis() Zeitgeber ja 
parallel weiterläuft. Lies millis() am Beginn der Schleife 1x in ein 
lokale millis_akt Variable ein und arbeite mit dieser, damit du während 
des gesamten Schleifendurchlaufs die gleiche Zeit verwendest!

Und dann musst du noch eine Variable millis_start anlegen, die den 
Startwert der Zeitmessung speichert.

Und dann musst du noch eine Variable millis_ende anlegen, die den 
Stopwert der Zeitmessung speichert.

Und eine Zustandsvariable messung_aktiv, die speichert, ob du gerade in 
einer Messung bist oder die Stoppuhr steht.

Und dann brauchst du noch eine Flankenerkennung und eine Entprellung für 
den Start-Stop-Taster...

Schleifenbeginn:

Du liest millis_akt auf millis() ein;

Du zeigst im Display immer den Wert millis_ende-millis_start an.

Wenn die Zeitmessung mit dem Start-Stop Taster gestartet wird (steigende 
Flanke), dann bekommen millis_ende und millis_start den Wert von 
millis_akt zugewiesen und du merkst dir den Zustand messung_aktiv = 1.

Wenn messung_aktiv == 1 ist und nochmal der Start-Stop Taster gedrückt 
wird (steigende Flanke), dann wird messung_aktiv = 0 gesetzt.

Wenn messung aktiv == 1 ist, dann wird millis_ende laufend in jedem 
Schleifendurchlauf der Wert von millis_akt zugewiesen.

Und wenn der Reset Knopf gedrückt wird, dann wird messung_aktiv = 0 
gesetzt und millis_start = millis_ende gesetzt, damit die Anzeige 0:0:0 
ist.

Schleifenende, von vorn.

BTW: als echtes Programm ist das natürlich wesentlich kürzer als so in 
Prosa... ;-)

: Bearbeitet durch Moderator
von Timothy K. (time226)


Lesenswert?

Kannst du mir das vllt mal zeigen wie du es meinst?

von Karl M. (Gast)


Lesenswert?

Hallo,

Timothy K. schrieb:
> Kannst du mir das vllt mal zeigen wie du es meinst?

Die "Aufgabe" von Lothar Miller ist folgende, formuliere ein "pseudoe" 
Programm anhand der textlichen Beschreibung von Lothar Miller.
Anhand dieser Darstellung lässt sich durch (fast) jede 
Programmiersprache ein reales Programm formulieren.
Ich schreibe extra 'formulieren', da es hier um eine Transformation der 
textlichen Darstellung zur Beschreibung durch eine Programmsprache geht.

von Stefan F. (Gast)


Lesenswert?

Ich würde empfehlen, einen Aufsatz zum Thema "Endliche Automaten" oder 
"Zustandsautomaten" (ist das Selbe) und einen zum Thema "Entprellen" zu 
lesen. Das sollte deine Fragen klären.

Falls du diese Artikel nicht verstehst, nimm separate Taster für Start 
und Stop - das ist viel einfacher umzusetzen.

Wir werden Dir hier kein fertiges Programm präsentieren, denn daraus 
würdest du nichts lernen. Dieses Programm zu erklären würde letztendlich 
auf eine Wiederholung der oben genannten Aufsätze führen, also ebenfalls 
sinnlose Zeitverschwendung sein.

von Timothy K. (time226)


Lesenswert?

Wie kann ich durch einen Tasterdruck mein Programm anhalten? Zum 
Beispiel bei einer stoppuhr auf dem LCD display

von Frank L. (hermastersvoice)


Lesenswert?

schliess die Taste an den Reseteingang des Controllers an. Damit wird 
jedes Programm zuverlässig angehalten

von Philipp G. (geiserp01)


Lesenswert?

alt + F4


Frank L. schrieb:
> schliess die Taste an den Reseteingang des Controllers an. Damit wird
> jedes Programm zuverlässig angehalten

Doof dass die Stoppuhr dann 3 Sekunden später wieder anläuft.

: Bearbeitet durch User
von Joe G. (feinmechaniker) Benutzerseite


Lesenswert?

Philipp G. schrieb:
> Doof dass die Stoppuhr dann 3 Sekunden später wieder anläuft.

Das zu verhindern stand nicht im Pflichtenheft ;-)

von Stefan F. (Gast)


Lesenswert?

Wie sollen wir Fragen zu deinem Programm beantworten, ohne es gesehen zu 
haben?

von Peter D. (peda)


Lesenswert?

Timothy K. schrieb:
> Wie kann ich durch einen Tasterdruck mein Programm anhalten?

Auf jeden Fall nicht, indem Du hartnäckig die Millionen Codebeispiele 
zum Tasten einlesen und entprellen im Web ignorierst.

von sumo (Gast)


Lesenswert?

Stefan U. schrieb:
> Wie sollen wir Fragen zu deinem Programm beantworten, ohne es
> gesehen zu haben?

Es wurden schon viele Tipps im anderen Thread gegeben.
Beitrag "Stoppuhr TASTER"
Auf die Antworten ging er aber nicht ein.
Statt dessen hat der TO einen zweiten Thread aufgemacht...

von Dutch Leera (Gast)


Lesenswert?

Timothy K. schrieb:
> auf dem LCD display

Da hat wieder jemand so ein beliebtes

Liquid Crystal Display   Display

Und ich dachte schon die sind am Aussterben.

von fop (Gast)


Lesenswert?

Mit dem Taster einfach den Oszillator lahmlegen, z.B. durch 
kurzschliessen eines Pins des Quarzes mit Masse.
Oder noch besser : Enable-Leitung zwischen µC und HD44... auftrennen -> 
Programm kann ruhig weiterlaufen, aber Displayanzeige bleibt stehen. 
Eignet sich auch ganz toll für Rundenzeiten. Sobald der Taster 
losgelassen wird, wird das Display wieder auf Stand gebracht.

von Stephan (Gast)


Lesenswert?

fop schrieb:
> Oder noch besser : Enable-Leitung zwischen µC und HD44... auftrennen ->
> Programm kann ruhig weiterlaufen, aber Displayanzeige bleibt stehen.
> Eignet sich auch ganz toll für Rundenzeiten. Sobald der Taster
> losgelassen wird, wird das Display wieder auf Stand gebracht.

die Idee hat sogar was.

von Plim (Gast)


Lesenswert?

Timothy K. schrieb:
> Wie kann ich durch einen Tasterdruck mein Programm anhalten? Zum
> Beispiel bei einer stoppuhr auf dem LCD display

Normalerweise sollte man dir links und rechts eine an deine Backen 
hauen, weil du nicht mal fähig bist hier zu schreiben welche Stoppuhr es 
ist bzw. einen Pseudocode postest auf den man eingehen kann, du 
Donnerstagstroll

von Einer K. (Gast)


Lesenswert?

Timothy K. schrieb:
> Wie kann ich durch einen Tasterdruck mein Programm anhalten?

Du könntest  dem Programmteil eine "Stopp Nachricht" senden!
1
StoppUhr stoppuhr;

Und in einer Funktion/Methode dann:
1
stoppuhr.stopp();

von Route_66 H. (route_66)


Lesenswert?

Stephan schrieb:
> die Idee hat sogar was.

Funktioniert nur meist nicht, denn man muss genau den richtigen 
Augenblick erwischen und der Taster darf nicht prellen!

von Philipp G. (geiserp01)


Lesenswert?

Arduino F. schrieb:
>> Wie kann ich durch einen Tasterdruck mein Programm anhalten?

Ich habe eine viel bessere Lösung als ihr:

Falls Batteriebetrieben:

Taster mit VCC+ und GND verbinden.

Falls am Netz:

Taster mit P und N verbinden.

No code. Funzt.

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Timothy K. schrieb:
> Wie kann ich durch einen Tasterdruck mein Programm anhalten?
Du bist offensichtlich auf der Suche nach Code....


Hier mal was vorgekautes...
Aber dennoch habe ich Bedenken dabei, ob du das verdauen kannst.
1
class StoppUhr: public Printable
2
{
3
  private:
4
  unsigned long startzeit;
5
  unsigned long abgelaufenezeit;
6
  bool isrunning;
7
8
  public:
9
  StoppUhr():startzeit(0),abgelaufenezeit(0),isrunning(false){}
10
11
  void reset()
12
  {
13
    isrunning = false;
14
    startzeit = 0;
15
    abgelaufenezeit = 0;
16
  }
17
  
18
  void start()
19
  {
20
    if(isrunning) return; // nachstart Verriegelung
21
    isrunning = true;
22
    startzeit = millis();
23
  }
24
  
25
  void halt()
26
  {
27
    if(!isrunning) return; // eine angehaltene Uhr kann man nicht anhalten
28
    isrunning = false;
29
    abgelaufenezeit += millis()-startzeit;
30
  }
31
 
32
  virtual size_t printTo(Print &printer) const
33
  {
34
    return printer.print(isrunning?millis()-startzeit+abgelaufenezeit:abgelaufenezeit);
35
  }
36
};
37
38
StoppUhr stoppuhr;
39
40
void yield()
41
{
42
  switch(Serial.read())
43
  {
44
    case 'r':stoppuhr.reset();break;
45
    case 's':stoppuhr.start();break;
46
    case 'h':stoppuhr.halt(); break;
47
  }
48
}
49
50
void setup() 
51
{
52
  Serial.begin(9600);
53
}
54
55
void loop() 
56
{
57
  Serial.println(stoppuhr);  
58
  delay(1000);
59
}

von Philipp G. (geiserp01)


Lesenswert?

Version 01.00.00001 build 00001
Revision: Mit Tastern ergänzt:
1
const int iStopStartPin = 9;
2
const int iResetPin = 10;
3
boolean bStopStartState  = false;
4
5
class StoppUhr: public Printable
6
{
7
  private:
8
  unsigned long startzeit;
9
  unsigned long abgelaufenezeit;
10
  bool isrunning;
11
12
  public:
13
  StoppUhr():startzeit(0),abgelaufenezeit(0),isrunning(false){}
14
15
  void reset()
16
  {
17
    isrunning = false;
18
    startzeit = 0;
19
    abgelaufenezeit = 0;
20
  }
21
  
22
  void start()
23
  {
24
    if(isrunning) return; // nachstart Verriegelung
25
    isrunning = true;
26
    startzeit = millis();
27
  }
28
  
29
  void halt()
30
  {
31
    if(!isrunning) return; // eine angehaltene Uhr kann man nicht anhalten
32
    isrunning = false;
33
    abgelaufenezeit += millis()-startzeit;
34
  }
35
 
36
  virtual size_t printTo(Print &printer) const
37
  {
38
    return printer.print(isrunning?millis()-startzeit+abgelaufenezeit:abgelaufenezeit);
39
  }
40
};
41
42
StoppUhr stoppuhr;
43
44
void yield()
45
{
46
  switch(Serial.read())
47
  {
48
    case 'r':stoppuhr.reset();break;
49
    case 's':stoppuhr.start();break;
50
    case 'h':stoppuhr.halt(); break;
51
  }
52
}
53
54
void setup() 
55
{
56
  Serial.begin(9600);
57
  pinMode(iStopStartPin, INPUT);
58
  pinMode(iResetPin, INPUT);
59
}
60
61
void loop() 
62
{
63
  Serial.println(stoppuhr);  
64
  delay(1000); // someone need to told the author not to use delays. I'm damn sure this will happen very very soon in uC forum.
65
  if (digitalRead(iStopStartPin) == HIGH) // press and hold at least 1001 ms. blame the author not me.
66
67
  // todo: entprell gedoens
68
  {
69
     stoppuhr.start();
70
   bStopStartState = !bStopStartState
71
   break;
72
   // to do: read bStopStartFlag to continue counting when button is pressed second time
73
  }
74
75
    if (digitalRead(iResetPin) == HIGH) // press and hold at least 1001 ms. blame the author not me.
76
  {
77
     stoppuhr.reset();break;
78
79
  }
80
}

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Philipp G. schrieb:
> // someone need to told the author not to use delays.
Ach, da mache dir mal keine Sorgen......

Und wenn du die Tastenauswertung in yield() stopfen würdest, dann könnte 
dich das delay() auch mal kreuzweise.

von Philipp G. (geiserp01)


Lesenswert?

Ich glaub' für erste haben wir für den TO genug getan.

von Einer K. (Gast)


Lesenswert?

Philipp G. schrieb:
> genug getan

Das ist die Frage ....
Genug für dich?
Für mich?
Für den TE?

Ich fürchte, dass es da Diskrepanzen geben wird.

von Philipp G. (geiserp01)


Lesenswert?

Der soll sich erstmal melden.

von Einer K. (Gast)


Lesenswert?

Philipp G. schrieb:
> Der soll sich erstmal melden.
Nein nein, ich meine schon dich.....

Original: 
Beitrag "Re: Stoopen Programm"
Verfremdet: 
Beitrag "Re: Stoppuhr TASTER"

Philipp G. schrieb:
> someone need to told the author not to use delays.
Wie gesagt, über delay() muss mir keiner mehr was sagen.

Philipp G. schrieb:
> I'm damn sure this will happen very very soon in uC forum.
Und wie du siehst, macht das auch keiner, entgegen deiner Vorsehung

Philipp G. schrieb:
> press and hold at least 1001 ms.
Du bist es, der Tastenauswertungen in einer "Display Routine" 
unterbringen möchte.
Warum auch immer?!?!?

Philipp G. schrieb:
> blame the author not me.
Warum schüttest du Schande über mich?

Ich habe nichts dagegen, wenn du meinen Code verwendest.
Aber es kann doch nicht meine Blamage sein, wenn du ihn nicht verstehst.
Oder?

---

Das, mein, delay() in loop() hat drei wichtige Aufgaben:

1. Es dient dafür, eine lesbare Anzeige zu bekommen. Denn ohne huschen 
die Zahlen zu schnell durch.

2. Und zwar so schnell, dass die Serial FiFo vollläuft und damit das 
Print blockierend wird. Das gilt es zu verhindern.

3. Es soll Rechenzeit an die Uhrsteuerung abgeben. Denn die UHR soll ja 
SOFORT auf Eingaben reagieren können.

---

Auch wenn es auf den ersten Blick nicht so aussieht, und es sich 
überzogen anhört, implementiert das Programm dennoch zwei Nebenläufige 
Fäden. Also kooperatives Multitasking, auf einem Arduino UNO, in seiner 
wohl primitivsten Form.

---

Ja, sicherlich könnte man sagen, dass das delay() an der Stelle nicht 
optimal ist. Auch könnte man sagen, dass es noch einige weitere 
Möglichkeiten gibt, da ein Zeitverhalten und Nebenläufigkeiten unter zu 
bringen.

Aber die delay() Variante ist mit Abstand die einfachste. Und für diese 
(meine) Problemlage doch vollkommen ausreichend. Es sei denn, es kommt 
jemand daher, und stopft Tastenauswertungen dahin, wo sie vom delay() 
blockiert werden und macht dann mich dafür verantwortlich.

von Philipp G. (geiserp01)


Lesenswert?

Arduino F. schrieb:
> Philipp G. schrieb:
>> blame the author not me.
> Warum schüttest du Schande über mich?

Wie gesagt, wir - vor allem aber DU - hast für den TO genug getan. Der 
erste ernst gemeinte Vorschlag für den TO.

Bis der sich meldet belass' ich es erstmal dabei, auf die Kommentare 
einzugehen.

Vielleicht will er das Ding in Assembler realisieren, oder in Q Basic, 
oder in Pascal, oder in Fortran, oder mit Java, .net, C++, Cobal, ABAP, 
Python, Shell script, fox pro, egal.

von sumo (Gast)


Lesenswert?

Philipp G. schrieb:
> Vielleicht will er das Ding in Assembler realisieren, oder in Q Basic,
> oder in Pascal, oder in Fortran, oder mit Java, .net, C++, Cobal, ABAP,
> Python, Shell script, fox pro, egal.

Hast du überhaupt die Frage des TO gelesen?
Ich frage deshalb, weil du mit allen möglichen Programmiersprachen auf 
den Arduino losgehen willst...

Timothy K. schrieb:
> wie kann ich bei meinem bestehenden Arduino Programm für eine Stoppuhr
> zwei Taster verwenden.

von Philipp G. (geiserp01)


Lesenswert?

ok, das ist mir entgangen.

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.