Autor |
Beitrag |
dkx
      
Beiträge: 36
|
Verfasst: So 03.10.04 11:17
Hallo,
ich möchte von einem Messgerät Daten auslesen.
Wenn ich z.B. den String "DMF" sende, dann sollte ich die Uhrzeit vom Messgerät genannt bekommen.
Habe dies mit dem WinXP HyperTerminal ausprobiert und da hat es auch geklappt.
Mit den verschiedenen Delphi-Komponenten (TComPort und SerialNG) funktioniert es nicht.
Ich habe die Beispieldateien ausprobiert und den String gesendet, aber ich bekomme nur ein komisches Ascii-Zeichen zurück (im dec-format: 165).
Habe auch andere fertige Terminal Programme getestet (z.B. Docklight) und mit diesen Programmen kam der gleiche Fehler.
Ein den Einstellungen (Baud, Stop-Bit, ...) kann es nicht liegen da ich diese Einstellungen vorgenommen habe so wie sie in der Anleitung stehen.
Wo könnte also der Fehler zu finden sein?
Danke,
Anton
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: So 03.10.04 11:25
Ich kann mich irren, aber war es nicht so, dass das HyperTerminal keine reine RS232-Verbindung herstellt, sondern die Handshake-Bits mit verwendet? Hast du das mal überprüft bzw. bei den anderen Programmen auch eingestellt?
Gruß,
Jörg
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
dkx 
      
Beiträge: 36
|
Verfasst: So 03.10.04 12:23
Ich weiss zwar nicht was diese FlowControl bedeutet, aber ich habe in DockLight alle Einstellungen durchprobiert: Off, Manual, Hardware, Software, Hard+Software.
Im Hyperterminal kann ich die FlowControl auf None, Hardware oder Xon/Xoff stellen: mit allen Einstellungen funktioniert es jedoch problemlos.
Im Gegensatz zu den anderen Programmen gibt es im Hyperterminal allerdings noch ein paar weitere Einstellungen:
Emulation: Auto detect, ANSI, TTY, VT100, ...
und Telnet terminal ID steht auf "ANSI"
Backscroll buffer lines: 500
Diese ganzen Einstellungen kenne ich leider nicht und weiss nicht für was sie gut sind. Habe allerdings verschiedene durchprobiert und es gab bei keiner Einstellung Probleme!
Ansonsten finde ich keine weiteren (unbekannten) Einstellungen in den ganzen Programmen von denen es evt. abhängen könnte (aber es muss wohl/hoffentlich doch noch eine geben?!).
Übrigens hatte ich zufällig zwei dieser Programme mal laufen und ich weiss nicht wie ich es geschafft habe, aber plötzlich hat auch das Hyperterminal dann nur noch 165 im dec-format zurück gesendet!
Erst nachdem ich die anderen Programme geschlossen hatte und auch Hyperterminal neu gestartet hatte ging es wieder.
...Auch das hat mich ein wenig verwirrt.
mfg
Anton
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: So 03.10.04 12:38
Sorry, aber deine Fehlerbeschreibung enthält wenig verwertbare Information. Im Handbuch zum Messgerät muss doch stehen, was es für eine Verbindung ist. Und wenn du Glück hast, steht auch ein Kommunikationsprotokoll drin. Sonst kann ich da aus der Ferne nicht mehr dzu sagen.
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
dkx 
      
Beiträge: 36
|
Verfasst: So 03.10.04 15:01
Es handelt sich um ein Blutzuckermessgerät und hier ist die Anleitung die ich habe:
lifescan.com/pdf/ultra_commspec.pdf
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: So 03.10.04 15:10
Aha, die Beschreibung ist äußerst aufschlussreich. Und zwar basiert die Kommunikation auf reinem RS-232, aber du musst RTS und DTR high setzen, da diese Pins als Spannungsversorgung genutzt werden. Sowas ist zwar allgemein nicht empfehlenswert, aber unter bestimmten Bedingungen möglich. Mein Infrarotempfänger arbeitet auch nach dem Prinzip.
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
dkx 
      
Beiträge: 36
|
Verfasst: So 03.10.04 15:26
Ich finde leider in der ComPort-Komponente keine Möglichkeit um RTS und DTR auf high zu stellen.
Wie genau soll das funktionieren?
Ich gebe zu, dass ich mich noch nicht so sehr auskenne, aber ich würde trotzdem gerne bei dieser Komponente bleiben da wir sie auch in anderen Projekten (Modelleisenbahn) im Informatikunterricht in der Schule verwenden.
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: So 03.10.04 15:43
Tja, willkommen in der wunderbaren Welt der Api-Programmierung.
Wenn du aus den Komponenten (die ich nicht kenne) irgendwie das Handle vom Port kriegst, kannst du die Signale so setzen:
Delphi-Quelltext 1: 2:
| EscapeCommFunction(Handle,SETRTS); EscapeCommFunction(Handle,SETDTR); |
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
dkx 
      
Beiträge: 36
|
Verfasst: So 03.10.04 15:54
Ich glaube es liegt doch nicht an RTS und DTR, da diese bereits eingeschaltet sind. Bei der SerialNG Komponente ist nämlich ein monitoring-programm dabei welches ich laufen lassen habe wärend ich mit dem ComPort-Komponenten-Programm eine Verbindung geöffnet habe. Das Monitoring Programm hat daraufhin folgendes angezeigt:
www.basicmotion.de/sonstiges/seriell.jpg
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: So 03.10.04 16:01
Tja, dann liegt das Problem woanders (war klar, oder?). Jetzt musst du das machen, was Millionen an ihren Projekten tagtäglich machen: Stelle für alle Kombinationen von Eingabemöglichkeiten unter allen Bedingungen die Ausgaben mit den erwarteten Ausgaben gegenüber, und der Fehler wird sich von alleine zeigen.  Und wenn nicht, ist die Hardware kaputt.
PS: Ich wette, es ist einer dieser Fehler, den man sofort erkennt, wenn man es SIEHT, aber diskutieren werden wir noch ewig ...
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
dkx 
      
Beiträge: 36
|
Verfasst: So 03.10.04 16:09
Ich glaube ich kann auch dies ausschließen, denn die Ausgabe ist wie ich schon sagte immer nur ein und das selbe zeichen (dec: 165).
Wie das z.B. unter DockLight aussieht:
www.basicmotion.de/sonstiges/rs232.jpg
Auch die Hardware ist nicht kaputt: Ich habe das Messgerät nicht nur zweimal (und es auch beide male getestet), nein, auch das dafür vorgesehene "Original"-Programm (eine Diabetes-Management-Software) funktioniert problemlos.
Vielleicht hat es doch etwas mit den Pins zu tun?!
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Di 12.10.04 14:53
Ich habe folgenden Verdacht (ist bei vielen Messgeräten so):
Das Ding sendet Xon und Xoff Chars - das heißt, wenn Xon (wahrscheinlich dein 165) gesendet wurde, dann kannst Du solange senden bis Xoff gesendet wird. Um Xoff brauchst Du dich wahrscheinlich nicht kümmern, da erfahrungsgemäß eh nur eine Hand voll Zeichen gesendet werden müssen - dafür reicht das Zeitfenster.
Lösung per Hand (API Kochrezept) :
Schreibe einen Polling thread. Den Thread hältst du an mit WaitCommEvent.
Wenn du senden willst setzt du den Event Char auf 165.
Wird der Thread danach fortgesetzt, schreibst den Befehl mit WriteFile auf die Schnittstelle.
Wenn Du empfangen willst ... wirds kompliziert ... Du must wissen ob das Gerät immer alles gesendete mit einem Zeichen abschließt - wenn das der Fall ist setzt du den EventChar auf dieses Zeichen und liest den Eingabepuffer aus, wenn der Thread fortgesetzt wird. Ansonsten must Du dir was einfallen lassen (z.B. Timer).
Bei SerialNG kannst Du das ganze mit den Events machen (OnCharCommEvent oder so)
|
|
dkx 
      
Beiträge: 36
|
Verfasst: Mo 18.10.04 14:04
Danke für deine Antwort,
aber es klappt immer noch nicht - folgendes habe ich ausprobiert:
Ich habe von der SerialNG-Komponente das Beispielprogramm genommen (ein einfaches Terminal-Programm welches senden + empfangen kann).
Dies habe ich folgendermaßen modifiziert:
Bei der SerialPortNG-Komponente im Objektinspektor "EventChar" auf "#165".
Und ebenfalls im Objektinspektor unter Eigenschaften die Prozedur "OnRXCharEvent" erstellt und folgendes reingeschrieben:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.SerialPortNG1RxCharEvent(Sender: TObject); var SendStr : String; begin SendStr := Edit1.Text; if CBAddCRLF.Checked then SendStr := SendStr+#$0d#$0a; SerialPortNG1.SendString(SendStr); end; |
(Du sagtest ja man soll hier einfach Senden, wenn die 165 emfangen wird)
Habe ich evt. was ganz falsch gemacht?
Wenn ich das Programm starte und als String z.b. "DMF" eingebe (das schaltet das messgerät ein), dann bekomme ich sekündlich (endloslange) eine antwort -> 165.
Ich habe auch ausprobiert die oben genannte Prozedur in "procedure TForm1.SerialPortNG1CommEvent(Sender: TObject);" zu schreiben, aber dann kommt das gleiche problem, ausser das bereits beim programmstart die ganze zeit 165 empfangen wird, obwohl man noch gar nicht auf "senden" geklickt hat (und demnach auch in das edit feld noch gar keinen string eingegeben hat der gesendet werden soll).
Kann mir evt. jemand ein kurzes, simples Delphi-Beispiel-Programm schreiben, welches einen string senden kann und dann auch strings empfangen kann - unter berücksichtigung dieser 165?
Ich kenne mich einfach zu wenig mit der Materie aus als das ich mich noch am eigenen Kopf aus dem Wasser ziehen könnte
mfg
Anton
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Mo 18.10.04 15:09
So schnell ist das nicht geschrieben...
Versuch mal folgendes:
1.Füge neuen Button hinzu und eine globale Variable namens "StrToSend"
2.Folgenden EventHandler für neuen Button schreiben
Quelltext 1: 2: 3: 4: 5:
| procedure TForm1.NewButtonOnclick(Sender: TObject); begin StrToSend := Edit1.Text; SerialPortNG1.EventChar := #165; end; |
3.Ändere die EventChar Procedure:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm1.SerialPortNG1RxCharEvent(Sender: TObject); begin if SerialPortNG1.EventChar = #165 then begin SerialPortNG1.SendString(StrToSend); SerialPortNG1.EventChar := #0; end; end; |
Nun kannst Du mit GetNextClusterAsString das gesendete als String speichern.
#165 wird natürlich immer noch ständig gesendet - du must es aus dem Empfangs String raus filtern.
|
|
dkx 
      
Beiträge: 36
|
Verfasst: Mo 18.10.04 18:30
Ich denke ich habe es so gemacht wie du gesagt hast, aber wenn ich jetzt mit dem neuen button was sende, dann kommt gar keine antwort mehr.
ich habe jetzt mal mein delphi-projekt hochgeladen:
www.basicmotion.de/sonstiges/serialng.zip (3kb)
evt. wird jemandem der fehler klar?!
mfg
Anton
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Di 19.10.04 11:49
Du hast bei deinem Upload die nicht völlig unwesentlichen  .pas Dateien vergessen!
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Di 19.10.04 11:56
Ach so, Du könntest noch mal versuchen CarriageReturn und / oder (mal rumprobieren) LineFeed anzuhängen.
Also:
SerialNg.SendString(StrToSend + #$0d#$0a)
oder
SerialNg.SendString(StrToSend + #$0d)
oder
SerialNg.SendString(StrToSend + #$0a)
|
|
dkx 
      
Beiträge: 36
|
Verfasst: Di 19.10.04 12:57
[url] www.basicmotion.de/s...s/serialng.zip[/url] (ca. 70 kb)
so, jetzt stimmt der link aber.
das mit carriagereturn/linefeed hat leider keine änderung mit sich gebracht.
|
|
SchelmVomElm
      
Beiträge: 154
W2K Pro
D5 Pro
|
Verfasst: Di 19.10.04 14:11
Hm, nu fehlt noch die Formulardatei (.dfm) ...
Aber ich hab noch 'ne andere Idee - kam mir als ich die SerialNG Source mal wieder gesehen habe - da hast Du ein Programm das heißt SerialSpy. Mit dem kann man die Schnittstelle auf dem Rechner durchschleifen und der Rechner protokolliert alles mit
Hier der Kommentar aus der SerialSpy Unit:
Hello folks,
this is the "spy" Demo for the SerialPortNG Component.
This program can listen to two talking separate RS232 Devices.
You need a Windows Computer with 2 working and unused serial Ports (e.g. COM1, COM2)
You need a special Cable, builded by Your own: The Spyadapter.
Simply buy (or find in Your home) one piece of an openable 9pin to 25pin adapter.
Also knowed as serial Mouse adapter. Depending from the listeners computer's capabilities
You need additonally one 9pin and one 25pin or two 9 pin female sub d plugs.
Open the Adapter, proof if the connections are as follow
Signal 9Pin side 25Pin Side
DCD 1 8
RXD 2 3
TXD 3 2
DTR 4 20
GND 5 7
DSR 6 6
RTS 7 4
CTS 8 5
RI 9 22
The signals DCD and RI, are sometimes not implemented!
Now solder as follow (Pin numbers are 9 Pin plugs!)
9 Pin Side 9 Pin plug for the listener computer
TXD 3 RXD 2
GND 5 GND 5
DTR 4 DSR 6
RTS 7 CTS 8
Result: all Out Pins of the 9pin plug are patched to Input pins of the the listener computer
Solder now the opposite plug
25 Pin Side 25 Pin plug for the listener computer
TXD 3 RXD 2
RTS 4 CTS 5
GND 7 GBD 7
DTR 20 DSR 6
Plug the adapter between the link of the observed devices,
and the new solderd plugs into the observer computer.
So now COMX will receive what DEV1 is sending, and COMY receive what DEV2 sends
Additionally You may also use a simple Comporttester (has some blinking lights)
*No warranty* for Your Hardware!!!
Plug the stuff together, start the Programm and opens the Ports.
You will see in the Terminal what the attached devices are sending.
You will see the RTS, DTR Lights changing.
Naja, Du must dir ein Kabel zusammenlöten und brauchst 'nen 2. Rechner, aber dann kannst Du 100%ig sehen was auf der Schnittstelle passiert.
Falls alle Stricke reissen - mir ist nämlich aufgefallen daß ich ein ähnliches Problem auch nicht mit SerialNG lösen konnte... Ich bin damals den API Weg gegangen.
|
|
dkx 
      
Beiträge: 36
|
Verfasst: Di 19.10.04 15:40
Jetzt hab ich den link nochmals upgedated (diesemal ist das ganze serialng-paket drin: 200kb).
Wie du gesehen hast hatte ich schon mit der SerialNGkomponente meine Probleme - von api-programmierung habe ich erst gar keine ahnung/erfahrung... schließlich wurde mir delphi in der schule beigebracht...
|
|