Guten Tag liebe Community, ich habe mit Hilfe der Software Tinkercas eine Schaltung erstellt bei der ich mit Hilfe eines Arduino Uno die Zeitdifferenz zwischen zwei Rechtecksignalen messen möchte. Jedoch klappt es bei mir nicht. Ich habe in etlichen Foren nach Lösungen gesucht und versucht ähnliche Fälle bei meinem Problem anzuwenden. Jedoch ohne Erfolg. Kann mir einer sagen, was ich da Falsch mache ? Ich generiere mit zwei Drucktaster Signale. Zunächst klicke ich auf den ersten Drucktaster und danach auf den zweiten und möchte "einfach nur" die Zeitdifferenz messen. Ich habe auch nichts in Richtung Interrupt gemacht, da ich völliger Anfänger bin. Kann mir jemand sagen was da nicht stimmt ?
Kann es sein das Dein Loop mit Delay 10 viel zu schnell ist? Immerhin wird im Bildchen je Kästchen 1 s angezeigt. mfg Klaus
Hallo Klaus, danke für deine Antwort. Ich habe es geändert, jedoch funktioniert es trotzdem nicht. Es wird mir nur ne 0 immer angezeigt und ab und zu ne "4294967295".
Na, das erste Proramm misst ja garnichts, sondern kopiert nur den Zustand der Tasten an die beiden Ausgänge. Das zweite misst durchaus den Abstand und soll ihn in Millisekunden anzeigen. Wegem dem delay(100) allerdings nur mit 100ms Auflösung. Lass das delay doch mal ganz weg. Oh, und es sollte wohl eher
1 | |
heissen. Sonst wird dauer negativ, was macht die Simulation da bei einer unsigned-Variablen?
Gast
#5883070
Ende - Start
Gast
#5883090
Sven P. schrieb: > Ich generiere mit zwei Drucktaster Signale Zwei Drucktaster n , Mehrzahl! Der angehängte Programmkot beinhaltet keinerlei Zeiten, der schaltet lediglich zwei LEDs und auch das erst, wenn man ihn korrigiert.
Vielen Danke für die Rückmeldungen, ich habe das Delay komplett weggelassen und die Rechnung korrigiert. Jedoch erhalte ich andauern die Zahl "0". Also es wird keine Differenz angezeigt. Hier mein aktueller Code:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
Sven P. schrieb: > while(buttonState1 == HIGH); > start = millis(); > > while(buttonState2 == HIGH); > ende = millis(); Ist WHILE denn hier der richtige Befehl? Anfänglich hattest Du doch IF verwendet. Kannst Du mit der Oberfläche nicht debuggen? Dann geh doch mal step für step den Code durch. mfg Klaus
Gast
#5883125
Manfred schrieb: > Programmkot Sollen wir das als Kritik oder Verschreiber lesen?
Gast
#5883127
Ich würde folgenden Code probieren:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Grund: in der While Schleife ändern sich die zuvor gelesenen Werte nicht mehr!
Gast
#5883128
Sven P. schrieb: > while(buttonState1 == HIGH); ^ Semikolon muss weg > start = millis(); > > while(buttonState2 == HIGH); ^ hier ebenso > ende = millis(); Ich finde das mit Klammersyntax besser und eindeutiger: while(buttonState1 == HIGH) { start = millis(); }
Gast
#5883135
Sven P. schrieb: > Jedoch erhalte ich andauern d die Zahl "0". Was würde ich jetzt tun: Ich baue serial.print(start) und serial.print(ende) in die Hauptschleife ein und gucke, ob die sich ändern. Wenn nicht, baue ich weitere Ausgaben, ob die Taster überhaupt erkannt werden, z.B. auf Deine zwei LEDs. Programmieren lebt davon, dass Du eigene Strategien entwickelt, Fehlfunktionen einzugrenzen. Klaus R. schrieb: > Ist WHILE denn hier der richtige Befehl? Ich bezweifele es.
Sven P. schrieb: > while(buttonState1 == HIGH); > start = millis(); > > while(buttonState2 == HIGH); > ende = millis(); Ich denke Du verwendest WHILE fehlerhaft. Siehe: https://www.arduino.cc/reference/en/language/structure/control-structure/while/ Mach es mal so.
1 | |
2 | |
3 | |
4 | |
5 | |
Dein Code füllt in jedem Loop die Varaiablen. Und das geht so schnell das sie immer den selben Wert haben. Das IF:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
mfg klaus
Gast
#5883142
GEKU schrieb: > == HIGH ist die Polarität der Taster richtig? Sonst hätte er in der While Schleife auf Ewig hängen bleiben müssen! Wenn nicht probiert != HIGH oder == LOW
Gast
#5883145
Klaus R. schrieb: > Dein Code füllt in jedem Loop die Varaiablen. Und das geht so schnell > das sie immer den selben Wert haben. Ja, es ist Freitag. leo
GEKU schrieb: > Sonst hätte er in der While > Schleife auf Ewig hängen bleiben müssen! Natürlich, also unbedingt IF verwenden, mit {}. mfg klaus
Gast
#5883160
Klaus R. schrieb: >> Sonst hätte er in der While >> Schleife auf Ewig hängen bleiben müssen! > > Natürlich, also unbedingt IF verwenden, mit {}. Wenn ich das richtig verstanden habe, bleibt while solange auf Taste1 hängen, bis diese aktiv wird. Danach hängt while in Taste2 fest, bis auch diese betätigt wird. Könnte Sinn geben, je nachdem, was man erreichen will. Das würde man zügig heraus bekommen, wenn man Tasten und Timer serial ausgeben lässt, so furchtbar komplex ist das Programm ja mal nicht.
Vielen Danke für die zahlreichen Antworten. So wie ich es nun verstanden habe, soll ich die while-Schleife durch eine If-Schleife ersetzten. Das habe ich gemacht. Sobald ich den ersten Taster (auf Pin 2) drücke erscheinen die Zahlen "4294967101" und anschließend habe ich 5 Sekunden gewartet bis ich den zweiten Taster (auf Pin 3) gedrückt habe. Ich würde nun erwarten, dass irgendwas im Bereich von "5000" angezeigt wird. Jedoch kommt ein vollkommen anderer Wert raus, wie in der Abbildung zu sehen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
Gast
#5883166
Klaus R. schrieb: > Ich denke Du verwendest WHILE fehlerhaft. Die Frage ist, ob er die Arduino Loop nutzen , oder in dieser eine eigene Loop verwenden will. Im ersten Fall:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Im zweiten Fall:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Gast
#5883171
Sven P. schrieb: > If-Schleife if ist kein Schleifenkonstrukt! Die Schleife wird erst durch
1 | |
bewirkt! Diese Schleife bildet das Arduino Betriebssystem indem es loop () ständig aufruft.
Gast
#5883178
Sven P. schrieb: > if(digitalRead(3)==HIGH) > { > ende=millis(); > } > > dauer = start - ende; > > Serial.println(dauer); Besser ist :
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
dann erfolgt die Auswertung und Ausgabe nur wenn Taste 2 gedrückt wird
Gast
#5883187
Sven P. schrieb: > Jedoch kommt ein vollkommen anderer Wert raus, Dann ergreife endlich Eingeninitiative und lasse Dir alle Werte zeigen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Gast
#5883191
Sven P. schrieb: > void loop() > { > if(digitalRead(2)==HIGH) > { > start = millis(); > } > > if(digitalRead(3)==HIGH) > { > ende=millis(); > } > > dauer = start - ende; > > Serial.println(dauer); > > } So geht es nicht. So sollte es gehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
Kurze Erläuterung: Er bleibt in der 1. while Schleife hängen bis der Taster gedrückt wird. Drücken des Tasters unterbricht die while Schleife. Dadurch wird die Variable start gesetzt und er bleibt in der 2. while Schleife hängen. Hier gleiche Funktion wie in der 1. Schleife. Allerdings wird hier beim Beenden der Schleife ende gesetzt. Anschließend käme Deine Berechnung der Differenz und Ausgabe des Ergebnisses. Das delay kannst Du weg lassen. Danach bleibt er dann wieder in der 1. Schleife hängen. Die Variable Condition am besten global definieren und in setup() mit dem entsprechenden Wert belegen. Man braucht sie auch nicht wenn man den passenden Wert in der while-Schleife einträgt.
Gast
#5883542
Zeno schrieb: > Die Variable Condition am besten global definieren und in setup() mit > dem entsprechenden Wert belegen. Man braucht sie auch nicht wenn man den > passenden Wert in der while-Schleife einträgt. Was soll der Wert in einer Variablen, die sowieso im Programm nicht geändert werden kann. Ein #define für den Präprozessor ist da deutlich zielführender und universeller, auch wenn man den Wert in der Bedingung für den while-Block direkt festlegen möchte, was hier defacto der Fall ist.
Gast
#5883571
Wolfgang schrieb: > Was soll der Wert in einer Variablen, die sowieso im Programm nicht > geändert werden kann. Ein #define für den Präprozessor ist da deutlich > zielführender und universeller, auch wenn man den Wert in der Bedingung > für den while-Block direkt festlegen möchte, was hier defacto der Fall > ist. Es führen viele Wege nach Rom und ja man kann auch #define verwenden. Auch wenn Dein Post mal wieder der typische C-Zeigefinger "Das macht man nicht so", der von mir hin geschriebene Code wird funktionieren, sogar wenn man das Ganze in loop() rein schreibt, auch wenn das nicht sonderlich elegant wäre. Ich habe es eigentlich nur zur Erklärung eingefügt, weil sich es sich so leichter schreiben ließ. Ich denke mal das es für den TO so auch verständlicher ist. Das man es auch im while machen kann hatte ich ja geschrieben.
Gast
#5883580
Zeno schrieb: > Auch wenn Dein Post mal wieder der typische C-Zeigefinger "Das macht man > nicht so" ... Sei beruhigt, von C habe ich nicht sonderlich viel Ahnung und enthalte mich gewöhnlich bei solchen Stilfragen. Aber manche Dinge fallen selbst mir als Quereinsteiger auf. ;-)
Danke für eure Hilfe, der Code funktioniert nun und es zähl fleißig die Differenz. Jedoch zählt es sie falsch. Nach 10 sek. ist die Anzeige gerade mal bei "2100 ms". Kann mir einer sagen woran das liegt ? wenn "millis()" Millisekunden entsprechen, so müsste es ja bei "10000" sein.
Gast
#5883889
Sven P. schrieb: > Danke für eure Hilfe, der Code funktioniert nun und es zähl fleißig die > Differenz. Jedoch zählt es sie falsch. Das Programm zählt nicht die Differenz, sondern es holt sich bei den Tastenereignissen als Timestamp den Zählerstand vom Millisekunden-Systemtimer. Die Dauer wird erst später ausgerechnet. Prüfe also erstmal die Timestamps unter Berücksichtigung der Tatsache, dass der Zähler auch mal überlaufen kann.
Danke für die Antwort, aber leider verstehe ich nicht was du meinst :(
Zeno schrieb: > Es führen viele Wege nach Rom Bei dem Vorgehen, landet er aber nicht in Rom, sondern kommt nur bis Castrop-Rauxel, weil er in einer Schleife überlaufende Werte erwischt. Damit wird er zwangsläufig auch negative Zeiten heraus bekommen. Dann kommt die Frage hoch, ob da die Relativitätstheorie zugeschlagen hat!
Gast
#5883936
Kai D. schrieb: > Damit wird er zwangsläufig auch negative Zeiten heraus bekommen. Wie sollen bei Verrechnung von unsigned Variablen negative Zahlen heraus kommen?
Gast
#5883939
Sven P. schrieb: > Danke für die Antwort, aber leider verstehe ich nicht was du meinst :( Gehe Stück für Stück bei der Fehlersuche vor: Prüfe erstmal die Werte für start und ende auf Plausibilität
Gast
#5884013
Kai D. schrieb: > Bei dem Vorgehen, landet er aber nicht in Rom, sondern kommt nur bis > Castrop-Rauxel, weil er in einer Schleife überlaufende Werte erwischt. > Damit wird er zwangsläufig auch negative Zeiten heraus bekommen. > > Dann kommt die Frage hoch, ob da die Relativitätstheorie zugeschlagen > hat! Nö er muß nur die Variablen start und ende passend definieren. Die Funktion millis() liefert unsigned long zurück, d.h. es kommt erst nach 1193 Stunden bzw. 49 Tagen zum Überlauf. Innerhalb dieser Zeit wird er wohl beide Taster gedrückt haben. Also die Variablen auf unsigned long setzen. Den Überlauf kann relativ einfach abfangen, wenn man prüft ob start > ende ist. Wenn dem so ist, dann muß etwas anders die Differenz berechnen. Die Differenz wäre nach einem Überlauf 4294967296-start+ende.
Gast
#5884037
Zeno schrieb: > Also die Variablen auf unsigned long setzen. Was meinst du wohl, was hier passiert: Sven P. schrieb: > unsigned int long start; > unsigned int long ende; > unsigned int long dauer; Zeno schrieb: > Den Überlauf kann relativ einfach abfangen, wenn man prüft ob start > > ende ist. Warum willst du beim Überlauf des millis()-Timers irgendetwas abfangen? Mir scheint, da fehlen ein paar Grundlagen. Rechne mal mit unsigned long Arithmetik aus, was bei der Rechnung
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
heraus kommt. Die Differenz wird richtig als 14 berechnet.
Gast
#5884492
Tja, heißt es nun Ende-Start oder Start-Ende ... genau hinschauen hilft hier ziemlich weiter.
Gast
#5884567
Wolfgang schrieb: > Was meinst du wohl, was hier passiert: > > Sven P. schrieb: >> unsigned int long start; >> unsigned int long ende; >> unsigned int long dauer; Hatte ich übersehen - wirgendwie nur auf long. Wolfgang schrieb: > Mir scheint, da fehlen ein paar Grundlagen. Mir schein Du bist ein biss'l arrogant. Ein einfacher Hinweis das es auch so funktioniert wäre völlig ausreichend gewesen. Rein mathematisch würde das nicht funktionieren. Von einer natürlichen Zahl kannst Du keine größere natürliche Zahl abziehen, das wäre ja negativ und das kennt dieser Zahlenbereich nicht. Bei ganzen Zahlen ginge es zwar aber es käme das falsche heraus und dazu noch negativ. Allerdings gibt es in der Mathematik auch keine Begrenzung des Zahlenbereiches. Das das hier richtig umgesetzt wird war mir bisher nicht bewußt. Ich habe es bisher immer so gemacht wie beschrieben. Funktioniert auch ist halt nur etwas umständlicher.
Gast
#5884591
Zeno schrieb: > Rein mathematisch würde das nicht funktionieren. Natürlich funktioniert das auch mathematisch. Man muss nur die Rechenregeln beachten. Beim Datentyp unsigned long gilt
1 | |
Gast
#5884729
Zeno schrieb: > Rein mathematisch würde das nicht funktionieren. Doch. > Von einer natürlichen > Zahl kannst Du keine größere natürliche Zahl abziehen, das wäre ja > negativ Das ist korrekt. Nur leider völlig am Problem vorbei. Computer rechnen nämlich nicht mit natürlichen Zahlen (dazu müssten sie unendlich breite Register haben), sondern in einem zyklischen Zahlenraum, der eine Teilmenge entweder der natürlichen oder der ganzen Zahlen umfaßt. Und in solchen zyklischen Zahlenräumen gelten andere Rechenregeln. Jeder Programmierer sollte diese aus dem Effeff beherrschen, sonst fällt er früher oder später auf die Schnauze.
Wolfgang schrieb: > Wie sollen bei Verrechnung von unsigned Variablen negative Zahlen heraus > kommen? Na, so: Zeno schrieb: > Rein mathematisch würde das nicht funktionieren. Von einer natürlichen > Zahl kannst Du keine größere natürliche Zahl abziehen, das wäre ja > negativ und das kennt dieser Zahlenbereich nicht. Doch kann man, wie die Antwort zeigte: Wolfgang schrieb: > Natürlich funktioniert das auch mathematisch. Man muss nur die > Rechenregeln beachten Wobei: Zeno schrieb: > Den Überlauf kann relativ einfach abfangen Muss aber auch erst einmal getan werden. Erst mal gibt es einen Unterlauf.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.

