Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi An com port gesendete daten lesen (https://www.delphipraxis.net/148540-com-port-gesendete-daten-lesen.html)

schweindi 3. Mär 2010 22:50


An com port gesendete daten lesen
 
Hallo alle,
wir verwenden eine SMS Notification software, die Broadcasts und Notifications per sms an alle Beützer versendet.
Das funktioniert so:
1) Ein ASP.NET Portal & SQL Datenbank ermöglichen die Eingabe von Benachrichtigungen und Nummern der Empfänger
2) Diese Daten werden von einer SMSServerRuntime in gsm befehle umgewandelt
3) Diese werden an COM1 geschickt, wobei COM1 ein USBModem ist, in dem sich die SIM Karte befindet, die dann letztendlich die SMS versendet.

Seitdem wir einen Modemwechsel durchgeführt haben, streikt die Software natürlich und nun ist es an mir, herauszufinden warum.
Gleich vorweg, ich arbeite mit dem Hersteller der SMSSoftware zusammen, doch er will/kann mir nicht die Sourcecodes geben, aber er arbeitet schon an einem Patch.
Ich dachte mir so als Herausforderung, versuche ich ein Delphi Programm zu schreiebn, dass mir bei der Suche nach dem Fehler bisschen hilft, doch leider bin ich in meinen Überlegungen nicht zu mehr gekommen als:
1) Man könnte einen Port emulieren und auslesen welche Befehle er zu gesendet bekommt.
2) Mann könnte die Befehle direkt von Port/ Software lesen.

Ich denke Möglichkeit 1) ist seeehr viel schwerer, deshalb denke ich an 2).
Ich weiß ja, welche Befehle das Modem eig. bekommen sollte:

at+cpin? +CPIN:READY
at+csca=xxx OK
at+cmgs="xx",xxx +CMGS:(Index)
at+cmsp=xx,xx,xx,xx OK
(Command : Response)

Das sind die GSM Befehle die ich erwarte. Da ich per Hyperterminal ja die SIM einwandfrei steuern kann und auch sms verschicken kann, denke ich der Fehler liegt genau bei der Schnittstelle Software/COM Anschluss.

Hat jemand eine Idee, wie ich die gesendeten Befehle auslesen kann?? Ich habe ja schon Bedenken, da der Anschluss nur von einem Programm gleichzeitig verwendet werden kann, aber vielleicht liege ich ja auch ganz falsch.

Bin gespannt, ob jemand eine gute Idee hat.
lg

s.h.a.r.k 3. Mär 2010 23:14

Re: An com port gesendete daten lesen
 
Warum schließt du nicht an Stelle des Modems einen anderen Rechner an den bisherigen an und liest so die ankommenden Werte? Ich kenne aber das Protokoll nicht und daher kann ich dir auch nicht sagen, ob du evtl. ankommende Nachrichten beantworten musst (ACK oder sowas). Aber ein Versuch ist es wert :) btw: das COM-Kabel muss natürlich gekreuzt sein!

schweindi 3. Mär 2010 23:56

Re: An com port gesendete daten lesen
 
also vielleicht ist das nicht so klar rausgekommen :)

Die SMS Software unterstützt als Modemlocation nur COM1-5 und ich habe das USB Modem am Anschluss COM1 eingerichtet... also softwaremäßig, damit das ganze läuft. Deshalb ist das alles bisschen komplizierter für mich :)

s.h.a.r.k 4. Mär 2010 00:01

Re: An com port gesendete daten lesen
 
Hä? Ich verstehe wohl immer noch nicht ganz :gruebel: Das hier ist doch der aktuelle Stand:
Code:
+-----------+     COM1
| Rechner B | <------------> GSM-Modem
+-----------+
Richtig soweit?

Was spricht gegen sowas?
Code:
+-----------+      COM1      +-----------+
| Rechner A | <------------> | Rechner B |
+-----------+                +-----------+
Oder folgendes

Code:
+-----------+     COM1
| Rechner B | <-----+------> GSM-Modem
+-----------+       |
                    |        +-----------+
                    +------> | Rechner B |
                             +-----------+

schweindi 4. Mär 2010 07:00

Re: An com port gesendete daten lesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
hmm... okay also vielleicht wirds klarer:

Modem -> USB Slot
In windows Settings: Modems -> Advanced Port Settings. Dort in dem drop down menu einfach den 'COM1' ausgewählt. (Siehe Anhang)

Deshalb hab ich eigentlich keinen "Hardware COM1" Anschluss, da es ja über usb geht- oder versteh ich da was falsch?

jfheins 4. Mär 2010 07:08

Re: An com port gesendete daten lesen
 
Naja, du hast einen virtuellen Comport, der wahrscheinlich direkt an den Mikrocontroller geht der an der SIM-Karte hockt. Das ist ein übliches Vorgehen, weil die meisten Mikrocontroller kein USB haben, aber RS232 - also wird ein Bauteil zwischengeschaltet und ein COM-Port über USB bereitgestellt. (es gibt dabei also keinen "COM-Port-Stecker" sondern nur ein paar Leiterbahnen auf der Platine, die diese serielle Verbindung herstellen)

Mein Ansatz wäre folgender (zugegebenermaßen langweiliger als den COM-Port abfangen): Lies die Doku durch die hoffentlich bei beiden Modems dabei war ;)
(oder guck, ob beide Hersteller sowas wie ein SDK haben, oder ein Beispiel um über ihr Modem eine SMS zu versenden)

schweindi 4. Mär 2010 09:13

Re: An com port gesendete daten lesen
 
ja, also ich weiß welche Befehle am Modem funktionieren und genau die Befehle von der SMSSoftware sind ja das Problem... deswegen "spannend" den Port auslesen :)

Leider hab ich von dem Anbieter noch keine Infos bekommen, welche Befehle gesendet werden und in welchem Format genau (Pud/Text mode).

Da das ganze schnell gelöst werden sollte, dachte ich so könnte das schnell gehen...

LargoD 4. Mär 2010 11:38

Re: An com port gesendete daten lesen
 
Du brauchst da nichts selbst zu schreiben, google einfach mal nach 'com port monitor' oder 'serial port monitor'. Es gibt da einige Programme, die Dir den Datenverkehr zeitlich korreliert in beide Richtungen anzeigen (auch für virtuelle Ports), und die Daten trotzdem zur Anwendung durchlassen. Teilweise Shareware, teilweise Freeware.
Gruß
Erich

schweindi 4. Mär 2010 13:47

Re: An com port gesendete daten lesen
 
ah super danke.. ich habe zwar gegoogelt, aber erst jetzt was gefunden!

Danke sehr...

//erledigt :) - Doch nicht!

Will da gleich weiterarbeiten:

Hab mir ein Com Monitor runtergeladen und sehe jetzt genau was das Programm sendet... ich möchte jetzt einmal selber eines schreiben, dass diese Befehle sendet, genau wie zb Hyperterminal.

Dazu hab ich schon mal von S.h.a.r.k das verwendet und bisschen umgeschrieben:

Delphi-Quellcode:
unit com_bridge;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Button3: TButton;
    Button4: TButton;
    Edit2: TEdit;
    Label2: TLabel;
    Button5: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
  private
    { Private declarations }
    procedure ConnectToCOMPort(Disconnect: Boolean);
    function ReadDataFromCom(lange:Integer):string;
    function WriteDataToCOMPort(Text: String): Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
//Anschluss
ComHandle : THandle;
comport:string;

implementation

{$R *.dfm}

procedure TForm1.ConnectToCOMPort(Disconnect: Boolean);
var
DCB : TDCB;
TimeOut : TCommTimeouts;
i : Integer;
begin
  { Wenn die Verbindung wieder getrennt werden soll }
  if (Disconnect) then
  begin
  FileClose(ComHandle);
  ComHandle := 0;
  exit;
  end else
{ Die Verbindung zum COM-Port wird hergestellt - wenn dies nicht
funktioniert
wird es bis zu zehn Mal probiert }
  begin
  COMPort:=Edit1.Text; //Com-Ports beginnen bei Com1, Com2, Com3...
  i := 0;
  while (ComHandle <= 0) and (i < 10) do
  begin
  ComHandle := CreateFile(pchar(COMPort), GENERIC_READ or
  GENERIC_WRITE,0, nil, OPEN_EXISTING, 0, 0);
  inc(i);
  end;
{ Einstellungen zum COM-Port zuweisen, wenn die Verbindung aktiv
ist }
if (ComHandle > 0) then
begin
DCB.DCBlength := SizeOf(DCB);
DCB.ByteSize := 8;
DCB.Parity := NoParity;
DCB.StopBits := ONESTOPBIT;
DCB.BaudRate := 9600;
{
DCB.Flags := 5123; // Wenn 2 Pins belegt sind
DCB.EofChar := #0;
DCB.ErrorChar := #0;
DCB.EvtChar := #0;
DCB.XoffChar := #0;
DCB.XoffLim := 0;
DCB.XonChar := #0;
DCB.XonLim := 0;
}
SetCommState(ComHandle, DCB);
GetCommTimeOuts(ComHandle, TimeOut);
TimeOut.ReadIntervalTimeOut := 100;
TimeOut.ReadTotalTimeoutMultiplier := 0;
TimeOut.ReadTotalTimeoutConstant := 250;
TimeOut.WriteTotalTimeoutMultiplier := 0;
TimeOut.WriteTotalTimeoutConstant := 200;
SetCommTimeouts(ComHandle, TimeOut);
end;
end;
end;

function TForm1.WriteDataToCOMPort(Text: String): Boolean;
var
i,k : integer;
str:string;
begin
{ Senden der Daten an den COM-Port - mit Ausgabe ob der Befehl
erfolgreich war }
i:=FileWrite(ComHandle, Text[1], Length(Text));
ShowMessage(str);
if (i <> Length(Text)) then
Result := False
else
Result := True;
end;

function TForm1.ReadDataFromCom(lange:Integer):string;
var n:string;
begin
FileRead(ComHandle,n,lange);
ShowMessage(n);
Result:=n;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Application.Terminate;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ConnectToComPort(false);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
ConnectToComPort(True);
ShowMessage('Disconnected from '+Edit1.Text);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
WriteDataToComPort(Edit2.Text);
ShowMessage('Write Data Successfull');
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
ReadDataFromCom(length(Edit2.Text))
end;

end.
so nun das schicken hab ich per virtual serial port schon überprüft, das funktioniert.
Wenn ich aber in hyperterminal mir das anschaue, sehe ich dass irgendwie ein 'Zeilenumbruch' noch gesendet wird, was ist das für ein Befehl?

im monitor siehts so aus:

Log # / Zeit / Programm / Befehl / Port / Status / Details
...
16 15:36:28 SMSServer IRP_MJ_READ USBER000 TIMEOUT Length 16: AT+CMGF=0...OK..
17 15:36:28 SMSServer IRP_MJ_WRITE USBER000 SUCCESS Length 11: AT+CMGF=0...
18 15:36:28 SMSServer IRP_MJ_FLUSH_BUFFERS USBER000 SUCCESS
...

also dieser "Success" Befehl, den sollte ich auch iwie schicken können, aber das wichtigste ist nun, wie "lese" ich die Antworten vom Modem??

Mein ReadDataFromCom() geht leider nicht, da kommt ein leerer String, wenn ich 2-10 Zeichen Lesen lasse.
Wie sollte das genau gehen?

schweindi 5. Mär 2010 10:20

Re: An com port gesendete daten lesen
 
muss ich überhaupt extra die Antworten des Modems abwarten und ausgeben, oder geht das iwie automatisch, also als eine Art "echo"?

Wenn man es extra abfragen muss, wäre eine while schleife dafür geeignet?

Delphi-Quellcode:
var input: string;
    NumberOfBytesRead : dword;
    Buffer           : array[0..255] of char;

begin
ReadFile(hCommFile, Buffer, sizeof(Buffer), NumberOfBytesRead, nil);

//Buffer -> input?

while input <> '' do#
  begin
//irgendetwas
  end;
ich hab irgendwo gelesen, dass einer diese Wartezeit, bis das Modem antwortet, zwar geschafft hat zu verarbeiten aber dauerhaft CPU auf 100%, was bei mir nicht sein darf, da noch andere Programme laufen müssen.

Oder gibt es ein Event im Sinne von "Nachricht erhalten"?

Und noch eine kleine Erklärung von ReadFile() wäre ganz super.

ReadFile( (COMPort Handle) , (die Variable die den gelesene String bekommt) , ?? , ?? , (wieso nil?) );

muss ein Array of char oder string verwendet werden als input variable?

LargoD 5. Mär 2010 11:26

Re: An com port gesendete daten lesen
 
Um com-ports anzusteuern benutze ich immer TComPort von Dejan Crnila.
Da sind auch Beispiele im Paket, die Du leicht modifiziert direkt einsetzen kannst.
Auf die Antwort des Modems wartest Du nicht, sondern wenn Zeichen auf der seriellen Schnittstelle ankommen, wird ein Event ausgelöst und die Zeichen kannst Du aus einem Puffer abholen. TComPort hat sogar eine einfache Paket-Erkennung, sodass dann ein Event getriggert wird, wenn eine bestimmte Zeichenkombination, z. B. CR/LF erkannt wird. Das macht die Sache noch einfacher.
Gruß
Erich

s.h.a.r.k 5. Mär 2010 14:56

Re: An com port gesendete daten lesen
 
Zitat:

Zitat von schweindi
Dazu hab ich schon mal von S.h.a.r.k das verwendet und bisschen umgeschrieben:

Das ist gar nicht direkt von mir, auch wenn ich mehrfach zitiert werde für diesen Code :mrgreen: hatte da echt eine nette Hilfe (Dirk Meyer hieß der Herr glaub), mit der ich den Code erarbeitet hatte!

schweindi 5. Mär 2010 16:19

Re: An com port gesendete daten lesen
 
okay ... danke :) Ich versuch mal TComPort und melde dann evtl Fehler!

und ja, ich hab dich einfach mal weiterzitiert ;)

schweindi 5. Mär 2010 19:14

Re: An com port gesendete daten lesen
 
okay ich habe jetzt mal TComPort installiert und alles verwendet... also es läuft super, nur beim auslesen hab ich noch probleme:

Also wenn ich

ComPort1.ReadFile(str,255);

mache dann wird ja immer nur 1 zeichen gelesen -> ComDataPacket, stimmt doch oder damit kann man es als "ganzes Packet" lesen?
So dann hab ich start parameter leer gelassen und als Stopparam ist #13, da das Modem ja nach jedem befehl eine neue zeile beginnt...

Doch iwie wenn ich jetzt in meinem virtual com nach dem befehl vom programm etwas eingeben, passiert nichts. Vorher habe ich in meinem Memo immer jeden Buchstaben einzeln gesehen, doch jetzt passiert garnichts, was habe ich vergessen?

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject); //da sende ich die Eingabe zum port
var Str : String;
    i : Integer;
begin
//write to port
Str := Edit2.Text;
//ComPort1.WriteStr(Str); // string type variable
ComPort1.Write(Str[1], Length(Str)); // no defined type
ComPort1.TransmitChar(#13);
ShowMessage('Write Data Successfull');
//answer
end;
und so sieht mein Packetding aus:

[delphi]object ComDataPacket1: TComDataPacket
ComPort = ComPort1
StopString = '#13'
OnPacket = ComDataPacket1Packet
Left = 48
Top = 200
end
end[/delpi]

das OnPacket Event gibt ja an, wenn ein vollständiges packet gefunden wurde, da hab ich einfach mal ein ShoMessage() reingeschrieben, doch nichts passiert! Wenn ich zb: "abc#13" eingebe im Modem, tut mein programm so, als ob es nichts im InputBuffer hätte.

Ne idee?

Matczek 5. Mär 2010 19:31

Re: An com port gesendete daten lesen
 
versuche mal #13 (CR) und #10 (LF) zu senden...
Ich glaube, dass sind die Endezeichen für Modems.

gruß matthias

schweindi 5. Mär 2010 19:37

Re: An com port gesendete daten lesen
 
naja mein Problem ist ja, dass die Pakete garnicht erkannt werden.

Ich habe ja beim Startparameter nichts eingetragen, das heißt, es muss bei jedem zeichen beginnen zu lesen und stopparameter ist #13 dh wenn ich #13 eingebe müsste es fertig gelesen haben.

Matczek 5. Mär 2010 19:56

Re: An com port gesendete daten lesen
 
Also ich kenne die TComPort Komponente nicht ich benutze immer AsyncPro. Dort hatte ich immer Probleme mit dem Packet-Komponente, deswegen schreibe ich die Werte immer in einen Buffer und werte selbst aus.

Habe ich das richtig verstanden du sendest z.B. "AT"+CR und bekommst keine Antwort vom Modem?

schweindi 5. Mär 2010 20:01

Re: An com port gesendete daten lesen
 
naja ich teste das programm gerade nur auf einem virtuellen modem, indem ich di eigentlichen antworten slbr reinschreibe... aberich bekomme eben diese nicht

Matczek 5. Mär 2010 20:05

Re: An com port gesendete daten lesen
 
[edit]Sorry ich sollte mal richtig lesen[/edit]

Was ist ein virtuelles Modem? Ein Modem der einen virtuellen COM Port via USB anbietet?

WoGe 5. Mär 2010 20:16

Re: An com port gesendete daten lesen
 
Zitat:

Zitat von Matczek
Sorry noch ne doofe Frage:
Was ist das für ein Gerät welches an den virtuelle COM Port angeschlossen ist?

Würde mich auch mal interessieren

Wenn es nur darum geht SMS zu verschicken, kann man auch ein ganz normales Handy mit Bluetooth nehmen. Hab ich mit meinem Uralt-Handy mal ausprobiert und ging einwandfrei. Hat zudem den Vorteil keinerlei Kabel zwischen Rechner und Handy notwendig.

Gruss
wo

schweindi 5. Mär 2010 20:19

Re: An com port gesendete daten lesen
 
es ist ein Nokia CS-15 usb umts modem, umts deswegen, weil unser Provider nur auf umts basis funktioniert.
Und es muss so über einen COM Port gehen, da die software leider veraltet ist.

Also von den Befehlen her:

At ... OK
at+cpin? ... +CPIN: Ready

usw... ganz einfaches gsm modem, es geht mir nur darum:

mit ComPort1.ReadStr(string,255) bekomme ich nur den jeweils ersten Buchstaben, ich will aber immer das ganze packet haben, wie kann man das einfach machen? Ich dachte nur wenn ich schon diese Paketoption habe, verwende ich sie doch gleich...

Virtuelles Modem:
Ein Programm, dass einen Com Anschluss simuliert und ausgibt, welche Befehle versendet & empfangen werden. Es ist halt einfacher so mein Programm auf Fehler zu prüfen.

Matczek 5. Mär 2010 20:25

Re: An com port gesendete daten lesen
 
Zitat:

Zitat von WoGe
... kann man auch ein ganz normales Handy mit Bluetooth nehmen. Hab ich mit meinem Uralt-Handy mal ausprobiert und ging einwandfrei. Hat zudem den Vorteil keinerlei Kabel zwischen Rechner und Handy notwendig.

Wenn man aber sowas wie (wichtige) Ausfälle via SMS melden muss sollte man sicherhaltshalber verdrahte GSM-Modems nehmen. Diese Verbindung bricht nur äusserst selten ab ;-)

Matczek 5. Mär 2010 20:30

Re: An com port gesendete daten lesen
 
[edit]okay okay ich lese bald richtig ich verspreche es!![/edit]

Da wird dir jemand mit TCOMPort Erfahrung weiterhelfen müssen.

gruss
Matthias

schweindi 5. Mär 2010 20:36

Re: An com port gesendete daten lesen
 
ja... :) viel glück dabei noch ^^

Ich will ja eigentlich nur wissen, wie ich die Echos vom Modem ausgeben kann in meinem Programm? Wie schon erwähnt verwende ich TComPort und das Paketobjekt funzt nicht bei mir.

Matczek 5. Mär 2010 21:14

Re: An com port gesendete daten lesen
 
Trage in deiner *.dfm vom Packet mal folgendes ein
Delphi-Quellcode:
StopString = #13
und nicht wie du geschrieben hattest
Delphi-Quellcode:
StopString = '#13'
Bei deinem wartet er auf den String "#13" beim anderen auf den Char #13 (CR)

gruss matthias

schweindi 5. Mär 2010 21:40

Re: An com port gesendete daten lesen
 
wunderbar!
ich dachte eig, wenn ich es im Object Inspector bei den Einstellungen einfüge, wird es eh als char gespeichert, naja dem war nicht so.

Gut jetzt hab ich auch gleich Start: #10 Stop: #13 eingefügt, das geht super.. jetzt noch die entscheidende Frage (ich komm mir echt schon doof vor): wo wird der String gespeicher??

Ich hab grad in Help gesucht, da wird nirgends eine methode zum auslesen bzw variable zum Speichern erwähnt!

schweindi 5. Mär 2010 22:15

Re: An com port gesendete daten lesen
 
ah ich habs gefunden:

Delphi-Quellcode:
procedure TForm1.ComDataPacket1Packet(Sender: TObject; const Str: String); //da ist es ja, das str!
begin
ShowMessage(str);
end;
wenn ich das so ausführe und im terminalfenster vom virtual com port das eingebe:
#10
OK
#13

(wäre ja standard antwort auf "AT") dann kommt eine eher größere MsgBox wo aber nichts drin steht!

Matczek 6. Mär 2010 09:23

Re: An com port gesendete daten lesen
 
ich hoffe du hast nicht "#10" eingegeben sonden einfach "AT"+<Enter> gedrückt!
Ersteres ist wieder der String "#10" und nicht das Steuerzeichen LF

bzgl der großen msgbox: schau dir mal "trim" an

Gruß
Matthias

schweindi 6. Mär 2010 11:42

Re: An com port gesendete daten lesen
 
nei, nein :) habe natürlich enter gedrückt!
Ich meinte: In meinem programm schreibe ich "at" und dann steht im Terinalfenster vom VirtualPort:
"Recieved: at" dann schreibe ich halt "ok+(enter)" und er erfasst zwar im delphi programm, dass sozusagen das packet aus ist, aber er zeigt mir nur ein leeres Fenster an, das je nach größe des ReadBuffers groß ist. Also er gibt mir den String nicht aus!

[EDIT] ich habe trim verwendet auf den String der in der MsgBox gezeigt wird und ja, die größe bleibt immer gleich, aber er zeigt keine buchstaben an... also so als ob die Packet Procedure von Tcomport falsch wäre... also ka was genau da noch falsch sein kann.[/edit]

schweindi 6. Mär 2010 12:37

Re: An com port gesendete daten lesen
 
so hab jetzt mal was überprüft:

1) Die Länge des output strings von TComDataPacket ist unterscheidlich, dh es werden Leerzeichen sozusagen "gelesen"
2) Ich hab den "Buffer" mal nach einer Eingabe des "Modems" ausgelesen:
Delphi-Quellcode:
//----
var str2 : TComBuffer;
begin
str2:=ComPort1.Buffer;
ShowMessage(Char(str2));
end;
das gibt nach jeder Ausgabe das Zeichen "é" aus... wieso??

vielleicht half das ja etwas weiter!?

LargoD 6. Mär 2010 14:35

Re: An com port gesendete daten lesen
 
Hast Du Dir mal angesehen, was TCOmBuffer für ein Typ ist? Das ist kein String!
Bitte benutze die entsprechenden Events und sieh Dir den übergebenen String an, notfalls mal einen Breakpoint in den Eventhandler setzen und dann einfach mit dem Mauszeiger auf den übergebenen String zeigen, und schon siehst Du, was angekommen ist.

Ich verstehe noch nicht, wieso Du einmal den String an das Modem (at<CR>) und dann die erwartete Antwort vom Modem (ok<CR><LF>) im selben Terminalfenster tippen kannst. Was du nach dem Tippen von ok<CR><LF> empfängst ist doch mMn die Antwort des Modems auf dieses (sinnlose) Kommando (ok<CR><LF>), oder?
Gruß
Erich

schweindi 6. Mär 2010 17:51

Re: An com port gesendete daten lesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
also... danke für den Hinweis jetzt seh ich der String ist: #0 hmm.. toll hätte "ok" sein sollen.
Das lesen von Paketen klappt also noch nicht so ganz.

Das mim Terminalfenster:
Folgende Prozedur:
1) In meinem Programm tippe ich bei Befehl senden: "at" ein (als wäre es ein gsm modem)
2) Im Modememulator (siehe screen) sehe ich, was angekommen ist und antworte, als wäre ich das Modem mit "ok"+#13
3) jetzt müsste in meinem Programm das Event (RxChar) ausgelöst werden, was es auch tut, leider ist der gelesene String: #0 und nicht "ok"

kennst du TComPort? Bzw die Komponente TComDataPacket? Da soll angeblich folgendes machen:
(Helpfile von TComPort)
"When application is connected to some sort of serial device like data loggers which constantly send data to PC, data is usually sent in packets. Packet is a string of charackters, usually of constant size, with some start and/or stop charackters. Application can parse incoming data inside OnRxChar event handler, but it's much easier to use TComDataPacket component, which does parsing process automatically.
...
When packet is formed OnPacket event is triggered with packet string as parameter. Any data that is discarded during the process of packet forming goes through OnDiscard event.
"

Also ich habe beim OnPacket event meinen Befehl reingeschrieben:

ShowMessage(str) //str = der string der ausgegeben wird von TComDataPacket

das muss doch so passen oder?

LargoD 6. Mär 2010 19:23

Re: An com port gesendete daten lesen
 
OK, das mit den zwei Terminal-Fenstern habe ich verstanden.

TComPort und auch TComDataPacket habe ich schon öfter in verschiedenen Projekten eingesetzt, hat immer gut geklappt.

Zeig doch mal aktuellen Code, vor Allem
die Initialisierung des Paket-objektes und den OnPacket Handler

Gruß
Erich

schweindi 6. Mär 2010 19:53

Re: An com port gesendete daten lesen
 
super, also hier mal eine kurze (!!) beschreibung:
hab 2 edits:
1) gibt den comport an ('com6' in meinem Fall)
2) gibt den Befehl an, den man ans modem senden will (nur mal als test ob alles funktioniert)

Buttons:
1) 'Test Connection' -> code:

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var StartIni : TIniFile;
begin
ComPort1.Port:=Edit1.Text;
//Ini File
StartIni:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI'));
try
StartIni.writeString('Com','Name',Edit1.Text);
finally
  StartIni.Free;
end;
ComPort1.Open;
end;
2) Disconnect (Testzweck) beinhaltet nur Comport1.Close;
3) Write -> sendet das was in Edit2.Text steht an den Port -> code:

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
var Str: String;
begin
//write to port
Str := Edit2.Text;
//ComPort1.WriteStr(Str); // string type variable
ComPort1.Write(Str[1], Length(Str)); // no defined type
ComPort1.TransmitChar(#13);
ShowMessage('Write Data Successfull');
//answer
//read_answer;      //das war mein Alternativversuch, wird nicht verwendet
//answer with datapacket
ComDataPacket1.StartString:=#10;   //hier angegeben, da es per Optionsmenu als '#13' angegeben wird (alter fehler)
ComDataPacket1.StopString:=#13;
end;
so und jetzt noch die komponenten:
1) TComPort ('ComPort1'):

Delphi-Quellcode:
object ComPort1: TComPort
    BaudRate = br9600
    Port = 'COM6'
    Parity.Bits = prNone
    StopBits = sbOneStopBit
    DataBits = dbEight
    EventChar = #10
    Events = [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS, evDSR, evError, evRLSD, evRx80Full]
    Buffer.InputSize = 4096
    Buffer.OutputSize = 4096
    FlowControl.OutCTSFlow = True
    FlowControl.OutDSRFlow = False
    FlowControl.ControlDTR = dtrDisable
    FlowControl.ControlRTS = rtsHandshake
    FlowControl.XonXoffOut = False
    FlowControl.XonXoffIn = False
    Timeouts.ReadInterval = 20
    Timeouts.ReadTotalMultiplier = 100
    Timeouts.ReadTotalConstant = 10000
    Timeouts.WriteTotalMultiplier = 2
    Timeouts.WriteTotalConstant = 10000
    OnError = ComPort1Error
    Left = 8
    Top = 200
  end
2) TComDataPacket -> code:

Delphi-Quellcode:
  object ComDataPacket1: TComDataPacket
    ComPort = ComPort1
    OnPacket = ComDataPacket1Packet
    Left = 48
    Top = 200
  end
und zuletzt noch: OnPacket ->

Delphi-Quellcode:
procedure TForm1.ComDataPacket1Packet(Sender: TObject; const Str: String);
begin
ShowMessage('Packet RX: '+IntToStr(length(str)));
ShowMessage(str);
end;
so das wäre alles... hoffe es hilft dir weiter :)

LargoD 6. Mär 2010 21:33

Re: An com port gesendete daten lesen
 
Also nur mal so auf die Schnelle drübergesehen:

StartString := #10 ist falsch, wieso sollte das Modem vor der Antwort Linefeed senden?
StopString := #13+#10 sollte passen, denn normalerweise senden Modems nach der Antwort CR/LF, wenn sie nicht umkonfiguriert sind.
Ich hofft Du weißt, wie man CR/LF auf der Tastatur (zum Testen) sendet.

Also zum Senden:
ComDataPacket1.StartString:=''; // das sollte eigentlich nur einmal gemacht werden, ist aber egal
ComDataPacket1.StopString:=#13+#10; // das sollte eigentlich nur einmal gemacht werden, ist aber egal
ComPort1.WriteStr(Edit2.Text+#13)

Timeouts brauchst Du zum Testen erst mal keine, solange Du nur das abholst was auch wirklich im Puffer ist.
Außerdem kannst Du nicht schnell genug tippen ;-)

Kein Eventchar, also
EventChar :=#0;

Vielleicht habe ich jetzt noch was übersehen, aber bau das erst mal um und teste es.

Noch ein Tip: Zur Auswahl des ComPorts sieh Dir mal TComCombobox an.

Gruß
Erich

schweindi 6. Mär 2010 23:57

Re: An com port gesendete daten lesen
 
okay danke :)

habe das mal geändert und ja, wenn ich einfach ok+(enter) eingebe dann kommt die MsgBox mit der länge des strings und der erste buchstabe "o" wird ausgegeben... wenn ich es nochmal mache, ist die zeichenkette nur noch leer... also ja immer den ersten buchstaben kann er ausgeben.

Danach sollte an den Buffer clearen oder? naja egal - ich will mal, dass er das ganze packet liest

LargoD 7. Mär 2010 07:12

Re: An com port gesendete daten lesen
 
Zitat:

habe das mal geändert und ja, wenn ich einfach ok+(enter) eingebe dann kommt die MsgBox mit der länge des strings...
Wenn Du den Stop-String richtig eingegeben hast, sollte die Message Box erst aufgehen, wenn Du ok#13 und danach #10 gedrückt hast.
Vier Zeichen 'o', 'k', #13 und dann #10!
Hast Du die Timeouts wirklich abgestellt?
Ist Size wirklich 0?
Und setze mal FlowControl auf None.

Zitat:

Danach sollte an den Buffer clearen oder?
Nein, was das PacketEvent Dir geliefert hat, ist aus dem Puffer verschunden.

Gruß
Erich

schweindi 7. Mär 2010 11:23

Re: An com port gesendete daten lesen
 
1) In den ComPort Options sind alle timeouts auf 0
2) Size = 0
3) FlowContorl = None

Wenn ich enter drücke kommt die msgbox - dh enter + #10#13, ich kann auch alt+010 bzw alt+013 eingeben, es kommt auch das fenster.
Wenn ich "ok"+#10#13 im terminal schreibe, Steht im Programm: "Input: o" beim nächsten mal, wenn ich etwas eintippe + enter nur "Input:" dh nur der erste buchstabe wird gelesen...

Das sagt mein Virtual Com log:
Port is opened
Application has set ByteSize to 5.
Application has set ByteSize to 8.
Application has set XonLim to 2048.
Application has set XoffLim to 512.
Application has set XoffChar to 13.
Application has set XonLim to 1024.
Application has set XoffLim to 1024.
Application has written 3 bytes.
Port is closed

vllt hilft das auch weiter...

schweindi 7. Mär 2010 12:24

Re: An com port gesendete daten lesen
 
okay.. das tut mir jetzt echt leid und ist mir wirklich peinlich :-P

Ich habe das Programm jetzt mal direkt auf dem Server mit der SMS Software ausprobiert und siehe da:

Code:
549   13:13:38   Pcom_bridge.exe   IRP_MJ_CREATE         USBSER000   SUCCESS   Options: Open    
550   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_SET_QUEUE_SIZE      USBSER000   SUCCESS   InSize: 4096 OutSize: 4096   
551   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_GET_BAUD_RATE      USBSER000   SUCCESS      
552   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_GET_LINE_CONTROL   USBSER000   SUCCESS      
553   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_GET_CHARS      USBSER000   SUCCESS      
554   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_GET_HANDFLOW      USBSER000   SUCCESS      
555   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_SET_BAUD_RATE      USBSER000   SUCCESS   Rate: 9600   
556   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_CLR_RTS      USBSER000   SUCCESS      
557   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_CLR_DTR      USBSER000   SUCCESS      
558   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_SET_LINE_CONTROL   USBSER000   SUCCESS   StopBits: 1 Parity: NONE WordLength: 8   
559   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_SET_CHAR      USBSER000   SUCCESS   EOF:80 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13   
560   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_SET_HANDFLOW      USBSER000   SUCCESS   Shake:0 Replace:0 XonLimit:1024 XoffLimit:1024   
561   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_SET_TIMEOUTS      USBSER000   SUCCESS   RI:0 RM:0 RC:0 WM:0 WC:0   
562   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_SET_WAIT_MASK      USBSER000   SUCCESS   Mask: RXCHAR RXFLAG TXEMPTY CTS DSR RLSD BRK ERR RING RX80FULL    
563   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_GET_MODEMSTATUS   USBSER000   SUCCESS      
564   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_GET_MODEMSTATUS   USBSER000   SUCCESS      
565   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_GET_MODEMSTATUS   USBSER000   SUCCESS      
566   13:13:38   Pcom_bridge.exe   IOCTL_SERIAL_WAIT_ON_MASK      USBSER000   SUCCESS      
567   13:14:01   Pcom_bridge.exe   IRP_MJ_WRITE                  USBSER000   SUCCESS   Length 3: at.   
568   13:14:01   Pcom_bridge.exe   IOCTL_SERIAL_WAIT_ON_MASK      USBSER000   SUCCESS      
569   13:14:01   Pcom_bridge.exe   IOCTL_SERIAL_GET_COMMSTATUS      USBSER000   SUCCESS      
570   13:14:01   Pcom_bridge.exe   IRP_MJ_READ                  USBSER000   SUCCESS   Length 6: ..OK..   
571   13:14:01   Pcom_bridge.exe   IOCTL_SERIAL_GET_COMMSTATUS      USBSER000   SUCCESS      
572   13:14:01   Pcom_bridge.exe   IOCTL_SERIAL_WAIT_ON_MASK      USBSER000   SUCCESS      
573   13:14:23   Pcom_bridge.exe   IRP_MJ_WRITE                  USBSER000   SUCCESS   Length 9: at+cpin?.   
574   13:14:23   Pcom_bridge.exe   IOCTL_SERIAL_WAIT_ON_MASK      USBSER000   SUCCESS      
575   13:14:23   Pcom_bridge.exe   IOCTL_SERIAL_GET_COMMSTATUS      USBSER000   SUCCESS      
576   13:14:23   Pcom_bridge.exe   IRP_MJ_READ                  USBSER000   SUCCESS   Length 22: ..+CPIN: READY....OK..   
577   13:14:23   Pcom_bridge.exe   IOCTL_SERIAL_GET_COMMSTATUS      USBSER000   SUCCESS      
578   13:14:23   Pcom_bridge.exe   IOCTL_SERIAL_WAIT_ON_MASK      USBSER000   SUCCESS      
579   13:14:34   Pcom_bridge.exe   IRP_MJ_WRITE                 USBSER000   SUCCESS   Length 9: at+cfun?.   
580   13:14:34   Pcom_bridge.exe   IOCTL_SERIAL_WAIT_ON_MASK      USBSER000   SUCCESS      
581   13:14:34   Pcom_bridge.exe   IOCTL_SERIAL_GET_COMMSTATUS      USBSER000   SUCCESS      
582   13:14:34   Pcom_bridge.exe   IRP_MJ_READ                  USBSER000   SUCCESS   Length 18: ..+CFUN: 1....OK..   
583   13:14:34   Pcom_bridge.exe   IOCTL_SERIAL_GET_COMMSTATUS      USBSER000   SUCCESS      
584   13:14:34   Pcom_bridge.exe   IOCTL_SERIAL_WAIT_ON_MASK      USBSER000   SUCCESS      
585   13:14:41   Pcom_bridge.exe   IOCTL_SERIAL_PURGE        USBSER000   SUCCESS   Purge: TXABORT RXABORT    
586   13:14:41   Pcom_bridge.exe   IOCTL_SERIAL_SET_WAIT_MASK      USBSER000   SUCCESS   Mask:    
587   13:14:41   Pcom_bridge.exe   IOCTL_SERIAL_PURGE       USBSER000   SUCCESS   Purge: TXCLEAR RXCLEAR   
588   13:14:41   Pcom_bridge.exe   IRP_MJ_CLEANUP                  USBSER000   SUCCESS      
589   13:14:41   Pcom_bridge.exe   IRP_MJ_CLOSE                  USBSER000   SUCCESS
also wie man hier sieht, geht der Befehl "at" und bekommt "Length 6: ..OK.." zurück... und at+cpin? geht auch usw... also das Problem war einfach mein dummes virtuelles Com Programm!
So jetzt muss ich mal die Antworten formatieren, damit man sich da auskennt... "+CPIN: Ready....OK..22" ist nicht ganz die Antwort die ich brauche :)

LargoD 7. Mär 2010 13:21

Re: An com port gesendete daten lesen
 
Ja, da scheint Dein virtuelles Com-Port Programm einiges selbständig zu tun, z. B. Enter in CR/LF umzuwandeln. Nach dem Log habe ich den Eindruck, dass es auch versucht, ein Xon/Xoff Software-Protokoll zu fahren. Du kannst ja nochmal in die Einstellungen reinsehen, ob man da was ändern kann. Ist aber nicht mehr wichtig, wenn Du mit dem echten Modem weiter testen kannst.
Gruß
Erich


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:14 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz