Board index » delphi » Serial comms and Win NT

Serial comms and Win NT

After researching some comms components and other drivers on various
sites I manage to develop the following routines which handle the coms
for my app.

These work ok under win 95 and when the device is not attached, the
program correctly displays its own warning message. when open comm
returns false. However with NT no erro message is received and the
program hangs and hangs a few other programs as well resulktin in a need
to reboot.

I saw something on the UDDF saying NT requires extra code but not what
or how to do it.

Has anybody  had experience with this ?

Kym Wilson

var
  Com: THandle = 0;
.
.
function OpenComm: Boolean;
var
  Port, Baud : LongInt;
  res,res1 :boolean;
  cont: ttable;
begin

  // extract coms parameters from Control.dbf

  cont:=ttable.create(nil);
  with cont do begin
    databasename:=mfmain.appdir;
    tablename:='control.dbf';
    tabletype:=ttsxnsx;
    active:=true;
    first;
    baud:=fieldbyname('ttbaud').value;
    port:=fieldbyname('ttport').value;
    close;
    free;
  end;
  if Com > 0 then CloseComm;
  comport:=port;
  Com := CreateFile(PChar(CPort[ComPort]),
                GENERIC_READ or GENERIC_WRITE,
                0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  Res := (Com > 0);
  res1:=SetCommTiming;
  res:=res1 and res;
  res1:= SetCommStatus(Baud) ;
  res:=res1 and res;
  res1:= SetCommBuffer(2048,2048);
  result:=res1 and res;
end;

function SetCommTiming: Boolean;
var
  Timeouts: TCommTimeOuts;

begin
  with TimeOuts do
    begin
      ReadIntervalTimeout := 1;
      ReadTotalTimeoutMultiplier := 0;
      ReadTotalTimeoutConstant := 1;
      WriteTotalTimeoutMultiplier := 2;
      WriteTotalTimeoutConstant := 2;
    end;
  Result := SetCommTimeouts(Com,Timeouts);
end;

function SetCommBuffer(InQueue, OutQueue: LongInt): Boolean;
begin
  Result := SetupComm(Com, InQueue, OutQueue);
end;

function SetCommStatus(Baud: Integer): Boolean;
var
  DCB: TDCB;

begin
  fillchar( dcb, sizeof(dcb), 0 );
  with DCB do
    begin
      DCBlength:=SizeOf(dcb);
      BaudRate := Baud;
      Flags:=$11; //12305;
      wReserved:=0;
      XonLim:=512;
      XoffLim:=1;
      ByteSize:=8;
      Parity:=0;
      StopBits:=0;
      XonChar:=#17;
      XoffChar:=#19;
      ErrorChar:=#0;
      EofChar:=#0;
      EvtChar:=#0;
//      wReserved1:=65;
    end;
  Result := SetCommState(Com, DCB);
end;

function SendCommStr(S: String): Integer;
var
  TempArray : array[1..255] of Byte;
  Count, TX_Count : Integer;

begin
  for Count := 1 to Length(S) do TempArray[Count] := Ord(S[Count]);
  WriteFile(Com, TempArray, Length(S), TX_Count, nil);
  Result := TX_Count;
end;

function SendComm(OutArray : array of Byte;n:integer): Integer;
var

  TX_Count : Integer;

begin
  WriteFile(Com, OutArray, n, TX_Count, nil);
  Result := TX_Count;
end;

 

Re:Serial comms and Win NT


use the API functions createfile(), readfile(), writefile, closefile()
functions described in the DDK.

Regards,

Thorsten

Quote
Kym Wilson wrote:
> After researching some comms components and other drivers on various
> sites I manage to develop the following routines which handle the coms
> for my app.

> These work ok under win 95 and when the device is not attached, the
> program correctly displays its own warning message. when open comm
> returns false. However with NT no erro message is received and the
> program hangs and hangs a few other programs as well resulktin in a need
> to reboot.

> I saw something on the UDDF saying NT requires extra code but not what
> or how to do it.

> Has anybody  had experience with this ?

> Kym Wilson

> var
>   Com: THandle = 0;
> .
> .
> function OpenComm: Boolean;
> var
>   Port, Baud : LongInt;
>   res,res1 :boolean;
>   cont: ttable;
> begin

>   // extract coms parameters from Control.dbf

>   cont:=ttable.create(nil);
>   with cont do begin
>     databasename:=mfmain.appdir;
>     tablename:='control.dbf';
>     tabletype:=ttsxnsx;
>     active:=true;
>     first;
>     baud:=fieldbyname('ttbaud').value;
>     port:=fieldbyname('ttport').value;
>     close;
>     free;
>   end;
>   if Com > 0 then CloseComm;
>   comport:=port;
>   Com := CreateFile(PChar(CPort[ComPort]),
>                 GENERIC_READ or GENERIC_WRITE,
>                 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
>   Res := (Com > 0);
>   res1:=SetCommTiming;
>   res:=res1 and res;
>   res1:= SetCommStatus(Baud) ;
>   res:=res1 and res;
>   res1:= SetCommBuffer(2048,2048);
>   result:=res1 and res;
> end;

> function SetCommTiming: Boolean;
> var
>   Timeouts: TCommTimeOuts;

> begin
>   with TimeOuts do
>     begin
>       ReadIntervalTimeout := 1;
>       ReadTotalTimeoutMultiplier := 0;
>       ReadTotalTimeoutConstant := 1;
>       WriteTotalTimeoutMultiplier := 2;
>       WriteTotalTimeoutConstant := 2;
>     end;
>   Result := SetCommTimeouts(Com,Timeouts);
> end;

> function SetCommBuffer(InQueue, OutQueue: LongInt): Boolean;
> begin
>   Result := SetupComm(Com, InQueue, OutQueue);
> end;

> function SetCommStatus(Baud: Integer): Boolean;
> var
>   DCB: TDCB;

> begin
>   fillchar( dcb, sizeof(dcb), 0 );
>   with DCB do
>     begin
>       DCBlength:=SizeOf(dcb);
>       BaudRate := Baud;
>       Flags:=$11; //12305;
>       wReserved:=0;
>       XonLim:=512;
>       XoffLim:=1;
>       ByteSize:=8;
>       Parity:=0;
>       StopBits:=0;
>       XonChar:=#17;
>       XoffChar:=#19;
>       ErrorChar:=#0;
>       EofChar:=#0;
>       EvtChar:=#0;
> //      wReserved1:=65;
>     end;
>   Result := SetCommState(Com, DCB);
> end;

> function SendCommStr(S: String): Integer;
> var
>   TempArray : array[1..255] of Byte;
>   Count, TX_Count : Integer;

> begin
>   for Count := 1 to Length(S) do TempArray[Count] := Ord(S[Count]);
>   WriteFile(Com, TempArray, Length(S), TX_Count, nil);
>   Result := TX_Count;
> end;

> function SendComm(OutArray : array of Byte;n:integer): Integer;
> var

>   TX_Count : Integer;

> begin
>   WriteFile(Com, OutArray, n, TX_Count, nil);
>   Result := TX_Count;
> end;

Re:Serial comms and Win NT


Check out

http://www.microsoft.com/win32dev/base/serial.htm

All you need to know about serial comms is there.  I have done something
similar to you but I have only tried it on Windows '95  

Kym Wilson <gra...@one.net.au> wrote in article
<3647B247.16CA2...@one.net.au>...

Quote
> After researching some comms components and other drivers on various
> sites I manage to develop the following routines which handle the coms
> for my app.

> These work ok under win 95 and when the device is not attached, the
> program correctly displays its own warning message. when open comm
> returns false. However with NT no erro message is received and the
> program hangs and hangs a few other programs as well resulktin in a need
> to reboot.

> I saw something on the UDDF saying NT requires extra code but not what
> or how to do it.

> Has anybody  had experience with this ?

> Kym Wilson

> var
>   Com: THandle = 0;
> .
> .
> function OpenComm: Boolean;
> var
>   Port, Baud : LongInt;
>   res,res1 :boolean;
>   cont: ttable;
> begin

>   // extract coms parameters from Control.dbf

>   cont:=ttable.create(nil);
>   with cont do begin
>     databasename:=mfmain.appdir;
>     tablename:='control.dbf';
>     tabletype:=ttsxnsx;
>     active:=true;
>     first;
>     baud:=fieldbyname('ttbaud').value;
>     port:=fieldbyname('ttport').value;
>     close;
>     free;
>   end;
>   if Com > 0 then CloseComm;
>   comport:=port;
>   Com := CreateFile(PChar(CPort[ComPort]),
>                 GENERIC_READ or GENERIC_WRITE,
>                 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
>   Res := (Com > 0);
>   res1:=SetCommTiming;
>   res:=res1 and res;
>   res1:= SetCommStatus(Baud) ;
>   res:=res1 and res;
>   res1:= SetCommBuffer(2048,2048);
>   result:=res1 and res;
> end;

> function SetCommTiming: Boolean;
> var
>   Timeouts: TCommTimeOuts;

> begin
>   with TimeOuts do
>     begin
>       ReadIntervalTimeout := 1;
>       ReadTotalTimeoutMultiplier := 0;
>       ReadTotalTimeoutConstant := 1;
>       WriteTotalTimeoutMultiplier := 2;
>       WriteTotalTimeoutConstant := 2;
>     end;
>   Result := SetCommTimeouts(Com,Timeouts);
> end;

> function SetCommBuffer(InQueue, OutQueue: LongInt): Boolean;
> begin
>   Result := SetupComm(Com, InQueue, OutQueue);
> end;

> function SetCommStatus(Baud: Integer): Boolean;
> var
>   DCB: TDCB;

> begin
>   fillchar( dcb, sizeof(dcb), 0 );
>   with DCB do
>     begin
>       DCBlength:=SizeOf(dcb);
>       BaudRate := Baud;
>       Flags:=$11; //12305;
>       wReserved:=0;
>       XonLim:=512;
>       XoffLim:=1;
>       ByteSize:=8;
>       Parity:=0;
>       StopBits:=0;
>       XonChar:=#17;
>       XoffChar:=#19;
>       ErrorChar:=#0;
>       EofChar:=#0;
>       EvtChar:=#0;
> //      wReserved1:=65;
>     end;
>   Result := SetCommState(Com, DCB);
> end;

> function SendCommStr(S: String): Integer;
> var
>   TempArray : array[1..255] of Byte;
>   Count, TX_Count : Integer;

> begin
>   for Count := 1 to Length(S) do TempArray[Count] := Ord(S[Count]);
>   WriteFile(Com, TempArray, Length(S), TX_Count, nil);
>   Result := TX_Count;
> end;

> function SendComm(OutArray : array of Byte;n:integer): Integer;
> var

>   TX_Count : Integer;

> begin
>   WriteFile(Com, OutArray, n, TX_Count, nil);
>   Result := TX_Count;
> end;

Re:Serial comms and Win NT


Thanks (again) for your help. As usual I have managed to come up with a work
around. Since the only PC that actually interfaces with the equipment *is*
running 95, I've added a command switch to turn on the access to the serial
port. Only that one PC will have the switch set so the other ones on the
network, whether running NT or 95 won't even try to access the harware via the
serial port.

This doesn't solve the problem but it eliminates it, which is sometimes even
better and usually a lot easier :)

Kym Wilson.

Quote
Sulu wrote:
> Check out

> http://www.microsoft.com/win32dev/base/serial.htm

> All you need to know about serial comms is there.  I have done something
> similar to you but I have only tried it on Windows '95

> Kym Wilson <gra...@one.net.au> wrote in article
> <3647B247.16CA2...@one.net.au>...
> > After researching some comms components and other drivers on various
> > sites I manage to develop the following routines which handle the coms
> > for my app.

> > These work ok under win 95 and when the device is not attached, the
> > program correctly displays its own warning message. when open comm
> > returns false. However with NT no erro message is received and the
> > program hangs and hangs a few other programs as well resulktin in a need
> > to reboot.

Re:Serial comms and Win NT


I am using those functions but in the microsoft article referred to by sulu,
there is obviously at lot more to timing etc than my simple program used.

Kym Wilson

Quote
Thorsten Kubis wrote:
> use the API functions createfile(), readfile(), writefile, closefile()
> functions described in the DDK.

> Regards,

> Thorsten

Other Threads