Autor Beitrag
Lago
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43



BeitragVerfasst: Di 03.01.06 13:13 
Ich will Daten über den COM1 empfangen und habe hierzu eine procedure geschrieben. Wenn ich den Button zum ausführen dieser Procedure klicke, dann stürzt das Programm ab, resp macht keinen Wank mehr. Wieso?

Die Procedure sieht so aus:

ausblenden volle Höhe 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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
{Wenn Daten empfangen werden, werden diese hier verarbeitet--------------------}  
procedure TForm1.empfangen;  
var  
i: integer;  
begin  
    with CommPortDriver1 do  
      begin  
         repeat  
            repeat  
            ReadChar(ch);  
            until ch = StartDelimiter;  
         checksum := 27;  
         ReadChar (ch);  
         checksum := checksum + ord (ch);  
         case ch of  
          'Z':  begin  
                n := 16;  
                msgType := 'Position';  
                end;  
          'W':  begin  
                n := 5;  
                msgType := 'Druckknopf';  
                end;  
          'U':  begin  
                n := 1;  
                msgType := 'Zeitabgelaufen';  
                end;  
         end;  
         SetLength (msg, n);  
         for i := 1 to n do  
          begin  
            ReadChar (ch);  
            checksum := checksum + ord (ch);  
            msg [i] := ch;  
            end;  
         ReadChar (ch);  
         until ord (ch) = checksum mod 256;  
      end;  
end;  
{------------------------------------------------------------------------------}



Ich habe ein Programm geschrieben, welches Daten sendet... und das funktioniert. (Mit Teraterm getestet).

Es könnte auch sein das er sich an der Repeat-Schleife aufhängt... Aber wie wird das normal erledigt mit dem Empfangen der Daten? Verwendet man da eine bestimmte Vorgehensweise?

Danke jetzt schon,

Pascal
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Di 03.01.06 13:26 
Was passiert denn wenn die folgende Repeat-Anweisung nie verlassen wird weil zum Beispiel das Startzeichen einfach nicht kommt?
ausblenden Delphi-Quelltext
1:
2:
3:
repeat
  ReadChar(ch);
until ch = StartDelimiter;

_________________
Ein Nutzer der Ecke ;-)
matze.de
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 576

Win95, Win98 SE, WinXp Prof SP2
D7P, D8P, FPC2.0
BeitragVerfasst: Di 03.01.06 13:29 
user profile iconMartin1966 hat folgendes geschrieben:
Was passiert denn wenn die folgende Repeat-Anweisung nie verlassen wird weil zum Beispiel das Startzeichen einfach nicht kommt?
ausblenden Delphi-Quelltext
1:
2:
3:
repeat
  ReadChar(ch);
until ch = StartDelimiter;


Ja, geb ich dir auch recht :) Könntest du ja einen Timeout einbauen.

mfg matze

_________________
si tacuisses, philosophus mansisses.
Lago Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43



BeitragVerfasst: Di 03.01.06 14:13 
Ich habe anstelle dieses Programms TeraTerm laufen gelassen... Da wird ja angezeigt, was über die RS232 empfangen wird.
Es wird alles richtig Empfangen, d.h. auch mein Programm sollte dieses Startzeichen bekommen....

Wie müsste ich dieses Timeout einbauen?

Mein Programm sollte permanent Daten empfangen... (Dient als Schnittstelle zwischen meinem Schachcomputer und dem Brett)


www.hsr-chess-05.ch.vu
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Di 03.01.06 14:31 
Aber irgendwie willst du doch das Problem lösen, oder? Das geht jedenfalls nicht wenn man immer davon ausgeht, dass alles klappen "sollte".

Also, am besten gehest du einfach davon aus, dass jede Zeile einen Fehler verursachen kann oder einfach anders läuft als Du denkst.

Die von mir gepostete Sourcecode-Stelle war halt das erste was mir auffiel.

Gibt die Funktion ReadChar ein Funktionergebnis zurück welches du eventl auswerten kannst?

Lg Martin

_________________
Ein Nutzer der Ecke ;-)
Lago Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43



BeitragVerfasst: Mi 04.01.06 10:47 
Ich habe jetzt einer meiner vielen Fehler erkannt...

Die funktion ReadChar() gibt mir nicht einen Buchstaben zurück, sondern ein True oder False...

Wenn ich jetzt also diese Procedure schreibe:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.empfangen2;
var ch: boolean;
    C: char;
begin
C:= 'Q';
  repeat
  ch:= CommPortDriver1.ReadChar(C)
  until ch = true;
end;


und dann ein 'Q' sende... dann geht es wieder...

Nun stellt sich eine ganz andere Frage... Gibt es überhaut eine möglichkeit einen Buchstaben zu lesen? Wenn ja, wie heisst die Procedure?
Habe alle möglichkeiten einmal angeschaut...Für mich nur Bahnhof.

Kennt sich jemand mit der TCommPortDriver-Komponente aus?
Lago Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43



BeitragVerfasst: Mi 04.01.06 11:10 
Ich erlaube mir noch die Procedures/Functions/dieser Komponente zu Posten:
ausblenden volle Höhe 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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
// Sets the COM port handle
    procedure SetHandle( Value: HFILE );
    // Selects the COM port to use
    procedure SetPort( Value: TPortNumber );
    // Sets the port name
    procedure SetPortName( Value: string );
    // Selects the baud rate
    procedure SetBaudRate( Value: TBaudRate );
    // Selects the baud rate ( actual baud rate value )
    procedure SetBaudRateValue( Value: DWORD );
    // Selects the number of data bits
    procedure SetDataBits( Value: TDataBits );
    // Selects the number of stop bits 
    procedure SetStopBits( Value: TStopBits );
    // Selects the kind of parity
    procedure SetParity( Value: TParity );
    // Selects the kind of hardware flow control 
    procedure SetHwFlowControl( Value: THwFlowControl );
    // Selects the kind of software flow control 
    procedure SetSwFlowControl( Value: TSwFlowControl );
    // Sets the RX buffer size 
    procedure SetInBufSize( Value: DWORD );
    // Sets the TX buffer size 
    procedure SetOutBufSize( Value: DWORD );
    // Sets the size of incoming packets 
    procedure SetPacketSize( Value: smallint );
    // Sets the timeout for incoming packets
    procedure SetPacketTimeout( Value: integer );
    // Sets the delay between polling checks 
    procedure SetPollingDelay( Value: word );
    // Applies current settings to open COM port 
    function ApplyCOMSettings: boolean;
    // Polling proc 
    procedure TimerWndProc( var msg: TMessage );
  public
    // Constructor 
    constructor Create( AOwner: TComponent ); override;
    // Destructor 
    destructor Destroy; override;

    // Opens the COM port and takes of it. Returns false if something
    // goes wrong.
    function Connect: boolean;
    // Closes the COM port and releases control of it
    procedure Disconnect;
    // Returns true if COM port has been opened
    function Connected: boolean;
    // Returns the current state of CTS, DSR, RING and RLSD (CD) lines.
    // The function fails if the hardware does not support the control-register
    // values (that is, returned set is always empty).
    function GetLineStatus: TLineStatusSet;
    // Returns true if polling has not been paused 
    function IsPolling: boolean;
    // Pauses polling 
    procedure PausePolling;
    // Re-starts polling (after pause) 
    procedure ContinuePolling;
    // Flushes the rx/tx buffers
    function FlushBuffers( inBuf, outBuf: boolean ): boolean;
    // Returns number of received bytes in the RX buffer 
    function CountRX: integer;
    // Returns the output buffer free space or 65535 if not connected 
    function OutFreeSpace: word;
    // Sends binary data 
    function SendData( DataPtr: pointer; DataSize: DWORD ): DWORD;
    // Sends binary data. Returns number of bytes sent. Timeout overrides
    // the value specifiend in the OutputTimeout property
    function SendDataEx( DataPtr: pchar; DataSize, Timeout: DWORD ): DWORD;
    // Sends a byte. Returns true if the byte has been sent
    function SendByte( Value: byte ): boolean;
    // Sends a char. Returns true if the char has been sent
    function SendChar( Value: char ): boolean;
    // Sends a pascal string (NULL terminated if $H+ (default))
    function SendString( s: string ): boolean;
    // Sends a C-style strings (NULL terminated) 
    function SendZString( s: pchar ): boolean;
    // Reads binary data. Returns number of bytes read 
    function ReadData( DataPtr: pchar; MaxDataSize: DWORD ): DWORD;
    // Reads a byte. Returns true if the byte has been read 
    function ReadByte( var Value: byte ): boolean;
    // Reads a char. Returns true if char has been read 
    function ReadChar( var Value: char ): boolean;
    // Set DTR line high (onOff=TRUE) or low (onOff=FALSE).
    // You must not use HW handshaking.
    procedure ToggleDTR( onOff: boolean );
    // Set RTS line high (onOff=TRUE) or low (onOff=FALSE).
    // You must not use HW handshaking.
    procedure ToggleRTS( onOff: boolean );

    // Make the Handle of the COM port public (for TAPI...) [read/write]
    property Handle: HFILE read FHandle write SetHandle;
  published
    // # of the COM Port to use ( or pnCustom for port by name )
    property Port: TPortNumber read FPort write SetPort default pnCOM2;
    // Name of COM port
    property PortName: string read FPortName write SetPortName;
    // Speed ( Baud Rate )
    property BaudRate: TBaudRate read FBaudRate write SetBaudRate default br9600;
    // Speed ( Actual Baud Rate value )
    property BaudRateValue: DWORD read FBaudRateValue write SetBaudRateValue default 9600;
    // Data bits to use (5..8, for the 8250 the use of 5 data bits with 2 stop
    // bits is an invalid combination, as is 6, 7, or 8 data bits with 1.5 stop
    // bits)
    property DataBits: TDataBits read FDataBits write SetDataBits default db8BITS;
    // Stop bits to use (1, 1.5, 2)
    property StopBits: TStopBits read FStopBits write SetStopBits default sb1BITS;
    // Kind of Parity to use (none,odd,even,mark,space)
    property Parity: TParity read FParity write SetParity default ptNONE;
    // Kind of Hardware Flow Control to use:
    //   hfNONE          none
    //   hfNONERTSON     no flow control but keep RTS line on
    //   hfRTSCTS        Request-To-Send/Clear-To-Send
    property HwFlow: THwFlowControl read FHwFlow write SetHwFlowControl default hfNONERTSON;
    // Kind of Software Flow Control to use:
    //   sfNONE          none
    //   sfXONXOFF       XON/XOFF 
    property SwFlow: TSwFlowControl read FSwFlow write SetSwFlowControl default sfNONE;
    // Input Buffer size ( suggested - driver might ignore this setting ! )
    property InBufSize: DWORD read FInBufSize write SetInBufSize default 2048;
    // Output Buffer size ( suggested - driver usually ignores this setting ! )
    property OutBufSize: DWORD read FOutBufSize write SetOutBufSize default 2048;
    // RX packet size ( this value must be less than InBufSize )
    // A value <= 0 means "no packet mode" ( i.e. standard mode enabled )
    property PacketSize: smallint read FPacketSize write SetPacketSize default -1;
    // Timeout (ms) for a complete packet (in RX) 
    property PacketTimeout: integer read FPacketTimeout write SetPacketTimeout default -1;
    // What to do with incomplete packets (in RX)
    property PacketMode: TPacketMode read FPacketMode write FPacketMode default pmDiscard;
    // ms of delay between COM port pollings  
    property PollingDelay: word read FPollingDelay write SetPollingDelay default 50;
    // Set to TRUE to enable DTR line on connect and to leave it on until disconnect.
    // Set to FALSE to disable DTR line on connect. 
    property EnableDTROnOpen: boolean read FEnableDTROnOpen write FEnableDTROnOpen default true;
    // Output timeout (milliseconds)
    property OutputTimeout: word read FOutputTimeOut write FOutputTimeout default 500;
    // Input timeout (milliseconds)
    property InputTimeout: DWORD read FInputTimeOut write FInputTimeout default 200;
    // Set to TRUE to prevent hangs when no device connected or device is OFF
    property CheckLineStatus: boolean read FCkLineStatus write FCkLineStatus default false;
    // Event to raise when there is data available (input buffer has data)
    // (called only if PacketSize <= 0)
    property OnReceiveData: TReceiveDataEvent read FOnReceiveData write FOnReceiveData;
    // Event to raise when there is data packet available (called only if PacketSize > 0)
    property OnReceivePacket: TReceivePacketEvent read FOnReceivePacket write FOnReceivePacket;
  end;

function BaudRateOf( bRate: TBaudRate ): DWORD;
function DelayForRX( bRate: TBaudRate; DataSize: DWORD ): DWORD;


Readchar ist z.b. schon gut und recht... dann kann er aber nur einen bestimmten Char lesen... und gibt ein True zurück, wenn er diesen findt...

Ich will jedoch, dass er nach meinem Startdelimiter alle Char liest... und diese mir dann ausgibt.. Bin ja wohl nicht der erste, der das so machen will, oder? :-)
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Mi 04.01.06 11:31 
user profile iconLago hat folgendes geschrieben:
Gibt es überhaut eine möglichkeit einen Buchstaben zu lesen? Wenn ja, wie heisst die Procedure?

Äh? Das musst du doch wissen. Schließlich benutzt du schon so eine Funktion. -> ReadChar.

user profile iconLago hat folgendes geschrieben:
Ich will jedoch, dass er nach meinem Startdelimiter alle Char liest... und diese mir dann ausgibt..

Dafür wird es wohl nicht schon eine Funktion geben. Aber was ist denn mit dem Code den du schon geposetet hast? Dieser Code soll doch genau das machen. Erst nach einem bestimmten Zeichen suchen und ab dann die restlichen Zeichen ausgeben. Warum willst du jetzt etwas anderes benutzen als deinen Code?

Lg Martin

_________________
Ein Nutzer der Ecke ;-)
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Mi 04.01.06 11:31 
Hallo,

readchar liest doch einen Buchstaben.
// Reads a char. Returns true if char has been read
function ReadChar( var Value: char ): boolean;

Die Funktion gibt aber nur ein geaendertes Zeichen zurueck, wenn auch tatsaechlich etwas neues gekommen ist oder noch nicht aus dem Puffer gelesen wurde.
Du solltest OnReceiveData benutzen.
Wenn Daten kommen dann kannst Du diese einlesen und verarbeiten.
Sonst schlafen....

Gruss Horst
Lago Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43



BeitragVerfasst: Mi 04.01.06 11:39 
Guten Morgen Martin... Der Retter... ;-)


Das Problem ist, dass ich mit Readchar gemeint habe das einfach der nächste Char gelesenwird...

Es ist aber so, dass wenn ich ReadChar ausführe... dann wird nach einem bestimmten Char gesucht... und
sobald er diesen findet, läuft das Programm weiter.

Was in meinem Programm der Fall ist... jeder Startdelimiter ist der selbe... Was nachher kommt, weiss ich nicht.

Ich kann doch nicht jedes mal, jeden Buchstaben abfragen.... manchmal sind es 4Buchstaben die kommen.. manchmal 7..
Lago Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43



BeitragVerfasst: Mi 04.01.06 11:42 
Reads a char... Ja.. hmm.. OnRecieveData... ja....

Dann stimmt ja mein Programm trozdem... wenn ja ein Char gelesen wurde.. aber wieso liest er dann keinen?
Ich muss immer nach einem bestimmten Char suchen, damit das Programm wieder weiter läuft.

Probiere es gleich einmal aus.... Danke jetzt schon...
Lago Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43



BeitragVerfasst: Mi 04.01.06 12:14 
Mit OnRecieveData könnte es klappen... Habe einfache Abfragen gemacht... sieht soweit I.O. aus.

Danke!