[Delphi] Simpel COM poort lezen/schrijven

Pagina: 1
Acties:
  • 387 views sinds 30-01-2008
  • Reageer

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik zoek een manier om simpel iets te schrijven naar een COM poort en vervolgens te lezen. Ik weet dat er componenten hiervoor zijn, maar die zijn meestal te uitgebreid, of ze hebben bepaalde events. Ik moet eigenlijk alles in 1 functie hebben.

Dus:
- Open COM poort
- Schrijf data
- Lees data
- Sluit COM poort
- Geef data terug aan functie

Ik denk dat er al es een GoT gebruiker is die zoiets simpels heeft gemaakt, dus waarom 2x het wiel uit vinden.

Alvast bedankt. :)

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Ik denk dat het (zeker onder WinNT/2K) toch via een tussenstap moet, en wel de freeware DLPortIO driver.

Hier een implementatie voor BC++, misschien werkt deze ook in Delphi, maar ik heb hem zelf nog niet getest. http://diskdude.cjb.net/software/cbuilder/index.html

De driver zelf haal je vandaan: http://www.driverlinx.com/Software_Products/softwareproducts.htm ff op Port IO klikken.

Misschien heb je hier ook wel wat aan: http://www.wideman-one.com/gw/tech/Delphi/iopm/

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Waarom niet via API?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb zoiets als dit:
code:
1
2
3
4
5
  ComFile := CreateFile('COM1', GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

  if ComFile = INVALID_HANDLE_VALUE then Exit;
  TextToSend := 'AT' + #13#10;
  if not WriteFile(ComFile, TextToSend[1], Length(TextToSend), BytesWritten, nil) then Exit;

Maar hoe lees ik nu?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Je zou het niet verwachten maar je doet het ReadFile :Y)

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op maandag 01 oktober 2001 21:33 schreef Yarvieh het volgende:
Je zou het niet verwachten maar je doet het ReadFile :Y)
Dat snap ik, maar hoe precies. Je moet namelijk bij ReadFile opgeven hoeveel bytes je wilt lezen. Maar dat kun je toch niet raden van te voren?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Dan lees je 1 byte tegelijkertijd? goed 't is verre van optimaal maar anders moet je async gaan werken en daar wil je niet aan omdat het dan te complex wordt.

zie: http://msdn.microsoft.com/library/en-us/hardware/commun_2pf7.asp voor de details van seriele communicatie. Ik denk dat je na 'n kwartiertje spitten daar die componenten met events lang zo gek nog niet vind :Y)

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Wat ik niet snap is dat ik voor zo iets simpels een extra component nodig heb. Zo moeilijk kan het toch niet zijn?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

'T hoeft niet maar je geeft zelf al aan niet al te complex te willen doen. Dan kom je al vrij rap uit bij componenten van derden die die complexiteit voor je verbergen, als je het zelf wil maken kan het wel geen probleem de beschikbare documentatie is daar meer dan voldoende voor. 't is meer een keus voor je zelf die je moet maken ga ik met een component van een ander of verdiep ik me zelf een beetje in de werking van io.

Ps. Wil je ophouden me te icq'en zodra je weer wat post? Ik of iemand anders reply'ed echt wel een keertje, heb maar wat geduld.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Op maandag 01 oktober 2001 23:59 schreef Yarvieh het volgende:
'T hoeft niet maar je geeft zelf al aan niet al te complex te willen doen. Dan kom je al vrij rap uit bij componenten van derden die die complexiteit voor je verbergen, als je het zelf wil maken kan het wel geen probleem de beschikbare documentatie is daar meer dan voldoende voor. 't is meer een keus voor je zelf die je moet maken ga ik met een component van een ander of verdiep ik me zelf een beetje in de werking van io.
Ik snap het. Wat ik ook es kan proberen is te kijken hoe die componenten het hebben gedaan, en daar dan alleen het deel uit halen wat ik nodig heb.
En of dit nou veel te maken heeft met de werking van IO weet ik niet. Eerder met de werking van IO onder Delphi. Want als je kijkt naar bijvoorbeeld (Q)Basic (onder DOS), dan was het wel even wat simpleren. Doet er verder niet toe. Iig bedankt voor je reply. :)
Ps. Wil je ophouden me te icq'en zodra je weer wat post? Ik of iemand anders reply'ed echt wel een keertje, heb maar wat geduld.
Sorry hoor. Sommige mensen stellen het op prijs, andere niet. Kan ik van te voren moeilijk ruiken. Maar ik zal het niet weer doen hoor. :P

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 18:58

Tomatoman

Fulltime prutser

En of dit nou veel te maken heeft met de werking van IO weet ik niet. Eerder met de werking van IO onder Delphi. Want als je kijkt naar bijvoorbeeld (Q)Basic (onder DOS), dan was het wel even wat simplere. :)
Een groot verschil tussen DOS en Windows is dat je in DOS direct de hardware - inclusief I/O - kunt aanspreken en bij Windows alleen via een driver. Da's ook logisch, want in Windows kunnen diverse processen tegelijkertijd dezelfde hardware proberen aan te spreken, bijvoorbeeld die COM-poort van je. De driver zorgt er dan voor dat er geen conflicten optreden.

Daarom kun je COM-poorten in principe alleen via een driver aanspreken. Maar er zijn wel trucs om daaromheen te werken. >:) Aangezien Windows 2000 ook nog met rechten werkt (je krijgt niet zomaar toegang tot alle hardware), wordt het daar nog een stukje moeilijker. :( Ingewikkelde I/O is dus geen zwakte van Delphi, maar gewoon een eigenschap van Windows. En als je dat niet wilt, dan schrijf je toch gewoon een DOS app? :)

Een goede grap mag vrienden kosten.


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik snap wat je bedoeld. Maar wat ik dus eigenlijk wil is gewoon een simpele functie die iets schrijft naar een COM poort en vervolgens de reactie leest en terug geeft.

Dit blijkt dus best moeilijk te zijn in Windows (met name NT) daarom moet ik maar een extra component gebruiken. Dat deze wel gewoon kunnen lezen/schrijven naar een COM poort blijft dan dus een raadsel, tenzij ik de source van zo'n component ga uitpluizen (wat geen pretje is).

Zelf gebruik ik nooit zo snel een niet-standaard component. Probeer het eerst zelf te maken, zodat ik het zo simpel of zo uitgebreid kan maken als ik wil. Ik heb dan gewoon meer overzicht over wat ik doe.

Maar nu het logische gevolg op dit 'probleem': wat is een goed component (gratis+source?) voor het lezen/schrijven naar een compoort?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Verwijderd

Je kunt ook gewoon het standaardcomponent Commportdriver gebruiken.

1 event voor het ontvangen van data.
1 procedure voor het zenden van data.

Verwijderd

Op dinsdag 02 oktober 2001 08:51 schreef jelmervos het volgende:
En of dit nou veel te maken heeft met de werking van IO weet ik niet. Eerder met de werking van IO onder Delphi. Want als je kijkt naar bijvoorbeeld (Q)Basic (onder DOS), dan was het wel even wat simpleren.
Het heeft weldegelijk te maken met de werking van io wellis waar niet in het algemeen maar wel op het win32 platform, de kennis die je hier opdoet met asynchrone io is zonder aanpassingen ook toepasbaar op files en device drivers. Inderdaad in Basic onder dos was het simpeler, maar basic was dan ook de enige taak die actief was in het geheugen. Denk persoonlijk dat het niet zo geslaagd zou zijn als bv m'n windows zou hangen op het moment dat ie op wat bytes van m'n modem staat te wachten toch? Kortom ja het is complexer maar niet zonder reden ;)

  • itsme
  • Registratie: Februari 2000
  • Niet online
Zo doet ik t
code:
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
function ReadPortB
( wPort : Word ) : Byte;
begin
asm
mov dx, wPort
in al, dx
mov result, al
end;
end;


procedure WritePortB
( wPort : Word; bValue : Byte );
begin
asm
mov dx, wPort
mov al, bValue
out dx, al
end;
end;


var data, com :integer;


WritePortB(com+4,1);
data:=ReadPortB(com+6);

hier nog ff de hele source (niet van COM Control overigens maar van mn eerste poging iets met de COM Poort te doen, proggie heet ook COM Poort :)).
code:
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
unit Compoortunit;

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Timer1: TTimer;
    Label2: TLabel;
    RadioGroup1: TRadioGroup;
    Label3: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function ReadPortB
( wPort : Word ) : Byte;
begin
asm
mov dx, wPort
in al, dx
mov result, al
end;
end;


procedure WritePortB
( wPort : Word; bValue : Byte );
begin
asm
mov dx, wPort
mov al, bValue
out dx, al
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var data, com :integer;
data1 : Variant;
begin
if RadioGroup1.ItemIndex = 0 then
Label3.caption := 'COM 1' else
if RadioGroup1.ItemIndex = 1 then
Label3.caption := 'COM 2' else
if RadioGroup1.ItemIndex = 2 then
Label3.caption := 'COM 3' else
if RadioGroup1.ItemIndex = 3 then
Label3.caption := 'COM 4' else
Label3.caption := 'Geen poort geselecteerd';
if RadioGroup1.ItemIndex = 0 then
com := 1016 else
if RadioGroup1.ItemIndex = 1 then
com := 760 else
if RadioGroup1.ItemIndex = 2 then
com := 1000 else
if RadioGroup1.ItemIndex = 3 then
com := 744 else
com := 0;

WritePortB(com+4,1);
data:=ReadPortB(com+6);
data1 := data;
if data = 0 then
label1.caption := 'Er is geen signaal' else
      label1.caption := data1;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin
RadioGroup1.ItemIndex := 0;
end;

end.

"If God wanted us to have unlimited free energy He would have put a giant fusion reactor in the sky"


Verwijderd

Op dinsdag 02 oktober 2001 18:07 schreef bas_konings het volgende:
Zo doet ik t
code:
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
function ReadPortB
( wPort : Word ) : Byte;
begin
asm
mov dx, wPort
in al, dx
mov result, al
end;
end;


procedure WritePortB
( wPort : Word; bValue : Byte );
begin
asm
mov dx, wPort
mov al, bValue
out dx, al
end;
end;


var data, com :integer;


WritePortB(com+4,1);
data:=ReadPortB(com+6);
mmm... waar is eigelijk die com+4 of +6 voor?

Verwijderd

Op woensdag 07 november 2001 20:38 schreef MPdave het volgende:
mmm... waar is eigelijk die com+4 of +6 voor?
code:
1
2
3
4
5
6
7
Base + 0   Data I/O port (plus divisor setting)
Base + 1   Interrupt enable port
Base + 2   Interrupt identification port
Base + 3   Line contol register
Base + 4   Modem control register
Base + 5   Line status register
Base + 6   Modem status register

  • roelio
  • Registratie: Februari 2001
  • Niet online

roelio

fruitig, en fris.

Op dinsdag 02 oktober 2001 13:47 schreef jelmervos het volgende:
...
Dit blijkt dus best moeilijk te zijn in Windows (met name NT) daarom moet ik maar een extra component gebruiken. Dat deze wel gewoon kunnen lezen/schrijven naar een COM poort blijft dan dus een raadsel, tenzij ik de source van zo'n component ga uitpluizen (wat geen pretje is).
...
dat is geen raadsel. Je moet de COM poort gewoon via Windows (API) aanspreken, daarna regelt Windows de communicatie met de driver (= poort)...
De componenten die je noemt gebruiken ook gewoon de (NT) API, dus zo gek is het niet ...

AMD Phenom II X4 // 8 GB DDR2 // SAMSUNG 830 SSD // 840 EVO SSD // Daar is Sinterklaas alweer!!


  • roelio
  • Registratie: Februari 2001
  • Niet online

roelio

fruitig, en fris.

Op dinsdag 02 oktober 2001 18:07 schreef bas_konings het volgende:
Zo doet ik t
(code)
tsja maar volgens mij mogen die assembler statements niet onder Windows NT (= XP/2K) want je spreekt "direct" met de hardware, of niet soms? experts op dit gebied?

AMD Phenom II X4 // 8 GB DDR2 // SAMSUNG 830 SSD // 840 EVO SSD // Daar is Sinterklaas alweer!!


Verwijderd

Je mag idd niet direct je hardware benaderen, maar daar is vrijgemakklijk overheen te komen door 't in kernel mode te doen dmv van een extra drivertje (dlportio bv) of je eigen drivertje te schrijven (zit een voorbeeldje in de NT driver DDK)

  • CRCerror
  • Registratie: December 2000
  • Laatst online: 21-01 15:02
Hoi,

Zelf maak ik altijd gebruik van de turbopower componenten, deze zijn zeer handig om te gebruiken.
Je kunt een string over de compoort sturen door gewoon:

compname.output := "commando naar apparaat op compooort";


kost alleen wel geld, maar valt ook wel een mouw aan te passen als je dat niet kunt betalen.. astalavista


voor de website: http://www.turbopower.com/products/apro/

Greetz,

CrCeRrOr

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:12

Creepy

Tactical Espionage Splatterer

Hmm.. heb ooit voor m'n werk eens de seriele communicatie tussen een kassa en een LCD display moeten uitlezen (tankstation weet je wel.. kassa alleen zichtbaar voor de persoon die daar werkt.. display zichtbaar voor de klant)

Had ergens een freeware componentje dat alle seriele communicatie voor je regelde... instellen.. en events afwachten :)

Zal eens kijken of ik die nog kan vinden..

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Baron
  • Registratie: Juli 2000
  • Laatst online: 21-06 17:02
Ik heb dit ooit geprobeerd

http://www2.arnes.si/~sopecrni/
Pagina: 1