Recent

Author Topic: How can one write serial programming code in Lazarus  (Read 15481 times)

4joey1

  • Newbie
  • Posts: 3
How can one write serial programming code in Lazarus
« on: September 08, 2007, 04:30:29 pm »
Hallo!My names are Mwangi Joe Irungu.I am a 23 year old Kenyan citizen who is a Linux and Lazarus newbie.

Sometime back,I built a computerized thermometer project using Borland Delphi 7 in a Windows XP.The project includes an external thermometer circuit which is interfaced to the computer via the serial port.The programs works nicely in Windows XP.

My intention now is to replicate the project in Suse Linux 10.1 using Lazarus compiler.Unfortunately,Lazarus does not recognize the syntax  used to manipulate the serial port.Also,I have tried to use synapse but I do not know how to install it.

I have tried to convert the Delphi code into Lazarus using the Tools->Convert Delphi project into Lazarus project  option in Lazarus.Converted code is as below.

unit temperature;

//{$MODE Delphi}
{$mode objfpc}{$H+}

interface

uses
  {Windows,} Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, LResources, Buttons;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button7: TButton;
    Button8: TButton;
    Button9: TButton;
    Timer1: TTimer;
    Memo1: TMemo;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Button10: TButton;
    Timer2: TTimer;
    Edit1: TEdit;
    Edit2: TEdit;
    Label4: TLabel;
    Button11: TButton;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    tempLabel: TLabel;
    Button12: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button9Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button10Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
   // procedure FormClose(Sender: TObject; var Action: TCloseAction);
    function  ReadPort(Port: word): byte;
    procedure Button11Click(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Button12Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
    temp,f,k:real;
    ticks:int64;
     Fport : integer;
  //  aDCb : tdcb;
     g,i,w,Q:integer;

  end;

var
  Form1: TForm1;
  potek:array[1..400000] of real;

implementation


function TForm1.ReadPort(Port: word): byte; assembler; register;
{$ASMMODE intel}

asm
    mov dx,Port
    cli
    in al,dx
    sti
end;

 function GetCPUTick: int64;
 {$ASMMODE intel}
 begin
asm
   DB $0F,$31 // this is RDTSC command. Assembler, built in Delphi,
              // does not support it,
              // that is why one needs to overcome this obstacle.
end;
end;

var
  CPUClock:extended;
   function CalibrateCPU:int64;
   //{$ASMMODE intel}
var
t:cardinal;
begin
t:=GetTickCount;
while t=GetTickCount do;
Result:=GetCPUTick;

while GetTickCount<(t+400)do;
Result:=GetCPUTick-result;
CPUClock:=2.5e-6*Result;
end;

function TicksToFloat(const Value:int64):real;
begin
Result:=Value/CPUClock;
end;



procedure TForm1.Button1Click(Sender: TObject);
begin
CalibrateCPU;
Label2.Caption:=Format('CPU clock = %f Mhz',[CPUClock]);
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
 if not timer2.Enabled then
  begin
   i:=1;
   button2.caption:='Stop';
   memo1.lines.Clear;
  timer2.enabled:=True;
  end
  else
   begin
  timer2.enabled:=False;
   button2.caption:='Log';
   
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  FPort:=CreateFile (pchar('COM1'),
                    GENERIC_READ or GENERIC_WRITE,0,NIl,
                    OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
end;

procedure TForm1.Button4Click(Sender: TObject);
var us:real;
begin
ticks:=GetCPUTick-ticks;
us:=TicksToFloat(ticks);
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
   EscapeCommFunction (FPort,CLRDTR)
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
  FPort:=CreateFile (pchar('COM2'),
                    GENERIC_READ or GENERIC_WRITE,0,NIl,
                    OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Button7.Caption:='Start';
  closeHandle (fPort);
end;







procedure TForm1.Button7Click(Sender: TObject);
var muc:dword;
    us:real;
    a,b: real;
begin
if Button7.Caption='Start' then Button7.Caption:='Stop'
else Button7.Caption:='Start';

while Button7.Caption='Stop' do begin
     EscapeCommFunction (FPort,SETDTR);
     ticks:=GetCPUTick;
     muc:=0;
while (muc =0) do begin

           GetCommModemStatus(Fport,muc);
           Application.ProcessMessages;
           end;
     ticks:=GetCPUTick-ticks;

us:=TicksToFloat(ticks);
//edit3.text:=FloatToStrF(us,ffGeneral,8,8);
EscapeCommFunction (FPort,CLRDTR);

label3.caption:=IntToStr(round(us));
{
upor:=0.0178*us/1000-0.424;
if upor>0 then begin
label1.caption:='R = '+IntTOStr(Round(upor*1000))+' Ohm';

temp:=1/(K+C*ln(upor))-273.16;
 }
 a:=StrToFloat(edit1.text);
 b:=StrToFloat(edit2.text);

 temp:=a*1/ln(us)+b;
 f:=9*temp/5+32;
 k:=temp+273.15;
// label9.Caption:=FloatToStrF(f,ffFixed,8,2);
// label10.Caption:=FloatToStrF(k,ffFixed,8,2);

tempLabel.caption:=FloatToStrF(temp,ffFixed,8,2);
{end
else begin
label1.caption:='Error. R too low!';
beep;
end;}
sleep(500);
Application.ProcessMessages;
end;

end;


procedure TForm1.Button8Click(Sender: TObject);
begin
EscapeCommFunction (FPort,SETDTR);
end;

procedure TForm1.Button9Click(Sender: TObject);
begin
print;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var muc:dword;
begin
GetCommModemStatus(Fport,muc);
//edit1.text:=IntToStr( (muc ));
end;
procedure TForm1.Button10Click(Sender: TObject);
begin
close;
end;

procedure TForm1.Button11Click(Sender: TObject);
begin
  FPort:=CreateFile (pchar('COM2'),
                    GENERIC_READ or GENERIC_WRITE,0,NIl,
                    OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
potek:=temp;
Memo1.Lines.Add(FloatToStrF(temp,ffFixed,8,2));
inc(i);
end;

procedure TForm1.Button12Click(Sender: TObject);
begin
print;
end;

initialization
  {$i temperature.lrs}
  {$i temperature.lrs}

end.              

Despite converting the code to Lazarus,I still getthe following error messages

temperature.pas(101,4) Error: Identifier not found "GetTickCount"
temperature.pas(102,9) Error: Identifier not found "GetTickCount"
temperature.pas(105,7) Error: Identifier not found "GetTickCount"
temperature.pas(112,23) Hint: Type size mismatch, possible loss of data / range check error
temperature.pas(143,10) Error: Identifier not found "CreateFile"
temperature.pas(144,21) Error: Identifier not found "GENERIC_READ"
temperature.pas(144,37) Error: Identifier not found "GENERIC_WRITE"
temperature.pas(145,21) Error: Identifier not found "OPEN_EXISTING"
temperature.pas(145,35) Error: Identifier not found "FILE_ATTRIBUTE_NORMAL"
temperature.pas(157,4) Error: Identifier not found "EscapeCommFunction"
temperature.pas(157,30) Error: Identifier not found "CLRDTR"
temperature.pas(158,1) Error: Illegal expression
temperature.pas(162,10) Error: Identifier not found "CreateFile"
temperature.pas(163,21) Error: Identifier not found "GENERIC_READ"
temperature.pas(163,37) Error: Identifier not found "GENERIC_WRITE"
temperature.pas(164,21) Error: Identifier not found "OPEN_EXISTING"
temperature.pas(164,35) Error: Identifier not found "FILE_ATTRIBUTE_NORMAL"
temperature.pas(167,27) Error: method identifier expected
temperature.pas(169,1) Error: Identifier not found "Button7"
temperature.pas(170,3) Error: Identifier not found "closeHandle"
temperature.pas(170,16) Error: Identifier not found "fPort"
temperature.pas(170,22) Error: Illegal expression
temperature.pas(188,6) Error: Identifier not found "EscapeCommFunction"
temperature.pas(188,32) Error: Identifier not found "SETDTR"
temperature.pas(188,39) Error: Illegal expression
temperature.pas(193,12) Error: Identifier not found "GetCommModemStatus"
temperature.pas(193,41) Error: Illegal expression
temperature.pas(200,1) Error: Identifier not found "EscapeCommFunction"
temperature.pas(200,27) Error: Identifier not found "CLRDTR"
temperature.pas(200,34) Error: Illegal expression
temperature.pas(210,27) Hint: Type size mismatch, possible loss of data / range check error
temperature.pas(211,27) Hint: Type size mismatch, possible loss of data / range check error
temperature.pas(213,20) Hint: Type size mismatch, possible loss of data / range check error
temperature.pas(215,16) Hint: Type size mismatch, possible loss of data / range check error
temperature.pas(234,1) Error: Identifier not found "EscapeCommFunction"
temperature.pas(234,27) Error: Identifier not found "SETDTR"
temperature.pas(234,34) Error: Illegal expression
temperature.pas(239,1) Error: Identifier not found "print"
temperature.pas(239,6) Error: Illegal expression
temperature.pas(245,1) Error: Identifier not found "GetCommModemStatus"
temperature.pas(245,30) Error: Illegal expression
temperature.pas(255,10) Error: Identifier not found "CreateFile"
temperature.pas(256,21) Error: Identifier not found "GENERIC_READ"
temperature.pas(256,37) Error: Identifier not found "GENERIC_WRITE"
temperature.pas(257,21) Error: Identifier not found "OPEN_EXISTING"
temperature.pas(257,35) Error: Identifier not found "FILE_ATTRIBUTE_NORMAL"
temperature.pas(270,1) Error: Identifier not found "print"
temperature.pas(270,6) Error: Illegal expression
temperature.pas(278) Fatal: There were 43 errors compiling module, stopping

Can anyone help me debug and correct my code so that it can execute in Lazarus?Please reply as soon as possible and I shall be infinitely grateful.Thanks in advance.

antonio

  • Hero Member
  • *****
  • Posts: 605
RE: How can one write serial programming code in Lazarus
« Reply #1 on: September 08, 2007, 04:49:54 pm »
Put mode Delphi directive as follows:

{$MODE Delphi}
//{$mode objfpc}{$H+}

Could you be more specific? Can you compile the program on Lazarus? Which error messages do you receive?

Saranezhil

  • Newbie
  • Posts: 2
Delphi 2 Lazarus
« Reply #2 on: September 10, 2008, 09:29:55 am »
Convert Delphi to Lazarus tools is only include  these codes
{$mode objfpc}{$H+}

 {$I unit1.lrs}, to open the project it Lazarus IDE. But it doesnot work.

The best way is  create new appl in Lazarus  and create all component as new, then copy code and paste it lazarus. it works fine.

For Serial port, i am trying to use this synapse.

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3541
RE: Delphi 2 Lazarus
« Reply #3 on: September 10, 2008, 03:34:37 pm »
I have created a very short tutorial which explains how to use serial port with synaser here:

http://wiki.lazarus.freepascal.org/Hardware_Access#Serial_Communication

windy

  • Full Member
  • ***
  • Posts: 186
RE: Delphi 2 Lazarus
« Reply #4 on: September 16, 2008, 12:39:04 am »
thanks for doing that :)
i am trying it out on a Mac Powerpc....that is not happy compiling synaser.pas, complains about identifier not found, TStream ....in the sendstream function...
maybe synaser is not going to work on a powerpc, because of archtectural differences, anyway?

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3541
Re: How can one write serial programming code in Lazarus
« Reply #5 on: February 11, 2009, 03:44:51 pm »
I think it should work. About the TStream problem, probably classes is missing from the uses clause for PowerPC architecture. Maybe some ifdef left it out. I would suggest you to just try to fix the compilation error and tell the authors how to fix it too.

Often libraries work after some quick compilation error fix.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8244
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How can one write serial programming code in Lazarus
« Reply #6 on: February 12, 2009, 05:21:38 am »
Quote
Unfortunately,Lazarus does not recognize the syntax  used to manipulate the serial port
Which procedure? The ReadPort one? Unit x86 has ReadPort implemented, try using that one instead.
Quote
Despite converting the code to Lazarus,I still getthe following error messages
That's because the code you wrote is Windows specific (CreateFile, GENERIC_WRITE, etc.). Replace with platform independent implementation in SysUtils (and perhaps LCL's FileUtil, too) unit.

I'm not sure about those *Comm* replacements. I think you should use Synaser at last 8-).

Paul Breneman

  • Sr. Member
  • ****
  • Posts: 290
    • Control Pascal
Re: How can one write serial programming code in Lazarus
« Reply #7 on: February 13, 2009, 01:14:33 am »
Quote
I'm not sure about those *Comm* replacements. I think you should use Synaser at last 8-).

Yesterday I put 3 files on a site that contain the minimum files needed to compile a "Simple Serial" application using SynaSer:
  http://www.turbocontrol.com/simpleserial.htm
Regards,
Paul Breneman
www.ControlPascal.com

 

TinyPortal © 2005-2018