Seri port kullanım örneği (PLC-PC)

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Cevapla
Kullanıcı avatarı
mege
Admin
Mesajlar: 2360
Kayıt: 05 Şub 2004 04:32
Konum: Beşiktaş
İletişim:

Seri port kullanım örneği (PLC-PC)

Mesaj gönderen mege »

geçenlerde bunu hocaya ödev olarak verdim :) belki birinin işine yarar
ödev konusu şu bilgisayar kontrollü bir depo izleme sistemi var. Burada PLC'den

gelen bilgiler ekranda gösterilecek. ve ekranda basılan valf PLC tarafında

açılacak gibi birşey işte.

Omron CQM1H serisi için haberleşme protokolü :
Resim

Programın arayüzü:
Resim

Kullanılan Komponentler :
Cport v3.0, LMDTools v6.11, Delphi 7

Kod: Tümünü seç

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, CPort, StdCtrls, ExtCtrls, CPortCtl, LMDCustomComponent,
  LMDWndProcComponent, LMDCustomFormFill, LMDFormFill, Buttons, LMDControl,
  LMDBaseControl, LMDBaseGraphicControl, LMDBaseLabel,
  LMDCustomSimpleLabel, LMDSimpleLabel, LMDGraphicControl,
  LMDBaseMeter, LMDCustomProgressFill, LMDProgressFill, LMDBaseShape,
  LMDShapeControl, LMDShadowFill, LMDLEDCustomLabel, LMDLEDLabel,
  LMDScrollText;

type
  TForm1 = class(TForm)
    ComPort1: TComPort;
    TimerPLCRead: TTimer;
    Panel1: TPanel;
    ComLed1: TComLed;
    ComLed2: TComLed;
    ComLed3: TComLed;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    LMDFormFill1: TLMDFormFill;
    BitBtn1: TBitBtn;
    Memo2: TMemo;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    LMDSimpleLabel1: TLMDSimpleLabel;
    LMDSimpleLabel2: TLMDSimpleLabel;
    LMDProgressFill1: TLMDProgressFill;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    LMDShapeControl1: TLMDShapeControl;
    Image4: TImage;
    Image5: TImage;
    LMDSimpleLabel3: TLMDSimpleLabel;
    LMDSimpleLabel4: TLMDSimpleLabel;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    LMDShapeControl2: TLMDShapeControl;
    LMDSimpleLabel5: TLMDSimpleLabel;
    LMDLEDLabel1: TLMDLEDLabel;
    LMDSimpleLabel6: TLMDSimpleLabel;
    LMDLEDLabel2: TLMDLEDLabel;
    LMDSimpleLabel7: TLMDSimpleLabel;
    LMDShadowFill1: TLMDShadowFill;
    LMDSimpleLabel8: TLMDSimpleLabel;
    Image6: TImage;
    Image7: TImage;
    Image8: TImage;
    LMDSimpleLabel9: TLMDSimpleLabel;
    LMDSimpleLabel10: TLMDSimpleLabel;
    LMDProgressFill2: TLMDProgressFill;
    SpeedButton5: TSpeedButton;
    SpeedButton6: TSpeedButton;
    LMDShapeControl3: TLMDShapeControl;
    LMDLEDLabel3: TLMDLEDLabel;
    LMDSimpleLabel14: TLMDSimpleLabel;
    LMDLEDLabel4: TLMDLEDLabel;
    LMDSimpleLabel15: TLMDSimpleLabel;
    LMDShadowFill2: TLMDShadowFill;
    LMDSimpleLabel16: TLMDSimpleLabel;
    Image11: TImage;
    LMDSimpleLabel11: TLMDSimpleLabel;
    Image9: TImage;
    Image10: TImage;
    LMDSimpleLabel17: TLMDSimpleLabel;
    LMDSimpleLabel18: TLMDSimpleLabel;
    SpeedButton7: TSpeedButton;
    SpeedButton8: TSpeedButton;
    LMDShapeControl4: TLMDShapeControl;
    Image12: TImage;
    Image13: TImage;
    Image14: TImage;
    Label4: TLabel;
    Label5: TLabel;
    LMDSimpleLabel12: TLMDSimpleLabel;
    LMDSimpleLabel13: TLMDSimpleLabel;
    procedure FormCreate(Sender: TObject);
    procedure TimerPLCReadTimer(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    Function hexToInt(hexStr: string): longint;
    procedure VarstoEdits;
    procedure SpeedButton4Click(Sender: TObject);
    procedure Panel1Click(Sender: TObject);
  private
    cSendBuffer        : PChar;   // Gönderilecek verinin tutulduğu buffer değişken
    cRcvBuffer         : PChar;   // Gelen verinin tutulduğu buffer değişken
    CharCntReceived    : Integer; // Porta gelen veri sayısı
    iErrorCount        : integer; // Cevap alamama sayısı
    myReadOnlyDMArea   : array [0..14] of Word; // PLC DM areasının aynası
    procedure CalcCRC(sStr:PChar;iLength :Integer; var Fcs1,Fcs2:Char);
    Function  CheckCRC(sStr:PChar;iLength :Integer): Boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.dfm}


{--------------------------------------------------------------------------}
procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
 cRcvBuffer := StrAlloc(512);
 cSendBuffer := StrAlloc(512);
 for i:=0 to 511 do cSendBuffer[i] := #0;
 for i:=0 to 14 do myReadOnlyDMArea[i]:=0;
 CharCntReceived := 0;
 iErrorCount := 3;
 comport1.Connected:=TRUE;
 comport1.ClearBuffer(TRUE,TRUE);
 TimerPLCRead.Enabled := TRUE;
end;
{--------------------------------------------------------------------------}
{Tform1.FormClose}
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 // Program kapatılmadan önce timer ve seri port kapatılmalı.
 // Seri portta çıkan bir hatadan dolayı kapatmadan önce Clearbuffer ile  temizlenmesi lazım
 TimerPLCRead.Enabled:=FALSE;
 comport1.ClearBuffer(TRUE,TRUE);
 //comport1.Connected:=FALSE;
 Close;
end;


{--------------------------------------------------------------------------}
// Tüm SpeedButtonlar Bu Fonksiyna Bağlı
(*
 DM 4: Vana ve Pompa Açma Komutu
    0001 : Output 100.0  Depo 2 - Çıkış Valfi-Pompa
    0010 : Output 100.1  Depo 2 - Giriş Valfi
    0100 : Output 100.2  Depo 1 - Çıkış Valfi-Pompa
    1000 : Output 100.3  Depo 1 - Giriş Valfi
*)
procedure TForm1.SpeedButton4Click(Sender: TObject);
var cFcs1 , cFcs2:Char;
begin
try
  cSendBuffer[0] := '@';
  cSendBuffer[1] := '0';
  cSendBuffer[2] := '0';
  cSendBuffer[3] := 'W';
  cSendBuffer[4] := 'D';
  cSendBuffer[5] := '0';
  cSendBuffer[6] := '0';
  cSendBuffer[7] := '0';
  cSendBuffer[8] := '4';

  if SpeedButton1.Down then cSendBuffer[9] := '1' else cSendBuffer[9] := '0';
  if SpeedButton3.Down then cSendBuffer[10] := '1' else cSendBuffer[10] := '0';
  if SpeedButton5.Down then cSendBuffer[11] := '1' else cSendBuffer[11] := '0';
  if SpeedButton7.Down then cSendBuffer[12] := '1' else cSendBuffer[12] := '0';
  CalcCRC(@cSendBuffer[0], 13, cFcs1, cFcs2);
  cSendBuffer[13] := cFcs1;
  cSendBuffer[14] := cFcs2;
  cSendBuffer[15] := '*';                        
  cSendBuffer[16] := #13;
  cSendBuffer[17] := #0;
  label4.Caption:= cSendBuffer;
  comport1.WriteStr(cSendBuffer);
  iErrorCount:= 4;
finally
//TimerPLCRead.Enabled:=TRUE;
end;
end;

{--------------------------------------------------------------------------}
procedure TForm1.TimerPLCReadTimer(Sender: TObject);
var PacketOK  : boolean;
    LastCount : integer;
    y         : integer;
begin
inc(iErrorCount);

// Porttan tampona gelen veriyi alır ve tampon değişkene aktarır.
// Eğer AsyncPro bileşenleri kullanılacak ise bu iki satır siline aşağıdaki ek yapıla
LastCount := comport1.read(cRcvBuffer[CharCntReceived],512);
CharCntReceived := CharCntReceived + LastCount;

PacketOK := ((CharCntReceived = 65 ) and (cRcvBuffer[0] = '@') and (cRcvBuffer[69] = '*'));
if PacketOK then PacketOK := CheckCRC(@cRcvBuffer[0],67);

 if PacketOK or (iErrorCount > 5 ) then
  begin
    //Eğer packet sağlam ise stringi parse et..
      if PacketOK then
      begin
        for y:=0 to 14 do myReadOnlyDMArea[y] := hexToInt(Uppercase(copy(cRcvBuffer,8+(y*4),4)));
        VarsToEdits;
      end;
    // Bufferi temizle ve PLC'den yeni paket veri iste
    iErrorCount:=0;
    CharCntReceived := 0;
    comport1.WriteStr('@00RD0000001552*'+#13+#0);
  end;
end;


{--------------------------------------------------------------------------}
(*<<<>>><<<>>>DM Area Map<<<>>><<<>>>
 DM 0  : Depo 1 Analog Sıcaklık Bilgisi
 DM 1  : Depo 1 Analog Basınç Bilgisi
 DM 2  : Depo 2 Analog Sıcaklık Bilgisi
 DM 3  : Depo 2 Analog Basınç Bilgisi
<<<>>><<<>>>DM Area Map<<<>>><<<>>>*)
procedure Tform1.VarstoEdits;
var tempStr : string;
    y : integer;
begin
//<<<>>><<<>>>DEPO 1 için<<<>>><<<>>>
//Sıcaklık
tempStr:= Floattostrf(((myReadOnlyDMArea[0]*200/65535)-100),fffixed,8,1);
while length(tempStr)<6 do
  tempStr:= ' '+tempStr;
LMDLEDLabel1.Caption := tempStr+' C';
//Basınçtan miktar
LMDProgressFill1.UserValue := myReadOnlyDMArea[1];
tempStr:= Floattostrf(((myReadOnlyDMArea[1]*4000/65535)),fffixed,8,1);
while length(tempStr)<6 do
  tempStr:= ' '+tempStr;
LMDLEDLabel2.Caption := tempStr+' L';

//<<<>>><<<>>>DEPO 2 için<<<>>><<<>>>
//Sıcaklık
tempStr:= Floattostrf(((myReadOnlyDMArea[2]*200/65535)-100),fffixed,8,1);
while length(tempStr)<6 do
  tempStr:= ' '+tempStr;
LMDLEDLabel3.Caption := tempStr+' C';
//Basınçtan miktar
LMDProgressFill2.UserValue := myReadOnlyDMArea[3];
tempStr:= Floattostrf(((myReadOnlyDMArea[3]*4000/65535)),fffixed,8,1);
while length(tempStr)<6 do
  tempStr:= ' '+tempStr;
LMDLEDLabel4.Caption := tempStr+' L';

//Memo2 gelen DM bilgilerini ekranda göstermek için kullanılır.
//Memo2 LED panele tıklayınca açılır.
if memo2.Visible then
 begin
  memo2.Lines.Clear;
  for y:=0 to 14 do
  memo2.Lines.Add('DM'+inttostr(y)+' = ' + inttostr(myReadOnlyDMArea[y]));
 end;

end;


(*
--------------------------------------------------------------------------
-------------------------- YARDIMCI FONKSIYONLAR -------------------------
--------------------------------------------------------------------------
HexToInt : girilen Hexadesimal sayıyı integera çevirir
CalcCRC  : girilem Length uzunluğunda pchar stringin 16bit CRC kodunu hesaplar
ChechkCRC: girilen Length uzunluğunda pchar stringin 16bit CRC kodunu hesaplar
           ve verilen CRC kodu ile karşılaştırır, doğru ise TRUE döner.
*)

Function Tform1.hexToInt(hexStr: string): longint;
var iErr:integer;
begin
  Result := 0;
  Val('$' + hexStr,Result , iErr);
end;

{--------------------------------------------------------------------------}
procedure TForm1.CalcCRC(sStr:PChar;iLength :Integer;var Fcs1,Fcs2:Char);
var cFcs, cTmpFcs:Byte;
    i:Integer;
begin
cFcs := 0;
for i := 0 to iLength-1 do
    cFcs := cFcs XOR ORD(sStr[i]);
cTmpFcs := cFcs AND $0f;
Fcs2:=CHAR(cTmpFcs+$30);
end;
{--------------------------------------------------------------------------}
Function TForm1.CheckCRC(sStr:PChar;iLength :Integer): Boolean;
var cFcs1, cFcs2: Char;
begin
result:= FALSE;
CalcCRC(@sStr[0], iLength, cFcs1, cFcs2);
if (cFcs1 = sStr[67]) and (cFcs2 = sStr[68]) then
 Result := TRUE;
end;
{--------------------------------------------------------------------------}

procedure TForm1.Panel1Click(Sender: TObject);
begin
//Memo2 gelen DM bilgilerini ekranda göstermek için kullanılır.
//LED panele tıklayınca açılır.
memo2.Visible := NOT memo2.Visible;
label4.Visible := NOT label4.Visible;
end;

end.

Kod: Tümünü seç

  object ComPort1: TComPort
    BaudRate = br9600
    Port = 'COM1'
    Parity.Bits = prEven
    StopBits = sbTwoStopBits
    DataBits = dbSeven
    Events = [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS, evDSR, 

evError, evRLSD, evRx80Full]
    FlowControl.OutCTSFlow = False
    FlowControl.OutDSRFlow = False
    FlowControl.ControlDTR = dtrDisable
    FlowControl.ControlRTS = rtsDisable
    FlowControl.XonXoffOut = False
    FlowControl.XonXoffIn = False
    Left = 112
    Top = 16
  end

Eğer AsyncPro bileşenleri kullanılacak ise... aşağıdaki fonksiyonu ekleyin.

Kod: Tümünü seç

procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
var LastCount,I : integer;
begin

LastCount:= Count;

for I := 1 to LastCount do
 begin
  cRcvBuffer[CharCntReceived]:= ApdComPort1.GetChar;
  inc(CharCntReceived);
 end;

end;

ve

Kod: Tümünü seç

    ApdComPort1.OutPut := '@00RD0000001552*'+#13+#0;
    //comport1.WriteStr('@00RD0000001552*'+#13+#0);
bu değişiklikleri yapın.

Kod: Tümünü seç

  object ApdComPort1: TApdComPort
    ComNumber = 1
    Baud = 9600
    Parity = pEven
    DataBits = 7
    StopBits = 2
    TraceName = 'APRO.TRC'
    LogName = 'APRO.LOG'
    OnTriggerAvail = ApdComPort1TriggerAvail
    Left = 32
    Top = 32
  end
baloglurecep
Üye
Mesajlar: 261
Kayıt: 21 Tem 2006 04:59
İletişim:

Re: Seri port kullanım örneği (PLC-PC)

Mesaj gönderen baloglurecep »

arkadaşlar cport bileşeni kullanıyoruym. bir seri poıt kullana devrem var. birde kumandası. kumanda 4 tane tuş. var. her tuş ayrı bir parametre gönderiyor. bunları nasıl alaırm program taskbarda çalışcak. pc açıkken başka programlarda aktif olablir ancak ben gelen veriye göre kullanıcının ayarladığı işi yapmasını istiyorum marş çalınması gibi. yada pc yi kapatması gibi. yada pover pointte slayt kontrolleri gibi. yardımcı olurmusunuz.
Cevapla