Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Virtuellen COM-Port ansteuern


icewave - Mo 10.01.11 00:46
Titel: Virtuellen COM-Port ansteuern
Hi Leute,

Für ein Projekt muss ich einen Virtuellen COM-Port ansteuern, den Befehl 'C01' senden und 3 Bytes empfangen.

Ich habe mich schon umgeschuat und einige Samples versucht, aber entweder bekomme ich den Error 'Verbindung mit COM-Port nicht möglich' oder das Programm reaiert für 1 Minute lang nicht mehr...

Ich habe mich an dieses Tutorial gehalten: http://www.delphipraxis.net/56359-com-port-ansteuern-bsp-modelleisenbahn.html

Kann mir vielleicht jemand Helfen?

Ich nutze übrigens Delphi 6.


Danke,

icewave


jaenicke - Mo 10.01.11 01:12

Hallo und :welcome:

Um bei deinem Problem konkret zu helfen, müsstest du schon den Code schreiben wie er bei dir aussieht. :nixweiss:

Wie wäre es mit dieser Bibliothek:
http://sourceforge.net/projects/comport/
Die macht prinzipiell auch nichts anderes, aber dann musst du dich nicht selbst um die Ansteuerung kümmern. ;-)

Die andere Sache: Falls du hier einen COM-to-USB-Adapter meinst, könnte das Problem auch bei diesem liegen.


icewave - Di 11.01.11 00:18

OK, dank der Klasse bekomme ich meine IO-Karte ja schon einmal angesteuert. Danke schon einmal dafür...

Allerdings kommt nun das nächste Problem:
Das gerät antwortet mit 3 Bytes: Zahl1, Zahl2, Summe aus Zahl 1+2
Somit habe ich also 3 Integer. Wenn ich jetzt einfach ReadStr(); nehme, bekomme ich Ägyptische Hyroglyphen, nehme ich nur Read(); weiß ich nicht, wie ich die Daten verarbeiten soll...

Wie bekomme ich also jetzt jedes einzelne Byte? (und mache daraus einen integer)


Danke, icewave


Edit: Wie ich herausgefunden habe, liefert mir die Schnittstelle die fertige millivolt-Zahl, allerdings statt als int als Hyroglyphen...


jaenicke - Di 11.01.11 05:37

Wenn die Bytes die z.B. 4 Bytes eines Integerwerts sind, musst du diese auch wieder zu einem zusammensetzen. Stichwort shl z.B., damit kannst du die Bits nach links verschieben um die 4 Bytes wieder hintereinander zu setzen.


chrisw - Di 11.01.11 13:01

Ich denke du machst ein Readstr() und wandelst den String in etwa so um :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure getIntegerFromString(var int1,int2,int3: Integer; s: String); 
begin
  if length(s) = 3 then 
  begin
    int1    := ord(s[0]);
    int2    := ord(s[1]);
    int3    := ord(s[2]);
  end;
end;


Aufruf dann mit :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var tempStr : String;

tempStr := ComPort1.Readstr();
 //asure that this String is a correct one; that means:
 //it starts with "CO1" and it's total length is 6 byte ("CO1" + 3 Integer Bytes)
if (pos('CO1',tempStr)=1and (length(tempStr) =6then
begin
  delete(tempStr,1,3//delete fixed String "CO1" from String
  getIntegerFromString(i1,i2,i3,tempStr);
end;


in den Integer-Variablen i1-i3 befinden sich dann die Werte, die du mit IntToStr() wieder in Strings umwandeln kannst !


icewave - Di 11.01.11 16:45

So...

Ich bekomme die 3 Zahlen nun ausgegeben und Zahl 3 ist auch die Prüfsumme von i1 + i2...

Danke an alle die geholfen haben...



Jetzt steht hier aber noch folgendes:
i1 ist das lowByte der Messung, i2 das HighByte...

die maximale Voltstärke, die ausgegeben wird, sind 4095V...


ist also, wenn i2 zB 255 ist 100% angekommen?

also (i2/255)*4095 ?


Narses - Di 11.01.11 16:51

Moin!

user profile iconicewave hat folgendes geschrieben Zum zitierten Posting springen:
i1 ist das lowByte der Messung, i2 das HighByte
Mach das mal so: :idea: ;)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
  msb, lsb: Byte;
  int: Integer;

begin
  int := (msb shl 8or lsb;
  ShowMessage(IntToStr(int));
cu
Narses


icewave - Di 11.01.11 21:34


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:
procedure TForm1.Timer1Timer(Sender: TObject);
var buffer : string;
var i1, i2, i3, i4 : integer;
var z : integer;

msb, lsb: Byte;
int: Integer;

begin
  if(hComPort.Connected = true) then
  begin
    hComPort.WriteStr('c01');
    hComPort.ReadStr(buffer, 3);

    if length(buffer) = 3 then
    begin
        i1 := ord(buffer[1]);
        i2 := ord(buffer[2]);
        i3 := ord(buffer[3]);
    end;

    int := (msb shl 8or lsb;
    ShowMessage(IntToStr(int));

    if((i1 + i2) = i3) then
    begin
      z := round((i2 / 256) * 4095);

      Label1.Caption := IntToStr(z);
     // Label2.Caption := IntToStr(i2);
      //Label3.Caption := IntToStr(i3);
    end;
  end;
end;


Wenn ich das so mache, bekomme ich 65535 ausgegeben. Dabei habe ich msb und lsb garnicht ausgegeben...

icewave


elundril - Di 11.01.11 21:42

du setzt in der Procedure ja LSB und MSB gar nicht. Ich glaube du solltest i1 als LSB und i2 als MSB umbenennen und den typ auf byte deklarieren. ;)

lg elundril


icewave - Di 11.01.11 21:50

Selbst dann ist der Wert > 4095...


jaenicke - Mi 12.01.11 00:55

Und wenn du die Werte vertauschst? Gibt ja da auch noch Big-Endian und Little-Endian. ;-)


icewave - Sa 15.01.11 17:30

Ich hab zwar kein Plan, was das jetzt wieder alles für Werte sind, aber es klappt jetzt...

danke!!!!!!!!