CAN_terminal/CAN_Terminal.pas

690 lines
16 KiB
ObjectPascal

unit CAN_Terminal;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, IniFiles, UNiiefa, ToolsCan, RXSwitch,
ComCtrls, Buttons, OoMisc, AdPort, Mask, RXSpin, RXCtrls;
type
TCANTerminal = class(TForm)
ProjectBox: TComboBox;
GroupBox: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
CanTimer: TTimer;
Memo1: TMemo;
CANswitch: TRxSwitch;
GroupBox1: TGroupBox;
CBLockRS: TCheckBox;
RxLabel2: TRxLabel;
RCom: TRxSpinEdit;
RGBaud: TRadioGroup;
MyCommPort: TApdComPort;
RxLabel6: TRxLabel;
TimeWait: TRxSpinEdit;
AbortKey: TSpeedButton;
PBRs: TProgressBar;
Memo2: TMemo;
RadioGroup1: TRadioGroup;
Button125: TRadioButton;
Button250: TRadioButton;
RxLabel1: TRxLabel;
procedure FormCreate(Sender: TObject);
procedure LoadProjectAdres(ProjID: string);
procedure ShowProjectAdres();
procedure ShoWinClick(Sender: TObject);
procedure CanTimerTimer(Sender: TObject);
procedure CANswitchClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure RGBaudClick(Sender: TObject);
procedure RComChange(Sender: TObject);
procedure CBLockRSClick(Sender: TObject);
procedure Memo2Change(Sender: TObject);
procedure ProjectBoxChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TBar = record
RSadr: TPanel;
RXadr: TPanel;
TXadr: TPanel;
Name: TPanel;
Go: TButton;
end;
TUKSS = record
Bar: TBar;
RSadr: cardinal;
RXadr: longword;
TXadr: longword;
Use: boolean;
Exist: boolean;
Name: string;
Wind: TModbusForm;
end;
TBars = record
BaseAdr: TPanel;
CommAdr: TPanel;
Name: TPanel;
end;
TProject = record
Bars: TBars;
BaseAdr: longword;
PlusAdr: integer;
CommAdr: longword;
UKSS: array[0..16] of TUKSS;
Name: string;
DigiButNames: array[0..16] of string;
DigiButNameChange: boolean;
Protokol: integer;
end;
Tbox = record
adr: longword;
qua: cardinal;
end;
Tboxx = record
box : array[1..100] of Tbox; // edit boxlen!
qua: cardinal;
end;
var
CANTerminal: TCANTerminal;
Project : TProject;
PathExe : String;
ProjectQua : integer = 0;
ProjectNum : integer = 0;
Boxx : Tboxx;
const
boxlen = 100;
implementation
{$R *.dfm}
procedure TCANTerminal.FormCreate(Sender: TObject);
var i: integer;
inifile : TIniFile;
nom,num: string;
wid,hei,tab,lef,top,lev : integer;
begin
InitSlavnaDll();
Project.Bars.Name := TPanel.Create(self);
Project.Bars.Name.Parent := GroupBox;
Project.Bars.Name.Left :=10;
Project.Bars.Name.Top :=15;
Project.Bars.Name.Width :=100;
Project.Bars.Name.Height := 30;
Project.Bars.BaseAdr := TPanel.Create(self);
Project.Bars.BaseAdr.Parent := GroupBox;
Project.Bars.BaseAdr.Left :=10+100+10;
Project.Bars.BaseAdr.Top :=15;
Project.Bars.BaseAdr.Width :=100;
Project.Bars.BaseAdr.Height := 30;
Project.Bars.CommAdr := TPanel.Create(self);
Project.Bars.CommAdr.Parent := GroupBox;
Project.Bars.CommAdr.Left :=10+100+10+100+10;
Project.Bars.CommAdr.Top :=15;
Project.Bars.CommAdr.Width :=100;
Project.Bars.CommAdr.Height := 30;
tab:=5;
Label1.Top := Project.Bars.Name.Top + Project.Bars.Name.Height + tab*3;
Label2.Top := Label1.Top; Label3.Top := Label1.Top; Label4.Top := Label1.Top;
Label5.Top := Label1.Top; Label6.Top := Label1.Top; Label7.Top := Label1.Top;
Label8.Top := Label1.Top; Label9.Top := Label1.Top; Label10.Top := Label1.Top;
for i:= 0 to 16 do
begin
hei := 25;
top := Label1.Top + Label1.Height + tab + (hei+tab)*((i mod 8)+8*(i div 16));
lef := 10 + ((i div 8) and 1)*(lev);
wid := hei;
Project.UKSS[i].Bar.RSadr := TPanel.Create(self);
Project.UKSS[i].Bar.RSadr.Parent := GroupBox;
Project.UKSS[i].Bar.RSadr.Width := wid;
Project.UKSS[i].Bar.RSadr.Height := hei;
Project.UKSS[i].Bar.RSadr.Left :=lef;
Project.UKSS[i].Bar.RSadr.Top :=top;
if i=0 then Label1.Left := lef;
if i=8 then Label6.Left := lef;
lef := lef + wid + tab;
wid := 110;
Project.UKSS[i].Bar.Name := TPanel.Create(self);
Project.UKSS[i].Bar.Name.Parent := GroupBox;
Project.UKSS[i].Bar.Name.Width :=wid;
Project.UKSS[i].Bar.Name.Height := hei;
Project.UKSS[i].Bar.Name.Left :=lef;
Project.UKSS[i].Bar.Name.Top :=top;
if i=0 then Label2.Left := lef;
if i=8 then Label7.Left := lef;
lef := lef + wid + tab;
wid := 90;
Project.UKSS[i].Bar.RXadr := TPanel.Create(self);
Project.UKSS[i].Bar.RXadr.Parent := GroupBox;
Project.UKSS[i].Bar.RXadr.Width :=wid;
Project.UKSS[i].Bar.RXadr.Height := hei;
Project.UKSS[i].Bar.RXadr.Left :=lef;
Project.UKSS[i].Bar.RXadr.Top :=top;
if i=0 then Label3.Left := lef;
if i=8 then Label8.Left := lef;
lef := lef + wid + tab;
wid := 90;
Project.UKSS[i].Bar.TXadr := TPanel.Create(self);
Project.UKSS[i].Bar.TXadr.Parent := GroupBox;
Project.UKSS[i].Bar.TXadr.Width :=wid;
Project.UKSS[i].Bar.TXadr.Height := hei;
Project.UKSS[i].Bar.TXadr.Left :=lef;
Project.UKSS[i].Bar.TXadr.Top :=top;
if i=0 then Label4.Left := lef;
if i=8 then Label9.Left := lef;
lef := lef + wid + tab;
wid := hei;
Project.UKSS[i].Bar.Go := TButton.Create(self);
Project.UKSS[i].Bar.Go.Parent := GroupBox;
Project.UKSS[i].Bar.Go.Width :=wid;
Project.UKSS[i].Bar.Go.Height := hei;
Project.UKSS[i].Bar.Go.Left :=lef;
Project.UKSS[i].Bar.Go.Top :=top;
Project.UKSS[i].Bar.Go.Caption :='S';
Project.UKSS[i].Bar.Go.Font.Style:=[fsBold];
Project.UKSS[i].Bar.Go.Tag := i;
Project.UKSS[i].Bar.Go.OnClick := ShoWinClick;
if i=0 then Label5.Left := lef;
if i=8 then Label10.Left := lef;
if i<8 then lev := lef + wid + tab*2;
end;
PathExe:=ExtractFileDir(ParamStr(0))+'\';
inifile := TIniFile.Create(PathExe+'Projects.ini');
ProjectQua := Inifile.ReadInteger('Projects','ProjectQua',0);
ProjectNum := Inifile.ReadInteger('Projects','ProjectNum',0);
for i:=1 to ProjectQua do
begin
Num := 'Project'+inttostr(i);
Nom := Inifile.ReadString('Projects',Num,Num);
ProjectBox.Items.add(Nom);
end;
inifile.Free;
Project.Name := ProjectBox.Items[ProjectNum];
ProjectBox.ItemIndex := ProjectNum;
ProjectBoxChange(Sender);
end;
procedure TCANTerminal.ShowProjectAdres();
var
i: integer;
begin
Project.Bars.Name.Caption := Project.Name;
Project.Bars.BaseAdr.Caption := '0x'+inttohex(Project.BaseAdr,8);
if Project.CommAdr = 0
then Project.Bars.CommAdr.Caption := ''
else Project.Bars.CommAdr.Caption := '0x'+inttohex(Project.CommAdr,8);
for i:=0 to 16 do
begin
Project.UKSS[i].Bar.RXadr.Tag:=0;
Project.UKSS[i].Bar.TXadr.Tag:=0;
if Project.UKSS[i].Use then
begin
Project.UKSS[i].Bar.RSadr.Caption := inttostr(Project.UKSS[i].RSadr);
Project.UKSS[i].Bar.RXadr.Caption := '0x' + inttohex(Project.UKSS[i].RXadr,8);
Project.UKSS[i].Bar.TXadr.Caption := '0x' + inttohex(Project.UKSS[i].TXadr,8);
Project.UKSS[i].Bar.Name.Caption := Project.UKSS[i].Name;
Project.UKSS[i].Bar.Go.Caption := 'S';
Project.UKSS[i].Bar.Go.Enabled:=true;
Project.UKSS[i].Bar.Name.Color:=clWindow;
Project.UKSS[i].Bar.RSadr.Color:=clWindow;
Project.UKSS[i].Bar.RXadr.Color := clWindow;
Project.UKSS[i].Bar.TXadr.Color := clWindow;
end else
begin
Project.UKSS[i].Bar.RSadr.Caption := '';
Project.UKSS[i].Bar.RXadr.Caption := '';
Project.UKSS[i].Bar.TXadr.Caption := '';
Project.UKSS[i].Bar.Name.Caption := '';
Project.UKSS[i].Bar.Go.Caption := '';
Project.UKSS[i].Bar.Go.Enabled:=false;
Project.UKSS[i].Bar.Name.Color:=clBtnFace;
Project.UKSS[i].Bar.RSadr.Color:=clBtnFace;
Project.UKSS[i].Bar.RXadr.Color := clBtnFace;
Project.UKSS[i].Bar.TXadr.Color := clBtnFace;
end;
end;
end;
procedure TCANTerminal.LoadProjectAdres(ProjID: string);
var i,adr: integer;
inifile : TIniFile;
nom,nym: string;
num: longword;
left: integer;
begin
inifile := TIniFile.Create(PathExe+'Projects.ini');
Project.Protokol := Inifile.ReadInteger(ProjID,'Protokol',0);
if Project.Protokol = 3 then
begin
Project.BaseAdr := 0;
Project.PlusAdr := 1 shl 28;
left:=20;
end else begin
Project.BaseAdr := Inifile.ReadInteger(ProjID,'BaseAdr',0);
Project.PlusAdr := Inifile.ReadInteger(ProjID,'PlusAdr',16);
left:=0;
end;
Project.CommAdr := Inifile.ReadInteger(ProjID,'CommAdr',0);
adr:=-1;
for i:=0 to 16 do
begin
nom := 'Use_'+inttostr(i);
Project.UKSS[i].Use := inifile.ReadBool(ProjID,nom,false);
if Project.UKSS[i].Use then
begin
nom := 'CANadr_'+inttostr(i);
adr := inifile.ReadInteger(ProjID,nom,adr+1);
nom := 'RSadr_'+inttostr(i);
Project.UKSS[i].RSadr := inifile.ReadInteger(ProjID,nom,i);
nom := 'TXadr_'+inttostr(i);
num := Project.BaseAdr+Project.PlusAdr+(adr shl left);
Project.UKSS[i].TXadr := inifile.ReadInteger(ProjID,nom,num);
nom := 'RXadr_'+inttostr(i);
num := Project.BaseAdr+(adr shl left);
Project.UKSS[i].RXadr := inifile.ReadInteger(ProjID,nom,num);
nom := 'Name_'+inttostr(i);
nym := 'UKSS_'+inttostr(i);
Project.UKSS[i].Name := inifile.ReadString(ProjID,nom,nym);
end;
end;
inifile.Free;
ShowProjectAdres();
end;
procedure TCANTerminal.ShoWinClick(Sender: TObject);
var
Tagg : integer;
begin
Tagg:= (Sender as TButton).Tag;
if not Project.UKSS[Tagg].Exist then
begin
Project.UKSS[Tagg].Wind := TModbusForm.Create(nil);
Project.UKSS[Tagg].Wind.Caption := Project.Name+': '+Project.UKSS[Tagg].Name;
Project.UKSS[Tagg].Wind.Numer:= Tagg;
Project.UKSS[Tagg].Wind.RSadr:= Project.UKSS[Tagg].RSadr;
Project.UKSS[Tagg].Wind.RXadr:= Project.UKSS[Tagg].RXadr;
Project.UKSS[Tagg].Wind.TXadr:= Project.UKSS[Tagg].TXadr;
Project.UKSS[Tagg].Wind.Protokol:= Project.Protokol;
Project.UKSS[Tagg].Exist := true;
end;
Project.UKSS[Tagg].Wind.show;
end;
procedure TCANTerminal.CanTimerTimer(Sender: TObject);
var
i,j,pak, paks : integer;
newstring: string;
adr: longword;
Mess: Tmessag;
begin
paks :=ReadMessageCanID(CanTimer.Interval);
if paks > 0 then
begin
for pak := 0 to paks-1 do
begin
if Project.Protokol=3
then adr := ArrCanMessage[pak].m_dwID and $1FF00000
else adr := ArrCanMessage[pak].m_dwID;
if boxx.qua = 0 then
begin
boxx.qua := 1;
boxx.box[1].qua := 1;
boxx.box[1].adr := adr;
end else
begin
i:=0;
repeat i:=i+1
until (boxx.box[i].adr = adr) or (i > boxx.qua);
if i <= boxx.qua then
begin
boxx.box[i].qua := boxx.box[i].qua + 1;
if boxx.box[i].qua > 1000 then
begin
boxx.qua := 1;
boxx.box[1].qua := 1;
boxx.box[1].adr := adr;
end else
begin
if i > 1 then
begin
if boxx.box[i].qua > boxx.box[i-1].qua then
begin
boxx.box[i].adr := boxx.box[i-1].adr;
boxx.box[i-1].adr := adr;
boxx.box[i-1].qua := boxx.box[i].qua;
boxx.box[i].qua := boxx.box[i].qua-1;
end
end
end
end else
begin
if i > boxlen then
begin
boxx.qua := 1;
boxx.box[1].qua := 1;
boxx.box[1].adr := adr;
end else
begin
boxx.qua := i;
boxx.box[i].qua := 1;
boxx.box[i].adr := adr;
end
end
end;
for i:=0 to 16 do
begin
if Project.UKSS[i].Use then
begin
if Project.UKSS[i].RXadr = adr then
begin
Project.UKSS[i].Bar.RXadr.Color := $FFD0A0; //clMoneyGreen;
Project.UKSS[i].Bar.RXadr.Tag := 5000 div CANTimer.Interval;
end;
if Project.UKSS[i].TXadr = adr then
begin
Project.UKSS[i].Bar.TXadr.Color := $A0FFC0; //clMoneyGreen;
Project.UKSS[i].Bar.TXadr.Tag := 5000 div CANTimer.Interval;
end;
if (Project.UKSS[i].RXadr = adr)
or (Project.UKSS[i].TXadr = adr) then
begin
if project.Protokol = 3 then
begin
mess.Leng := ArrCanMessage[pak].m_bDLC shr 1;
mess.Addr := ArrCanMessage[pak].m_dwID and $0000007F;
mess.Mask := $FF;
mess.Data[0] := ArrCanMessage[pak].m_bData[1] shl 8;
mess.Data[0] := ArrCanMessage[pak].m_bData[2] or mess.Data[0];
mess.Data[1] := ArrCanMessage[pak].m_bData[3] shl 8;
mess.Data[1] := ArrCanMessage[pak].m_bData[4] or mess.Data[1];
mess.Data[2] := ArrCanMessage[pak].m_bData[5] shl 8;
mess.Data[2] := ArrCanMessage[pak].m_bData[6] or mess.Data[2];
mess.Data[3] := ArrCanMessage[pak].m_bData[7] shl 8;
mess.Data[3] := ArrCanMessage[pak].m_bData[8] or mess.Data[3];
end else begin
mess.Mask := ArrCanMessage[pak].m_bData[5] shr 5;
mess.Addr :=(ArrCanMessage[pak].m_bData[5] and $1F) shl 8;
mess.Addr := ArrCanMessage[pak].m_bData[6] or mess.Addr;
mess.Leng := 3;
mess.Data[0] := ArrCanMessage[pak].m_bData[7] shl 8;
mess.Data[0] := ArrCanMessage[pak].m_bData[8] or mess.Data[0];
mess.Data[1] := ArrCanMessage[pak].m_bData[1] shl 8;
mess.Data[1] := ArrCanMessage[pak].m_bData[2] or mess.Data[1];
mess.Data[2] := ArrCanMessage[pak].m_bData[3] shl 8;
mess.Data[2] := ArrCanMessage[pak].m_bData[4] or mess.Data[2];
end;
if(Project.UKSS[i].TXadr = adr) then mess.Surs := 0;
if(Project.UKSS[i].RXadr = adr) then mess.Surs := 1;
if Project.UKSS[i].Exist then
Project.UKSS[i].Wind.ReceiveCanData(mess,i);
end
end
end
end;
newstring:='';
for i:= 1 to boxx.qua do
newstring:= newstring +
'0x'+ inttohex(boxx.box[i].adr,8) +
'(' + inttostr(boxx.box[i].qua) + ') ';
Memo1.Clear;
Memo1.Lines[0] := newstring;
end;
if CANswitch.StateOn then
for i:=0 to 16 do
if Project.UKSS[i].Use then
begin
if Project.UKSS[i].Bar.RXadr.Tag = 0
then Project.UKSS[i].Bar.RXadr.Color := clWindow
else
begin
Project.UKSS[i].Bar.RXadr.Tag := Project.UKSS[i].Bar.RXadr.Tag - 1;
if Project.UKSS[i].Bar.RXadr.Tag < 4000 div CANTimer.Interval
then Project.UKSS[i].Bar.RXadr.Color := $F0E0D0;
end;
if Project.UKSS[i].Bar.TXadr.Tag = 0
then Project.UKSS[i].Bar.TXadr.Color := clWindow
else
begin
Project.UKSS[i].Bar.TXadr.Tag := Project.UKSS[i].Bar.TXadr.Tag - 1;
if Project.UKSS[i].Bar.TXadr.Tag < 4000 div CANTimer.Interval
then Project.UKSS[i].Bar.TXadr.Color := $D0F0E0;
end
end;
end;
procedure TCANTerminal.CANswitchClick(Sender: TObject);
var
i: integer;
begin
if CANswitch.StateOn then
begin
if Button125.Checked then OpenSlavna(1,8);
if Button250.Checked then OpenSlavna(2,8);
CanTimer.Enabled:=true;
end else
begin
CloseSlavna();
CanTimer.Enabled:=false;
boxx.qua := 0;
for i:=0 to 16 do
begin
Project.UKSS[i].Bar.RXadr.Color := clBtnFace;
Project.UKSS[i].Bar.TXadr.Color := clBtnFace;
end;
end;
end;
procedure TCANTerminal.FormClose(Sender: TObject;
var Action: TCloseAction);
var i: integer;
inifile : TIniFile;
nom: string;
begin
if Project.DigiButNameChange then
begin
inifile := TIniFile.Create(PathExe+'Projects.ini');
for i:=0 to 16 do
begin
nom := 'DigiBut_'+inttostr(i);
inifile.WriteString(Project.Name,nom,Project.DigiButNames[i]);
end;
inifile.Free;
end;
CloseSlavna();
FreeSlavnaDll();
end;
procedure TCANTerminal.RGBaudClick(Sender: TObject);
begin
if RGBaud.ItemIndex=0 then MyCommPort.Baud:=57600;
if RGBaud.ItemIndex=1 then MyCommPort.Baud:=115200;
end;
procedure TCANTerminal.RComChange(Sender: TObject);
begin
MyCommPort.Open:=False;
MyCommPort.ComNumber:= Round(RCom.Value);
end;
procedure TCANTerminal.CBLockRSClick(Sender: TObject);
begin
MyCommPort.Open := CBLockRS.Checked;
end;
procedure TCANTerminal.Memo2Change(Sender: TObject);
begin
if Memo1.Lines.Count > 100 then Memo1.Clear;
end;
procedure TCANTerminal.ProjectBoxChange(Sender: TObject);
var i : integer;
inifile : TIniFile;
nom, num: string;
begin
for i:=0 to 16 do
if Project.UKSS[i].Exist then
begin
Project.UKSS[i].Wind.Close;
Project.UKSS[i].Exist:=false;
end;
Project.Name := ProjectBox.Items[ProjectBox.ItemIndex];
if ProjectBox.ItemIndex >0 then
LoadProjectAdres(Project.Name);
inifile := TIniFile.Create(PathExe+'Projects.ini');
nom:='ProjectNum';
num:=inttostr(ProjectBox.ItemIndex);
inifile.WriteString('Projects',nom,num);
for i:=0 to 16 do
begin
num := 'DigiBut_'+inttostr(i);
Project.DigiButNames[i] := inifile.ReadString(Project.Name,num,'-');
end;
Project.DigiButNameChange := false;
inifile.Free;
boxx.qua:=0;
for i:= 1 to 100 do
begin
boxx.box[i].adr:=0;
boxx.box[i].qua:=0;
end;
end;
end.