宣告:這個代碼不是多難,但好在資料還算全,可給部分尚在從事稱重行業的朋友們一個參考,即使代碼無用,或許某些協議你用得上。
代碼共1352行,基于繼承于TCnRS232,其實從SPCOMM也是一樣的(我更早的版本就是基于SPCOMM),只要改幾行代碼就可以了,但從過去的經驗看,用TCnRS232更好,SPCOMM會在某些場景下出問題。
代碼需要發好多次,如果CSDN還如以前一樣限制連續發帖(/回帖)次數,到時還得兄弟們頂一下,我才能繼續發下去。
unit UnitWeighDevCn;
interface
uses
Classes,CnClasses, CnRS232,ExtCtrls,Types,SysUtils,FmtBcd , Dialogs,StrUtils,UnitCRC16B;
type
TDevStatus = record
Weight : Integer; //重量
Steady : Boolean; //重量是否穩定
Connected : Boolean; //是否連接(有串口資料)
end;
TGetWeight = procedure(Sender :TObject ; Weight : Integer;RealDigit :integer ) of object;
TGetRawData = procedure(Sender :TObject ;RawData: Pointer;Length : integer) of object;
TWeighDevCn = class(TCnRS232)
private
FSteady : Boolean; //重量是否穩定
FConnected : Boolean;
RawDataGot : Integer;
CommBuffer : array[1..300] of Byte;
SendBuf : array[1..50] of Byte;
TimerCommCheck : TTimer; //通信檢測的定時器,看看串口資料是否正常。
TimerSteadyCheck : TTimer; //重量穩定判斷定時器。
TimerD2008Send :TTimer; //2014-10-23 李楊 D2008指令模式讀命令
FCheckInterval : Byte; //檢測儀表通訊時間間隔,單位:秒
FWeighTime : TDateTime; //稱重時間
FWeight : Integer; //重量
FDeviation : integer; //重量穩定允許誤差。
FMaxWeight : integer;
FMinWeight :integer;
FDevType : string; //儀表型別。
FGetWeight : TGetWeight;
FGetRawData : TGetRawData;
FNotConnect : TNotifyEvent;
FWeightAndDec:string; //2014-10-23 含有小數點的重量如D2008指令型別重量
FDevAddr : Byte;
procedure D2PlusSetZero(Addr :Char);
procedure D2008FSetZero();
procedure D2PlusReadWt(Addr :Char);
procedure D2008FReadWt();
procedure OnCommCheckTimer(Sender: TObject);
procedure OnSteadyCheckTimer(Sender : TObject);
procedure SendD2008GetValueOrder(Sender : TObject); //2014-10-23 李楊 用于發送獲取2008資料命令
procedure SetCurrWt ( CurrWt : Integer);
procedure SetGetWeight(GetWeightFunc : TGetWeight);
procedure SetGetRawData(GetRawDataFunc : TGetRawData);
procedure SetNotConnect(NotCon : TNotifyEvent);
procedure SetCheckInterval(intval : Byte);
procedure ProcessGotWeight(currWeight,Precision :integer);
function Handle3190(CommBuffer:Pointer;Length:integer):Boolean;
function HandleDI_880(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleDS822_D(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleXK3190D2(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleXK3190D2InstructMode(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleD2008F(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleD2002(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleD2002E(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleD2002E_2(CommBuffer:Pointer;Length:integer):Boolean ; //新疆和靜碰到怪的協議
function HandleWS822_A(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleT800(CommBuffer:Pointer;Length:integer):Boolean ;
function HandleHT9800_B(CommBuffer:Pointer;Length:integer):Boolean;
function Handle8142ProPlus(CommBuffer:Pointer;Length:integer):Boolean ;
//2008年5月4日 新增型別。
function HandleXK3102(CommBuffer:Pointer;Length:integer):Boolean;
function HandleXK315A2(CommBuffer:Pointer;Length:integer):Boolean;
//2014-10-23 李楊 D2008指令模式
function HandleD2008CommandType(CommBuffer:Pointer;Length:integer):Boolean;
procedure ReceiveCommData(Sender :TObject; Buffer : Pointer; BufferLength :Word);
function SendWeight3190(Weight,Precision : Integer):Boolean;
function SendWeightD2Plus(Weight,Precision: integer): Boolean;
function SendWeight3102(Weight,Precision : Integer):Boolean;
function SendWeightDI_880(Weight,Precision : Integer):Boolean ;
function SendWeightDS822_D(Weight,Precision : Integer):Boolean ;
function SendWeightXK3190D2(Weight,Precision : Integer):Boolean ;
function SendWeightD2002(Weight,Precision : Integer):Boolean ;
function SendWeightWS822_A(Weight,Precision : Integer):Boolean ;
function SendWeightT800(Weight,Precision : Integer):Boolean ;
function SendWeightHT9800_B(Weight,Precision : Integer):Boolean;
function SendWeight8142ProPlus(Weight,Precision : Integer):Boolean ;
protected
public
constructor Create(AnOwner: TComponent); override;
destructor Destroy; override;
procedure PickWeight(var Weight : Integer; var WeighTime :TDateTime);
procedure SendWeight( Weight,Precision : Integer); //組件作為儀器模擬用的功能。
function GetDevStatus : TDevStatus;
procedure ReadWeight(Addr :Char);
procedure SetZero(Addr : Char);
published
//作為接收解算用:
property DevType : string read FDevType write FDevType; //儀表型別
property DevAddr : Byte read FDevAddr write FDevAddr;
property Deviation : integer read FDeviation write FDeviation;
property CheckInterval : Byte read FCheckInterval write SetCheckInterval;
property OnGetWeight : TGetWeight read FGetWeight write SetGetWeight; //得到新的重量資料。
property OnGetRawData : TGetRawData read FGetRawData write SetGetRawData ; //得到原始資料。
property OnNotConnect : TNotifyEvent read FNotConnect write SetNotConnect; //儀表較長時間沒有發送資料。
property OnGetWeightAndDec: string read FWeightAndDec; //2014-10-23 含有小數點的重量如D2008指令型別重量 write Set;
end;
procedure Register;
uj5u.com熱心網友回復:
implementation
procedure Register;
begin
RegisterComponents('老劉控制元件', [TWeighDevCn]); //[TClientSocket]
end;
constructor TWeighDevCn.Create(AnOwner: TComponent);
begin
Inherited Create(AnOwner);
//設定通信檢測定時器。
TimerCommCheck := TTimer.Create(nil);
CheckInterval := 5; //5秒鐘無串口資料,則報警。
TimerCommCheck.Enabled := True;
FMinWeight := 0 ;
FMaxWeight := 0 ;
//設定D2008讀命令定時器
TimerD2008Send := TTimer.Create(nil);
TimerD2008Send.Interval := 500;
TimerD2008Send.OnTimer := SendD2008GetValueOrder;
TimerD2008Send.Enabled := True;
//設定穩定檢測定時器
TimerSteadyCheck := TTimer.Create(nil);
TimerSteadyCheck.Interval := 500;
TimerSteadyCheck.OnTimer := OnSteadyCheckTimer;
TimerSteadyCheck.Enabled := True;
//
// Self.ReadIntervalTimeout := 30; //防止連續有串口資料,但緩沖不滿,得不到及時處理。
Self.OnReceiveData := ReceiveCommData;
RawDataGot := 0;
end;
destructor TWeighDevCn.Destroy;
begin
TimerCommCheck.Free();
TimerSteadyCheck.Free();
TimerD2008Send.Free();
inherited Destroy;
end;
procedure TWeighDevCn.ProcessGotWeight(currWeight,Precision :integer);
begin
if (FWeight <> currWeight) then
begin
if Assigned(FGetWeight) then
FGetWeight(Self,currWeight,Precision);
end;
// FWeight := currWeight;
SetCurrWt(currWeight); //判斷重量是否不穩定。
FWeighTime := Now();
end;
function TWeighDevCn.Handle3190(CommBuffer:Pointer;Length:integer):Boolean;
function AdjustXorValue( orgValue : Byte):Byte; //一位元組拆成兩位元組。
begin
Result := orgValue + 48; // 0-9 : +48(30H) ; 10-15(A-F) +37H
if Result > 57 then // 9 + 48
Result := Result + 7;
end;
var
idx ,sn: integer;
// DataType : Integer;
tmpWeight : Integer;
// ADigit : Integer;
WtStr : ShortString;
//資料格式 : 02 2B 30 35 32 39 32 30 ,(52920KG) , 31 42
//-00007001A
//測驗資料一:02 2D 30 30 30 30 37 30 30 31 41 03
//測驗資料二:02 2d 30 30 30 31 34 30 30 31 38 03
EndLoc : Integer;
XorValue,XorHigh,XorLow : Byte;
PassCheck : Boolean;
NeedHandle : Boolean;
begin
Result := false;
NeedHandle := ((FDevType='XK3190-A9') or (FDevType='XK3190-D9') or (FDevType='XK3190-A9不校驗')
or (FDevType= 'XK3190-DS'));
if not NeedHandle then
Exit;
Result := true;
for idx := 0 to Length-1 do
begin
if (TByteDynArray(CommBuffer)[idx] = 2) then
begin
EndLoc := idx +11;
if (EndLoc >Length) then //資料長度不夠 第1位元組是02,第12位元組是03
Exit;
if not (TByteDynArray(CommBuffer)[EndLoc] = 3) then
Exit;
if not( FDevType ='XK3190-A9不校驗') then
begin
XorValue := TByteDynArray(CommBuffer)[idx+1];
for sn := 2 to 8 do
XorValue := XorValue xor TByteDynArray(CommBuffer)[idx+sn];
XorHigh := AdjustXorValue(XorValue div 16);
XorLow := AdjustXorValue(XorValue mod 16);
PassCheck := ( XorHigh = TByteDynArray(CommBuffer)[idx+9] ) //耀華的正確校驗
and ( XorLow = TByteDynArray(CommBuffer)[idx+10] );
if not PassCheck then
begin
XorValue := XorValue xor 48; //耀華的錯誤校驗
PassCheck := ( XorHigh = TByteDynArray(CommBuffer)[idx+9] )
and ( XorLow = TByteDynArray(CommBuffer)[idx+10] );
end;
if not PassCheck then //未通過校驗。
Exit;
end;
WtStr := '';
for sn := 1 to 7 do //七個位元組,帶符號。
WtStr := WtStr + Chr(TByteDynArray(CommBuffer)[idx+sn]);
if TryStrToInt(WtStr,tmpWeight) then
begin
ProcessGotWeight(tmpWeight,0);
Break;
end;
end;
end;
end;
function TWeighDevCn.HandleDI_880(CommBuffer:Pointer;Length:integer):Boolean ;
var
idx : Integer;
sn : Integer;
tmpWeight : integer;
ADigit : Integer;
begin
Result := false;
if not (FDevType = 'DI-880') then
Exit;
Result := true;
for idx := 0 to Length-1 do
begin
if (TByteDynArray(CommBuffer)[idx]=Ord('?')) then
begin
if (idx+5)>= Length then //長度不夠。
Exit;
tmpWeight := 0;
for sn := 1 to 5 do
begin
ADigit := TByteDynArray(CommBuffer)[idx+sn]-48;
if (ADigit<0 )or (ADigit>9) then Exit; //不合法
tmpWeight := tmpWeight*10 + ADigit;
end;
ProcessGotWeight(tmpWeight,0);
end;
end;
end;
function TWeighDevCn.HandleDS822_D(CommBuffer:Pointer;Length:integer):Boolean ;
var // DS822_D格式:'98762 ='
idx : Integer;
sn : Integer;
tmpWeight : integer;
tmpStr : string;
begin
Result := false;
if not (FDevType = 'DS822-D') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
if (PChar(CommBuffer)[idx]='=') then
begin
if idx<8 then Exit; //前面長度不夠。
tmpStr := '';
for sn := 1 to 8 do
tmpStr := tmpStr + PChar(CommBuffer)[idx-sn];
tmpStr := Trim(tmpStr);
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,0);
end; //合法格式
end; //倒序顯示。
end;
function TWeighDevCn.HandleXK3190D2(CommBuffer:Pointer;Length:integer):Boolean ;
var //
idx : Integer;
sn : Integer;
tmpWeight : integer;
tmpStr : string;
begin
Result := false;
if not (FDevType = 'XK3190-D2+') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
if (PChar(CommBuffer)[idx]='=') then
begin
if (idx+8)>=Length then Exit; //前面長度不夠。
tmpStr := '';
for sn := 8 downto 1 do
tmpStr := tmpStr + PChar(CommBuffer)[idx+sn];
tmpStr := Trim(tmpStr);
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,0);
end; //合法格式
end; //倒序顯示。
end;
function TWeighDevCn.HandleXK3190D2InstructMode(CommBuffer:Pointer;Length:integer):Boolean ;
var // #02 'A'(地址) 'B'(毛重) '+'(符號) '123456' (6位元組重量,高到低)
idx : Integer;
sn : Integer;
tmpWeight : integer;
tmpStr : string;
begin
Result := false;
if not ((FDevType = 'D2+指令方式') or (FDevType ='D2+指令(5倍)') ) then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
{ 02 01 42 2B 30 30 31 32 30 30 30 30
02 01 42 2B 30 30 31 32 30 30 30 30
02 01 42 2B 30 31 32 30 30 30 30 30
02 01 42 2B 30 30 37 38 30 30 30 30
02 01 42 2B 30 30 37
}
if (PChar(CommBuffer)[idx]=#2 ) and (PChar(CommBuffer)[idx+2]='B') then
begin
if (idx+8)>=Length then Exit; //前面長度不夠。
tmpStr := '';
for sn := 1 to 7 do //符號一位元組,資料六位元組
tmpStr := tmpStr + PChar(CommBuffer)[idx+sn+2];
tmpStr := Trim(tmpStr);
if TryStrToInt(tmpStr,tmpWeight) then
begin
if (FDevType ='D2+指令(5倍)') then
tmpWeight := tmpWeight * 5;
ProcessGotWeight(tmpWeight,0);
end;
end; //合法格式
end; //倒序顯示。
end;
// 80Kg : 02 2B 30 30 30 30 38 30 30 31 33 03
//-80Kg : 02 2D 30 30 30 30 38 30 30 31 35 03
function TWeighDevCn.HandleD2008F(CommBuffer:Pointer;Length:integer):Boolean ;
var
idx ,sn : Integer;
tmpWeight : Integer;
tmpStr : string;
begin
Result := False;
if not (FDevType = '柯力D2008F') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
{ 02 2B 30 30 30 30 38 30 30 31 33 03
}
if (PChar(CommBuffer)[idx]=#2 ) then
begin
if (idx + 11)> Length then Exit; //長度不夠。
if (idx+8)>=Length then Exit; //前面長度不夠。
tmpStr := '';
for sn := 1 to 7 do //符號一位元組,資料六位元組
tmpStr := tmpStr + PChar(CommBuffer)[idx+sn+2];
tmpStr := Trim(tmpStr);
if TryStrToInt(tmpStr,tmpWeight) then
begin
if (FDevType ='D2+指令(5倍)') then
tmpWeight := tmpWeight * 5;
ProcessGotWeight(tmpWeight,0);
end;
end; //合法格式
end; //倒序顯示。
end;
function TWeighDevCn.HandleD2002(CommBuffer:Pointer;Length:integer):Boolean ;
var // D2002格式:'=7654321'
idx : Integer;
sn : Integer;
tmpWeight : integer;
tmpStr : string;
begin
Result := false;
if not (FDevType = 'D2002') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
if (PChar(CommBuffer)[idx]='=') then
begin
if (idx+7) >=Length then Exit; //前面長度不夠。
tmpStr := '';
for sn := 7 downto 1 do
tmpStr := tmpStr + PChar(CommBuffer)[idx+sn];
tmpStr := Trim(tmpStr);
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,0);
end; //合法格式
end; //倒序顯示。
end;
function TWeighDevCn.HandleD2002E(CommBuffer:Pointer;Length:integer):Boolean ;
var // D2002格式:'=7654321' .06000-=
idx : Integer;
sn : Integer;
tmpWeight : integer;
tmpStr : string;
begin
Result := false;
if not (FDevType = 'D2002E') then
Exit;
Result := True;
for idx := 0 to Length-8 do
begin
if (PChar(CommBuffer)[idx]='.')
and (PChar(CommBuffer)[idx+7]='=') then
begin
// if (idx+7)>=Length then Exit; //前面長度不夠。
tmpStr := '';
for sn := 6 downto 1 do
tmpStr := tmpStr + PChar(CommBuffer)[idx+sn];
tmpStr := Trim(tmpStr);
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,0);
end; //合法格式
end; //倒序顯示。
end;
function TWeighDevCn.HandleD2002E_2(CommBuffer:Pointer;Length:integer):Boolean ; //新疆和靜碰到怪的協議
var // 格式:'ST,GS,+0000100g '#$0d#$0a 'ST,GS,-0000080g ' #$0d#$0a
idx : Integer;
sn : Integer;
AChar : Char;
GotHead : Boolean;
tmpWeight : integer;
tmpStr : string;
begin
Result := false;
if not (FDevType = 'D2002E-FY') then
Exit;
Result := True;
GotHead := False;
for idx := 0 to Length-1 do
begin
AChar := PChar(CommBuffer)[idx];
if not GotHead then
begin
if (AChar='+') or (AChar = '-') then
begin
GotHead := True;
tmpStr := AChar; //得到第一字符。
end;
end
else
begin
if (AChar = 'g') then //結尾。
begin
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,0);
Exit;
end;
tmpStr := tmpStr + AChar;
end;
end; //。
end;
uj5u.com熱心網友回復:
function TWeighDevCn.HandleWS822_A(CommBuffer:Pointer;Length:integer):Boolean ;
var // 格式:'AA+1234560' ,帶符號,小數位。
idx : Integer;
sn : Integer;
tmpWeight : integer;
DataType : Integer;
tmpStr : string;
begin
Result := false;
if not (FDevType = 'WS822-A') then
Exit;
Result := true;
for idx := 0 to Length-2 do
begin
if ( (PChar(CommBuffer)[idx]='A')
and (PChar(CommBuffer)[idx+1]='A') ) then
begin
if (idx+9)>(Length-1) then
Exit;
tmpStr := '';
for sn :=2 to 8 do
tmpStr := tmpStr + PChar(CommBuffer)[idx+sn];
DataType := Ord(PChar(CommBuffer)[idx+9])-48;
if (DataType<0) or (DataType>4) then //小數位。
Exit;
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,DataType);
end;
end;
end;
function TWeighDevCn.HandleT800(CommBuffer:Pointer;Length:integer):Boolean ;
var //
idx : Integer;
sn : Integer;
tmpWeight : integer;
tmpStr : string;
begin
Result := false;
if not (FDevType ='T800') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
if (PChar(CommBuffer)[idx]=#2) then
begin
if (idx +9) > (Length-1) then Exit;
tmpStr := '';
for sn := 5 to 9 do //5位數字。
tmpStr := tmpStr + PChar(CommBuffer)[idx+5];
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,0);
end;
end;
end;
function TWeighDevCn.HandleHT9800_B(CommBuffer:Pointer;Length:integer):Boolean ;
var
tmpWeight : integer;
tmpStr : string;
ABCD : TBCD;
tempByte : Byte;
begin
Result := false;
if not (FDevType='HT9800-B') then
Exit;
Result := true;
if ( TByteDynArray(CommBuffer)[0]= $FF) then
begin
ABCD.Precision:=6;
tempByte:=TByteDynArray(CommBuffer)[1] and $7;
if tempByte in ([1..6]) then
ABCD.SignSpecialPlaces:= tempByte-1
else ABCD.SignSpecialPlaces:=5;
ABCD.Fraction[0]:=TByteDynArray(CommBuffer)[4];
ABCD.Fraction[1]:=TByteDynArray(CommBuffer)[3];
ABCD.Fraction[2]:=TByteDynArray(CommBuffer)[2];
tempByte:=TByteDynArray(CommBuffer)[1] and $80 ;
if tempByte=$80 then
tmpStr := '999999'
else
begin
tempByte:=TByteDynArray(CommBuffer)[1] and $20;
if tempByte=$20 then
tmpStr:='-'+bcdtostr(ABCD)
else
tmpStr:=bcdtostr(ABCD);
end;
if TryStrToInt(tmpStr,tmpWeight )then
ProcessGotWeight(tmpWeight,0);
end;
end;
function TWeighDevCn.Handle8142ProPlus(CommBuffer:Pointer;Length:integer):Boolean ;
var
idx : Integer;
sn : Integer;
tmpWeight : integer;
tmpStr : string;
DotPos :Byte;
ADigit : integer;
begin
Result := false;
if not (FDevType ='8142PRO+') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
if (PChar(CommBuffer)[idx]=#2) then
begin
if (idx +17) > (Length) then Exit; //char(2) 之后沒有17個字符、
DotPos:=Byte(PChar(CommBuffer)[idx+1]) and $07;
ADigit := DotPos -2; //除以10的ADigit次方。DotPos為2,原數;3,除以10,0,乘以100.
tmpStr := '';
for sn := 1 to 6 do
tmpStr := tmpStr + PChar(CommBuffer)[idx+3+sn];
if TryStrToInt(tmpStr,tmpWeight)then
ProcessGotWeight(tmpWeight,ADigit);
end; //找到#2.
end;
end;
//3102型儀表的決議
function TWeighDevCn.HandleXK3102(CommBuffer:Pointer;Length:integer):Boolean;
var
idx : integer;
sn : integer;
tmpStr : string;
tmpWeight : Integer;
begin
Result := false;
if not (FDevType ='XK-3102') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
tmpStr := '';
if (PChar(CommBuffer)[idx]=#$20) then
begin
if (idx + 6) > Length then Exit;
for sn := idx+1 to idx+6 do //5位數字。
tmpStr := tmpStr + PChar(CommBuffer)[sn];
if TryStrToInt(tmpStr,tmpWeight) then
ProcessGotWeight(tmpWeight,0);
Exit;
end;
end;
end;
//315A2型儀表的決議 ,接近于3102的協議。
function TWeighDevCn.HandleXK315A2(CommBuffer:Pointer;Length:integer):Boolean;
var
idx : integer;
sn : integer;
tmpStr : string;
tmpWeight : Integer;
statusB : Byte;
begin
Result := false;
if not (FDevType ='XK-315A2') then
Exit;
Result := True;
for idx := 0 to Length-1 do
begin
tmpStr := ''; //STX(02) 狀態A 狀態B 狀態C(20H)
if (PChar(CommBuffer)[idx]=#2) and (PChar(CommBuffer)[idx+3]=#$20) then
begin
if (idx + 10 ) > Length then Exit;
for sn := idx+4 to idx+9 do //5位數字。
tmpStr := tmpStr + PChar(CommBuffer)[sn];
if TryStrToInt(tmpStr,tmpWeight) then
begin
statusB := Ord(PChar(CommBuffer)[idx+2]);
if (( statusB and 2)= 2 ) then
tmpWeight := - tmpWeight;
ProcessGotWeight(tmpWeight,0);
end;
Exit;
end;
end;
end;
function deal2008sData(Value:string;TheDecimalPoint:Integer):string;
var
intTmpStr,decmiamTmpStr:string;
begin
if TheDecimalPoint = 0 then
Result := IntToStr(StrtoInt(Value))
else
begin
intTmpStr :=IntToStr(StrToInt(LeftStr(Value,7 - TheDecimalPoint)));
decmiamTmpStr := IntToStr(StrToInt(RightStr(Value,TheDecimalPoint)));
Result := intTmpStr +'.' + decmiamTmpStr;
end;
end;
function TWeighDevCn.HandleD2008CommandType(CommBuffer: Pointer;
Length: integer): Boolean;
var
idx,tmpWeight,TheDecimalPoint,sn,idx2 : integer;
WtStr,weight : string;
{資料格式: 01 03 08 30 30 30 30 30 32 32 30 58 8F
地址 功能碼 資料長度 資料 16CRC校驗碼 }
begin
Result := False;
if not (FDevType = 'D2008指令型別') then Exit;
Result := True;
if Length < 13 then Exit;
for idx := 0 to Length - 1 do
begin
if (PChar(CommBuffer)[idx]=#3) and (PChar(CommBuffer)[idx+1]=#8) then
begin
WtStr := '';
for sn := 1 to 7 do //七個位元組,帶符號。
WtStr := WtStr + Chr(TByteDynArray(CommBuffer)[idx+1+sn]);
//如處理小數,另外做
if TryStrToInt(WtStr,tmpWeight) then
begin
ProcessGotWeight(tmpWeight,0);
Break;
end;
end;
end;
end;
procedure TWeighDevCn.ReceiveCommData(Sender :TObject; Buffer : Pointer; BufferLength :Word);
var
Len : integer;
idx : Integer;
AByte : Byte;
begin
FConnected := True; //表示串口資料正常。
TimerCommCheck.Enabled := False;
TimerCommCheck.Enabled := True;
Len := BufferLength;
if Len >300 then
Len := 300;
//Move(Buffer^,CommBuffer,Len);
// AByte :=TByteDynArray(Buffer)[11];
// ShowMessage(IntToStr(AByte));
Move(Buffer^,CommBuffer[RawDataGot+1],Len);
// for idx := 1 to Len do
// CommBuffer[idx+ RawDataGot] := TByteDynArray(Buffer)[idx-1];
Inc(RawDataGot,Len);
if RawDataGot < 20 then Exit; //要求至少20位元組才處理資料。
Len := RawDataGot ;
RawDataGot := 0; //復位
if Assigned(FGetRawData) then
FGetRawData(Self,@CommBuffer, Len);
if Handle3190(@CommBuffer,Len) then Exit;
if HandleDI_880(@CommBuffer,Len) then Exit;
if HandleDS822_D(@CommBuffer,Len) then Exit;
if HandleXK3190D2(@CommBuffer,Len) then Exit;
if HandleXK3190D2InstructMode(@CommBuffer,Len) then Exit; //D2+ 的指令模式,資料格式不一樣.
if HandleD2002(@CommBuffer,Len) then Exit;
if HandleD2002E(@CommBuffer,Len) then Exit;
if HandleD2002E_2(@CommBuffer,Len) then Exit;
if HandleWS822_A(@CommBuffer,Len) then Exit;
if HandleT800(@CommBuffer,Len) then Exit;
if HandleHT9800_B(@CommBuffer,Len) then Exit;
if Handle8142ProPlus(@CommBuffer,Len) then Exit;
if HandleD2008F(@CommBuffer,Len) then Exit;
if HandleXK3102(@CommBuffer,Len) then Exit;
if HandleXK315A2(@CommBuffer,Len) then Exit;
if HandleD2008CommandType(@CommBuffer,Len) then Exit;
end;
function TWeighDevCn.SendWeight3190(Weight,Precision : Integer):Boolean;
var
idx : integer;
tWeight : integer;
begin
Result := false;
if not ((FDevType='XK3190-A9') or (FDevType='XK3190-D9')) then
Exit;
Result := true;
tWeight := Weight;
SendBuf[1] := 2;
SendBuf[9] := Precision mod 10 +48;
SendBuf[12] :=3;
for idx := 8 downto 2 do
begin
SendBuf[idx] := (tWeight mod 10)+48;
tWeight := tWeight div 10;
end;
WriteCommData(@SendBuf,25);
end;
function TWeighDevCn.SendWeight3102(Weight,Precision : Integer):Boolean;
var
idx : integer;
tWeight : integer;
begin
Result := false;
if not (FDevType='XK-3102') then
Exit;
Result := true;
tWeight := Weight;
SendBuf[1] := $20;
for idx := 7 downto 2 do
begin
SendBuf[idx] := (tWeight mod 10)+48;
tWeight := tWeight div 10;
end;
WriteCommData(@SendBuf,10);
end;
function TWeighDevCn.SendWeightD2Plus(Weight,Precision: integer): Boolean;
var
commdata : array[1..20] of Byte;
// wt : Integer;
idx : Integer;
begin
Result := false;
if not (FDevType='D2+指令方式') then
Exit;
Result := True;
SendBuf[1] := 2;
SendBuf[2] := 1;
SendBuf[3] := $42;
SendBuf[4] := $2B;
// wt := StrToInt(edt2.Text);
for idx:= 6 downto 1 do
begin
SendBuf[4+idx] := (Weight mod 10) + 48;
Weight := Weight div 10;
end;
SendBuf[11] := 48;
SendBuf[12] := 48;
WriteCommData(@SendBuf,12);
end;
function TWeighDevCn.SendWeightDI_880(Weight,Precision : Integer):Boolean ;
var
idx : integer;
begin
Result := false;
if not (FDevType = 'DI-880') then
Exit;
Result := true;
SendBuf[1] := Ord('?');
//Weight := Weight mod 100000; //五位資料
for idx := 6 downto 2 do
begin
SendBuf[idx] := Weight mod 10 +48;
Weight := Weight div 10;
end;
WriteCommData(@SendBuf,6);
end;
uj5u.com熱心網友回復:
function TWeighDevCn.SendWeightDS822_D(Weight,Precision : Integer):Boolean ;
var // '7654321+='
tWeight : integer;
idx : integer;
begin
Result := false;
if not (FDevType = 'DS822-D') then
Exit;
Result := True;
tWeight := Weight;
if tWeight < 0 then
tWeight := -weight;
for idx := 1 to 7 do
begin
SendBuf[idx]:= (tWeight mod 10) +48;
tWeight := tWeight div 10;
end;
if (Weight>0) then
SendBuf[8]:=Ord('+')
else
SendBuf[8]:=Ord('-');
SendBuf[9] := Ord('=');
WriteCommData(@SendBuf,9);
end;
function TWeighDevCn.SendWeightXK3190D2(Weight,Precision : Integer):Boolean ;
var
idx ,tWeight :Integer;
begin
Result := false;
if not (FDevType = 'XK3190-D2+') then
Exit;
Result := True;
tWeight:= Weight;
SendBuf[1] := Ord('=');
for idx := 2 to 8 do
begin
SendBuf[idx]:= (tWeight mod 10) +48;
tWeight := tWeight div 10;
end;
if (Weight>0) then
SendBuf[9]:=Ord('+')
else
SendBuf[9]:=Ord('-');
WriteCommData(@SendBuf,9);
end;
function TWeighDevCn.SendWeightD2002(Weight,Precision : Integer):Boolean ;
var
idx ,tWeight :Integer;
begin
Result := false;
if not (FDevType = 'D2002') then
Exit;
Result := True;
tWeight:= Weight;
SendBuf[1] := Ord('=');
for idx := 2 to 8 do
begin
SendBuf[idx]:= (tWeight mod 10) +48;
tWeight := tWeight div 10;
end;
WriteCommData(@SendBuf,8);
end;
function TWeighDevCn.SendWeightWS822_A(Weight,Precision : Integer):Boolean ;
//'AA'+[符號1位元組]+'123456'+[小數位1位元組]
var
idx : integer;
tWeight : integer;
begin
Result := false;
if not (FDevType = 'WS822-A') then
Exit;
Result := true;
tWeight := Weight;
SendBuf[1] := Ord('A');
SendBuf[2] := SendBuf[1];
if weight> 0 then
SendBuf[3] := Ord('+')
else
begin
SendBuf[3] := Ord('-');
Weight := - Weight;
end;
for idx := 9 downto 4 do
begin
SendBuf[idx] := tWeight mod 10 + 48;
tWeight := tWeight div 10;
end;
SendBuf[10] := Precision mod 10 +48;
WriteCommData(@SendBuf,10);
end;
function TWeighDevCn.SendWeightT800(Weight,Precision : Integer):Boolean ;
//#2+[4位元組不知]+[5位元組資料],資料如‘12345’
var
idx ,tWeight : Integer;
begin
Result := false;
if not (FDevType ='T800') then
Exit;
Result := True;
tWeight := weight;
SendBuf[1] := 2;
for idx := 10 downto 6 do
begin
SendBuf [idx]:= tWeight mod 10 + 48;
tWeight := tWeight div 10;
end;
WriteCommData(@SendBuf,10);
end;
function TWeighDevCn.SendWeightHT9800_B(Weight,Precision : Integer):Boolean;
{#2+[17位元組]
[17位元組]=[狀態1位元組][其他狀態2位元組][毛重資料6位元組]
[狀態1位元組]的低三位表示放大倍數。}
var
idx ,tWeight : Integer;
begin
Result := false;
if not (FDevType='HT9800-B') then
Exit;
Result := true;
{
SendBuf[1]:= 2;
SendBuf[2]:=
}
end;
function TWeighDevCn.SendWeight8142ProPlus(Weight,Precision : Integer):Boolean ;
{
#2+[17位元組]
[17位元組]=[狀態1位元組][其他狀態2位元組][毛重資料6位元組]
[狀態1位元組]的低三位表示放大倍數。
}
var
idx ,tWeight :Integer;
begin
Result := false;
if not (FDevType ='8142PRO+') then
Exit;
Result := True;
tWeight := Weight;
SendBuf[1] := 2;
SendBuf[2] := Precision;
for idx := 10 downto 5 do
begin
SendBuf[idx] := tWeight mod 10 +48;
tWeight := tWeight div 10;
end;
WriteCommData(@SendBuf,20);
end;
procedure TWeighDevCn.SendWeight( Weight,Precision : Integer);
begin
if Precision > 4 then Exit;
if SendWeight3190(Weight,Precision) then Exit;
if SendWeight3102(Weight,Precision) then Exit;
if SendWeightD2Plus(Weight,Precision) then Exit;
if SendWeightDI_880(Weight,Precision) then Exit;
if SendWeightDS822_D(Weight,Precision) then Exit;
if SendWeightXK3190D2(Weight,Precision) then Exit;
if SendWeightD2002(Weight,Precision) then Exit;
if SendWeightWS822_A(Weight,Precision) then Exit;
if SendWeightT800(Weight,Precision) then Exit;
if SendWeightHT9800_B(Weight,Precision) then Exit;
if SendWeight8142ProPlus(Weight,Precision) then Exit;
end;
procedure TWeighDevCn.SetGetWeight(GetWeightFunc : TGetWeight);
begin
FGetWeight := GetWeightFunc;
end;
procedure TWeighDevCn.SetGetRawData(GetRawDataFunc : TGetRawData);
begin
FGetRawData := GetRawDataFunc ;
end;
procedure TWeighDevCn.PickWeight(var Weight : Integer; var WeighTime :TDateTime);
begin
Weight := FWeight;
WeighTime := FWeighTime;
end;
procedure TWeighDevCn.D2PlusSetZero(Addr :Char);
var
D2ComBuf : array[1..6] of Byte;
XORValue : Byte;
TmpStr : string;
tmpChar : Char;
begin
D2ComBuf[1] := 2;
D2ComBuf[2] := Ord(Addr);
D2ComBuf[3] := Ord('H');
XORValue := D2ComBuf[2] xor D2ComBuf[3];
TmpStr := IntToHex( XORValue,2 );
tmpChar := TmpStr[1];
D2ComBuf[4] := Ord(tmpChar);
tmpChar := TmpStr[2];
D2ComBuf[5] := Ord(tmpChar);
D2ComBuf[6] := 3;
WriteCommData( @D2ComBuf, 6);
end;
//01 06 00 01 00 17 98 04 置零
procedure TWeighDevCn.D2008FSetZero();
var
tmpComBuf : array[1..8] of Byte;
tmpStr:string;
idx:Integer;
begin
tmpComBuf[1] := FDevAddr;
tmpComBuf[2] := 6;
tmpComBuf[3] := 0;
tmpComBuf[4] := 1;
tmpComBuf[5] := 0;
tmpComBuf[6] := $17;
tmpStr := '';
for idx :=1 to 6 do
tmpStr := tmpStr +Char(tmpComBuf[idx]);
tmpComBuf[7] := CRC(tmpStr) div 256;
tmpComBuf[8] := CRC(tmpStr) mod 256;
tmpStr := tmpStr +Char(tmpComBuf[7]) +Char(tmpComBuf[8]);
WriteCommData( PAnsiChar(tmpStr),Length(tmpStr));
end;
//01 03 00 01 00 04 15 C9
procedure TWeighDevCn.D2008FReadWt();
var
tmpComBuf : array[1..8] of Byte;
begin
tmpComBuf[1] := 1;
tmpComBuf[2] := 3;
tmpComBuf[3] := 0;
tmpComBuf[4] := 1;
tmpComBuf[5] := 0;
tmpComBuf[6] := 4;
tmpComBuf[7] := $15;
tmpComBuf[8] := $C9;
WriteCommData( @tmpComBuf, 8);
end;
procedure TWeighDevCn.D2PlusReadWt(Addr :Char);
var
idx : Integer;
D2ComBuf : array[1..6] of Byte;
XORValue : Byte;
TmpStr : string;
tmpChar : Char;
begin
// AddLog('D2+讀重量,儀表序號:'+ IntToStr(DevIDX) );
D2ComBuf[1] := 2;
D2ComBuf[2] := Ord(Addr);
D2ComBuf[3] := Ord('B');
XORValue := D2ComBuf[2] xor D2ComBuf[3];
TmpStr := IntToHex( XORValue,2 );
tmpChar := TmpStr[1];
D2ComBuf[4] := Ord(tmpChar);
tmpChar := TmpStr[2];
D2ComBuf[5] := Ord(tmpChar);
D2ComBuf[6] := 3;
WriteCommData( @D2ComBuf, 6);
end;
uj5u.com熱心網友回復:
支持代碼共享,頂一個。uj5u.com熱心網友回復:
支持支持,頂uj5u.com熱心網友回復:
//01 06 00 01 00 17 98 04 置零
procedure TWeighDevCn.D2008FSetZero();
var
tmpComBuf : array[1..8] of Byte;
tmpStr:string;
idx:Integer;
begin
tmpComBuf[1] := FDevAddr;
tmpComBuf[2] := 6;
tmpComBuf[3] := 0;
tmpComBuf[4] := 1;
tmpComBuf[5] := 0;
tmpComBuf[6] := $17;
tmpStr := '';
for idx :=1 to 6 do
tmpStr := tmpStr +Char(tmpComBuf[idx]);
tmpComBuf[7] := CRC(tmpStr) div 256;
tmpComBuf[8] := CRC(tmpStr) mod 256;
tmpStr := tmpStr +Char(tmpComBuf[7]) +Char(tmpComBuf[8]);
WriteCommData( PAnsiChar(tmpStr),Length(tmpStr));
end;
//01 03 00 01 00 04 15 C9
procedure TWeighDevCn.D2008FReadWt();
var
tmpComBuf : array[1..8] of Byte;
begin
tmpComBuf[1] := 1;
tmpComBuf[2] := 3;
tmpComBuf[3] := 0;
tmpComBuf[4] := 1;
tmpComBuf[5] := 0;
tmpComBuf[6] := 4;
tmpComBuf[7] := $15;
tmpComBuf[8] := $C9;
WriteCommData( @tmpComBuf, 8);
end;
procedure TWeighDevCn.D2PlusReadWt(Addr :Char);
var
idx : Integer;
D2ComBuf : array[1..6] of Byte;
XORValue : Byte;
TmpStr : string;
tmpChar : Char;
begin
// AddLog('D2+讀重量,儀表序號:'+ IntToStr(DevIDX) );
D2ComBuf[1] := 2;
D2ComBuf[2] := Ord(Addr);
D2ComBuf[3] := Ord('B');
XORValue := D2ComBuf[2] xor D2ComBuf[3];
TmpStr := IntToHex( XORValue,2 );
tmpChar := TmpStr[1];
D2ComBuf[4] := Ord(tmpChar);
tmpChar := TmpStr[2];
D2ComBuf[5] := Ord(tmpChar);
D2ComBuf[6] := 3;
WriteCommData( @D2ComBuf, 6);
end;
procedure TWeighDevCn.ReadWeight(Addr : Char);
begin
if (FDevType = 'D2+指令方式') then
D2PlusReadWt(Addr);
if (FDevType = '柯力D2008F') then
D2008FReadWt();
end;
procedure TWeighDevCn.SetZero(Addr : Char);
begin
if (FDevType = 'D2+指令方式') then
D2PlusSetZero(Addr);
if (FDevType = '柯力D2008F') then
D2008FSetZero();
end;
procedure TWeighDevCn.SetNotConnect(NotCon : TNotifyEvent);
begin
FNotConnect := NotCon;
end;
procedure TWeighDevCn.OnCommCheckTimer(Sender: TObject);
begin
FConnected := False; //超時,則判斷為未連接。
if Assigned( FNotConnect ) then
FNotConnect(Self);
end;
//穩定檢測。
procedure TWeighDevCn.OnSteadyCheckTimer(Sender: TObject);
begin
FSteady := True; // 如果有事件,觸發事件。
end;
//設定當前重量
procedure TWeighDevCn.SetCurrWt ( CurrWt : Integer);
begin
FWeight := CurrWt;
if FWeight > FMaxWeight then
FMaxWeight := FWeight;
if FWeight < FMinWeight then
FMinWeight := FWeight;
if (FMaxWeight- FMinWeight) > FDeviation then //超出偏差范圍。 then
begin
FSteady := False;
// NotifyWtStatus();
//重新設定初始重量,判斷是否穩定。
FMaxWeight := CurrWt;
FMinWeight := CurrWt;
// ResetTimer();
//重啟定時器,判斷是否穩定。
TimerSteadyCheck.Enabled := False;
TimerSteadyCheck.Enabled := True;
end;
end;
procedure TWeighDevCn.SetCheckInterval(intval :Byte);
var
tmpV : Boolean;
begin
if not Assigned( TimerCommCheck) then
Exit;
tmpV := TimerCommCheck.Enabled;
TimerCommCheck.Enabled := false;
TimerCommCheck.Interval := intval * 1000; //秒為單位;
TimerCommCheck.Enabled := tmpV;
TimerCommCheck.OnTimer := OnCommCheckTimer; // OnCheckTimer ;
FCheckInterval := intval;
end;
function TWeighDevCn.GetDevStatus : TDevStatus;
var
tmpStatus : TDevStatus;
begin
tmpStatus.Weight := FWeight;
tmpStatus.Steady := FSteady;
tmpStatus.Connected := FConnected;
Result := tmpStatus;
end;
//2014-10-22 李楊 用于向D2008 發送讀數值命令
procedure TWeighDevCn.SendD2008GetValueOrder(Sender : TObject);
var
CommStr:string;
HighByte,LowByte:Integer;
CRCV : integer;
begin
CommStr := Char(FDevAddr);
CommStr := CommStr + #$03+#$00+#$01+#$00+#$04;
CRCV := CRC(CommStr);
HighByte := CRCV div 256;
LowByte := CRCV mod 256;
CommStr := CommStr + chr(HighByte) + chr(LowByte);
WriteCommData(PAnsiChar(CommStr),Length(CommStr));
end;
end.
uj5u.com熱心網友回復:
支持,頂一個。。。。uj5u.com熱心網友回復:
樓主好人,頂...uj5u.com熱心網友回復:
樓主好人,雖然不做這個,但是分享精神值得發揚uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
樓主真是好人!
uj5u.com熱心網友回復:
直好,感謝,好東東uj5u.com熱心網友回復:
好人
uj5u.com熱心網友回復:
值得表揚
uj5u.com熱心網友回復:
好東東,值得收藏uj5u.com熱心網友回復:
真心贊一個!!!好人啦!!!uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
2017感動CSDNuj5u.com熱心網友回復:
在這兒終于看到了uj5u.com熱心網友回復:
好東東,值得收藏uj5u.com熱心網友回復:
支持共享原始碼,頂。uj5u.com熱心網友回復:
支持共享原始碼,頂。uj5u.com熱心網友回復:
UnitCRC16B,這個是自定義的嗎?uj5u.com熱心網友回復:
也是網路上找得到的一個CRC演算法,因為手頭接觸到兩個演算法,某儀表跟其中一個對應的。
uj5u.com熱心網友回復:
不錯,樓組辛苦了uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
學習一下,想自己開發個單位可用的erp模塊,稱重模塊令人頭疼uj5u.com熱心網友回復:
這個可以有11uj5u.com熱心網友回復:
學習一下,能看到這樣的稱重代碼不容易啊。uj5u.com熱心網友回復:
學習,謝謝樓主分享,收藏了uj5u.com熱心網友回復:
你好,這個控制元件怎么用呀,能給點思路嗎?這樣的用法沒有用過,能留個聯系統方式嗎?uj5u.com熱心網友回復:
一直用SPCOMM,感覺穩定,挺好的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/12709.html
標籤:VCL組件開發及應用
上一篇:matlab 新手 可以幫我看看為什么我的牛頓迭代法找非線性方程組的根 我這個說索引超出 然后就沒有結果嗎 謝謝!
