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
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.
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
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.
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.
Wie kann ich durch einen Tasterdruck mein Programm anhalten? Zum Beispiel bei einer stoppuhr auf dem LCD display
schliess die Taste an den Reseteingang des Controllers an. Damit wird jedes Programm zuverlässig angehalten
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
Philipp G. schrieb: > Doof dass die Stoppuhr dann 3 Sekunden später wieder anläuft. Das zu verhindern stand nicht im Pflichtenheft ;-)
Wie sollen wir Fragen zu deinem Programm beantworten, ohne es gesehen zu haben?
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.
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...
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.
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.
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.
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
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(); |
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!
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
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 | }
|
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
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.
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.