| Autor |
Beitrag |
slugg
      
Beiträge: 21
|
Verfasst: Do 12.06.08 10:59
Hallo,
ich habe folgendes Problem:
Ich habe an einem LPT Stecker den Input freigelegt, also wenn ich ein Kabel auf Masse lege, ändert sich der Wert von 127 auf 111
Diese Wertänderungen will ich zählen und die Dauer angeben, die von Wert 111 auf 127 erreicht wird.
Wie kann ich eine dauerhafte Abfrage des Wertes programmieren? Während Listbox1.enabled=true soll der Wert bei einer Änderung erkannt werden, in einer Listbox ausgegeben werden und die Dauer zwischen 111 und 127 soll in einer Listbox ausgegeben werden!
Ich steh auf dem Schlauch, wenn ich dies mit einer repeat oder while Schleife programmieren will, stürzt das Programm ab!
Da ich ziemlicher Delphi Neuling bin, weiß ich nicht weiter und hoffe, dass ihr mir helfen könnt!
MfG
Alex Moderiert von Narses: Topic aus VCL (Visual Component Library) verschoben am Do 12.06.2008 um 12:21
|
|
Reinhard Kern
      
Beiträge: 591
Erhaltene Danke: 14
|
Verfasst: Do 12.06.08 13:36
slugg hat folgendes geschrieben: | Wie kann ich eine dauerhafte Abfrage des Wertes programmieren? ...
Moderiert von Narses: Topic aus VCL (Visual Component Library) verschoben am Do 12.06.2008 um 12:21 |
Pssst, das Geheimnis heisst Timer.
Repeat und ähnliche Schleifen sind eh Unsinn - was machst du, wenn dein Programm auf einem 10mal schnelleren Rechner läuft? Oder auf einem, der ausgelastet ist? Seitdem es Pascal-Programme gibt, sind die PCs 1000 mal schneller geworden, daher laufen viele alte Programme mit Zeitschleifen nicht mehr.
Also mit Hilfe eines Timers z.B. alle 10 msec den LPT-Eingang prüfen.
Gruss Reinhard
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Do 12.06.08 14:40
Reinhard Kern hat folgendes geschrieben: | | Repeat und ähnliche Schleifen sind eh Unsinn |
für exakte Zeitabstände zwischen Ereignissen ja, aber darum geht es hier ja nur an hinterer Stelle, eigentlich soll ein Wert überwacht werden.
@ slugg: Nun kommt es auf die Genauigkeit an, mit der du die Zeiträume zwischen den Wechseln brauchst. Über 30 Millisekunden kannst du ruhig einen Timer nehmen, schont das System("'Wecker' stellen und Windows weckt dich einmal pro Sekunde mit einem Timer-Ereignis auf" statt "ununterbrochen nachschauen").
Soll es aber sehr genau sein, so ist der Windows-Timer ungenügend, da er ein Intervall von 30 ms wohl nicht überschreiten kann. Dann würde ich wohl eine Schleife nehmen und bei erfolgtem Wechsel mittels NOW die Systemzeit auslesen. Weiss zwar nicht, in welchem Abstand die erneuert wird, aber mit einem Timer müsste man sie ja auch nochmal einholen, respektive eine "Zeit"-Variable jedes Mal erhöhen.
Wäre ganz schön, wenn du deinen Quelltext mit der abstürzenden Schleife und ein bisschen mehr über deinen Ansatz posten könntest, dann könnten wir dir sicher besser helfen.
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
slugg 
      
Beiträge: 21
|
Verfasst: Do 12.06.08 17:22
Huhu, danke für die Antworten!
Das Programm läuft derzeit über einen Timer, aber da ist ja der Abstand zwischen 127 und 111 genau die Timerzeit!
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.zaehlen(Sender: TObject); begin edit1.Text:=IntToStr(inp32($379)); if inp32($379)>(c) then p:=p+1; c:=inp32($379); edit2.Text:=inttostr(p); if inp32($379)=127 then edit3.Text:='nicht verbunden'; if inp32($379)=111 then edit3.Text:='verbunden'; end; |
edit: c wird bei tform.create also 127 festgelegt!
Das ist meine Source zur Zeit!
Das Zählen der Kontakte geht, aber die Zeit zwischen den Kontakten (ist da noch nicht drin, habe ich aber schon getestet) geht nicht, wenn ich die in einer ListBox ausgeben will, schreibt er alle ganz viele Werte hinein, so viele/sec wie der Timer ist... Das will ich ja nicht, ich will nur, dass er die Zeit zwischen 127 und 111 zählt! Wobei das auch erst nach dem ersten 111er Wert erfolgen soll!
MfG
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Do 12.06.08 17:36
Hi,
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.Zaehlen(Sender: TObject); const inp_Verbunden = 111; inp_NichtVerbunden = 127; InputPort = $379; begin Edit1.Text := IntToStr(inp32(InputPort)); if inp32(InputPort) > c then p := p + 1; c := inp32(InputPort); Edit2.Text := IntToStr(p); if inp32(InputPort) = inp_Verbunden then Edit3.Text := 'verbunden' else Edit3.Text := 'nicht verbunden'; end; |
PS: Wäre ganz schön, wenn du die Deklaration der Globalen Variablen mitliefern könntest.
Und nicht unbedingt a, b und c als Variablennamen - in der Mathematik hat man längere Therme, da müssen sie kurz sein, um lesbar zu bleiben. Beim Programmieren müssen sie selbsterklärend, quasi "intuitiv bedienbar" sein - genau, wie die Programme selber für den Benutzer später auch
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
oldmax
      
Beiträge: 380
D3 Prof, D4 Prof
|
Verfasst: Do 12.06.08 19:35
Hi
So ganz sicher bin ich mir nicht, aber die Werte die du einliest, könnten Fahrkarten sein. Wenn du sagst, die Zeit des Wechsels ist die Timerzeit macht es mich ein wenig stutzig. Aber gut, vernachlässigen wir dies mal. Was du einliest ist die Binäre "01111111" und vermutlich hast du D5 erwischt, denn das macht "01011111".
Das sind die Zahlen 127 und 111 dezimal.
Damit könntest du auch eine direkte Auswertung der einzelnen Bits bewirken. Ein wenig irritiert bin ich über D7. Entweder hast du da von Hause aus einen Masseschluß, oder dieser Pin ist irgendwie anders beschaltet.
Nun zur Zeitmessung. Auch ich würde hier über Timer einlesen, dabei die Timerzeit auf 10 ms. Schlagt mich nicht, ich weiß, das schaft er nicht, aber das garantiert einen einigermaßen gleichmäßigen Zyklus. In der Timerroutine liest du den Wert ein und schreibst ihn in eine Speicherzelle. Dann vergleichst du, ob sich der Wert geändert hat, wenn ja, eine kleine Procedure aufrufen.
In der Timerroutine
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| Begin Timer1.Enabled:=False; Neuwert:=inp32(InputPort); If New_Input<>Old_Input then Set_My_Event; Timer1.Enabled:=True; End; |
Die kleine Procedure dazu
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| TForm1.Set_My_Event; Begin New_Time:=Now; TimeFlag:=true; Old_InPut:=New_Input; end; |
Damit ist der "schnelle" Timer gut fertig, bevor er sich erneut aufruft. Nun würd ich einen 2. langsameren Timer nehmen, und das TimeFlag auswerten. In diesem kannst du dann die Zeitdifferenz berechnen und die Werte zur Ausgabe bringen. Nebenbei läßt sich dein Programm weiterhin bedienen und du bist nicht inn einer Schleife "gefangen".
z.B. die 2.Timerroutine für die Auswertung und die Ausgabe in dem Formular
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| Begin Timer2.Enabled:=False; If TimeFlag then begin Diff_Time:=New_Time - Old_Time; Edit1.Text:=FormatFloat('#0.0000',Diff_time); Timeflag:=False; end; end; |
Nun mußt du es nur noch ein wenig hübsch gestalten. Übrigends, alle hier verwendeten Variablen sind global zu vereinbaren. Die Zeitwerte sind vom Typ TTimeStamp, der erlaubt auch anzeige von ms.
Ich hab die Codes nicht getestet, da ich auf dieser Maschine kein Delphi habe. Sollte aber gehen. Eventuell mußt du Diff_Time etwas anders aufarbeiten.
Vielleicht solltest du auch mal die anderen Bits ausprobieren. Der Rechner in Windows kann dir die verschiedenen Formate Hex, Okt, Dez, und Bin anzeigen. Mit der Eingabe im Dez-Bereich wechseln auf Bin und du bekommst das Bitmuster.
So, nun genug.
Gruß oldmax
_________________ Zier dich nich so, ich krieg dich schon....
|
|
slugg 
      
Beiträge: 21
|
Verfasst: Do 12.06.08 21:03
Huhu
ok das muss ich alles erstmal verdauen und setzen lassen.
Vielleiccht erklär ich erstmal was ich machen will
Also wir sollen in der Schule, Informatik Leistungkskurs 11. Klasse, ein etwas schwierigeres projekt machen! Eine Projektarbeit, sozusagen.
Da ich und mein Partner Autofreaks sind wollten wir einen Leistungsprüfstand machen.
Da das aber technisch schwierig ist und es eigentlich nur um die programmierung geht, die schwieriger sein soll, werden wir das wohl erst einmal mit Hilfe eines Elektormotors oder Taster simulieren! Mein Partner ist für das Diagramm zuständig, da wir so etwas noch nicht im Unterricht behandelt haben, fordert es ihn ziemlich.
Ich bin für den Rest zuständig.
Mein Problem ist, dass ich eine Umdrehung mit einem Kontakt simulieren will. Somit muss ich die Wertänderung auslesen, die Zeit für nicht verbunden auf verbunden messen (Zeit für 1 rpm).
Da ich aber kaum Ahnung in Delphi habe (also nicht so spezialisiert wie ihr ^^) weiß icch manchmal gar nicht, was ihr schreibt ^^
Okay, zurück zum Problem.
Wenn ich die Zeitmesseung so mache wie ich denke, dann misst er in jeder timerprocedur die Zeit, aber die ist nur so groß wie die Timer Zeit! Leider habe ich den Quelltext aus Frust nicht gespeichert, aber ich weiß noch in etwa wie dieser war, ich werde ihn neu schreiben, so wie ich denke, dass es gehen könnte und poste ihn noch einmal
Bitte habt Verständins mit einem Newbe wie mir ^^
Danke
MfG
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Do 12.06.08 21:39
Hi,
slugg hat folgendes geschrieben: | | Mein Problem ist, dass ich eine Umdrehung mit einem Kontakt simulieren will. Somit muss ich die Wertänderung auslesen, die Zeit für nicht verbunden auf verbunden messen (Zeit für 1 rpm). |
Hmm... angenommen 111 = true; 127 = false. Brauchst du dann nicht einfach nur die Anzahl der Ausschläge pro Zeiteinheit?
@oldmax: Es hat doch niemand gesagt, dass das Auslesen in geregelten Abständen geschehen soll.. Dann würde er eventuell bei hohen Geschwindigkeiten sogar Ausschläge übersehen.
IMHO ist eine Schleife dann doch besser geeignet; ständig checken und entsprechend bei Ausschlag per Now an die Zeit. In der Schleife alle X durchgänge mal Application.ProcessMessages, sonst schmiert die Anwendung wie beschrieben ab.
Delphi-Quelltext 1: 2: 3:
| Timer1.Enabled:=False; Timer1.Enabled:=True; |
Edit: Delphi-Quelltext 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:
| procedure UeberwacheInput; var LetzterInput: Integer; begin repeat until Input = 127; LetzterInput := Input; repeat if Input <> LetzterInput then begin LetzterInput := Input; OnToggle(Now, LetzterInput); end; Application.ProcessMessages; until false; repeat repeat Application.ProcessMessages; until Input = 127; OnToggle(Now, 127); repeat Application.ProcessMessages; until Input = 111; OnToggle(Now, 111); until false; end; |
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
|