怎样读时时地取地磅的过称的数据(100t)?急急急!!!!!!!!(10分)

  • 主题发起人 主题发起人 tt123tt
  • 开始时间 开始时间
T

tt123tt

Unregistered / Unconfirmed
GUEST, unregistred user!
要从COM口读取电子称的数据并进行计算和打印,有哪位做过这个方面的东西,请多多指教!
 
热切关注,我也急需了解。
 
地磅应该是单片机控制的吧,那么就好办了,发指令不就搞定了,不过你得先知道此单片要的指令才行。我以前做过测量电表的,也是用COM口进行数据通信。
 
我做过从COM口读取地磅的数据,你首先要从厂商获得电子称的通讯参数(速率,校验
方式,数据位长,停止位)和发送的命令及接收的数据格式!
 
这样的,一般的地100t以上的地秤都应该有一个表头,表头有一个说明书,如果表头还接大屏幕就更好办了
你可以按照说明书在表头的输入出端接一根线到计算机的com口上,如果不会接就看大屏幕是怎么接的
然后你就可以用spcomm控件读取秤的数据了,我以前做过常洲托利多的秤接口,但是源码我现在没有了
(波特率,校验方式,数据位长,停止位,奇偶校验都设置好了,一般要和表头同步!)
 
波特率 4800
数据位长 8
停止位 1
 
在你这种情况下,只有电子式的才可以用。而纯机械式的无法使用。
电子式的有一个用来显示数据的表头,上面有232的输出口,并且在表头里设置的有波特率
一类的数据,你先看一下,如果用的MSCOMM读的话,直接在控件里设置好就可以了。显示表
头会发送一串串的数据。接收到后,根据表头内的数据设置,哪一位代表什么就可以了。如
果实时连接就得用计时器了
 
我制作了一个串口测试程序!可以满足串口的测试工作。
只要你参考地秤的产品说明书就可以搞定!不懂的话来E-mail
http://211.91.191.8/public/xzy/MCom.rar
用winrar3.0解压就可以使用
 
能不能贴出来部分(把重量从com口读进程序理的部分)代码呀?
最好是从HB-8210里读出数据的程序。
购买也可以我在深圳,价格面谈!
QQ: 17434898
 
这是对常洲托利多地磅仪表的串口读取程序!仪表型号不同,读取数据的格式也不一样!
unit RdComm;
interface
uses
Windows, SysUtils, Classes, inifiles, forms;
type
TComInfo = record
cCommNum: string;
{ com1..com4 }
cBaudRate: integer;
{ 1200..19200 }
// cDataLen: integer;
{ 6..8 }
// cStopLen: integer;
{ 1..2 }
cParity: integer;
{ non, odd, even }
cHandle: THandle;
{ 串口打开后用来保存句柄 }
end;

TMeterInfo = record { 仪表型号不同,数值也不一样 }
DatPos: integer;
{ 过磅值在从仪表中读取的字符串中的位置 }
DatLen: integer;
{ 过磅值的长度 }
end;

function ReadMeter(MeterNum: integer;
var MeterVal: Integer):Boolean;
function ReadINI:Boolean;
procedure OpenComm(num: integer);
procedure CloseComm(num: integer);
var
ComInfo: array[1..4] of TComInfo;
MeterInfo: array[1..4] of TMeterInfo;
implementation
function ReadMeter(MeterNum: integer;
var MeterVal: integer): Boolean;
var
k: integer;
s: string;
// 发送命令给仪表
procedure SendCmd(cHandle: THandle;
cmd: char);
var
bl: Boolean;
rwBytes: Dword;
begin
sleep(5);
bl:= WriteFile( cHandle, cmd, 1, rwBytes, nil);
sleep(5);
if (not bl) or (rwBytes<1) then
bl:= WriteFile( cHandle, cmd, 1, rwBytes, nil);
// 重试再次发送命令
if (not bl) or (rwBytes<1) then
raise Exception.Create('ERR');
// 无法发送命令,提交异常来终止线程
end;

// 定位数据头
procedure SearchDataHead(cHandle: THandle);
var
i: integer;
rwBytes: Dword;
bDat: byte;
bl: Boolean;
begin
i:=0;
while i<50 do
// 这个循环定位数据头
begin
sleep(5);
bl:= ReadFile( cHandle, bDat, 1, rwbytes, nil);
if bl and (bDat = $02) then
break;
// 读到数据起始符
inc(i);
end;
// 没有能正确定位数据头则提交异常退出
if bDat <> $02 then
raise Exception.Create('ERR2');
end;

// 读取数据串
function GetDataStr(cHandle: THandle):string ;
var
i: integer;
rwBytes: Dword;
bDat: byte;
bl: Boolean;
begin
result:='';
i:=0;
while i<50 do
// 这个循环读取数据
begin
sleep(5);
bl:= ReadFile( ComInfo[MeterNum].cHandle, bDat, 1, rwBytes, nil);
if bl then
if bDat = $0D then
break // 读到数据结束符
else
result:= result + chr(bDat);
inc(i);
end;
// 没有读取到结束符,则提交异常退出
if bDat <> $0D then
raise Exception.Create('ERR2');
end;

begin
MeterVal:= 0;
s:='';
try
OpenComm(MeterNum);
try
SendCmd(Cominfo[MeterNum].cHandle, 'P');
SearchDataHead(ComInfo[MeterNum].cHandle);
s:= GetDataStr(ComInfo[MeterNum].cHandle);
// 提取数值
s:= copy(s, MeterInfo[MeterNum].DatPos, MeterInfo[MeterNum].DatLen);
try
k:= StrToInt(s);
// 此处有可能产生异常
except
raise Exception.Create('ERR3');
end;
finally
CloseComm(MeterNum);
end;
MeterVal:= k;
result:= true;
except
on E: Exception do
begin
s:= copy(E.Message,4,1);
case StrToIntDef(s,4) of
1: MeterVal:=-1;
// 串口打开失败
2: MeterVal:=-2;
// 串口通讯失败
3: MeterVal:=-3;
// 数值转换失败
4: MeterVal:=-4;
// 其它错误失败
end;
result:= False;
end;
end;
end;

// 读串口参数INI文件
function ReadINI:Boolean;
var
lpIni: TIniFile;
s: string;
i: integer;
begin
Result:= False;
s:= ExtractFileDir(Application.ExeName);
if copy(s,Length(s),1)<>'/' then
s:= s+'/';
s:= s+'LinkPara.Ini';
lpIni:= TIniFile.Create(s);
try
if not FileExists(s) then
begin
// 一号仪表
lpIni.WriteInteger('MeterInfo','1_No',1);
// 使用的串口号
lpIni.WriteInteger('MeterInfo','1_BaudRate',1200);
// 波特率
lpIni.WriteInteger('MeterInfo','1_Parity',2);
// 校验
lpIni.WriteInteger('MeterInfo','1_Pos',4);
// 数值定位
lpIni.WriteInteger('MeterInfo','1_Len',6);
// 数值串长
// 二号仪表
lpIni.WriteInteger('MeterInfo','2_No',2);
lpIni.WriteInteger('MeterInfo','2_BaudRate',1200);
lpIni.WriteInteger('MeterInfo','2_Parity',2);
lpIni.WriteInteger('MeterInfo','2_Pos',4);
lpIni.WriteInteger('MeterInfo','2_Len',6);
// 三号仪表
lpIni.WriteInteger('MeterInfo','3_No',3);
lpIni.WriteInteger('MeterInfo','3_BaudRate',1200);
lpIni.WriteInteger('MeterInfo','3_Parity',2);
lpIni.WriteInteger('MeterInfo','3_Pos',4);
lpIni.WriteInteger('MeterInfo','3_Len',6);
// 四号仪表
lpIni.WriteInteger('MeterInfo','4_No',4);
lpIni.WriteInteger('MeterInfo','4_BaudRate',1200);
lpIni.WriteInteger('MeterInfo','4_Parity',2);
lpIni.WriteInteger('MeterInfo','4_Pos',4);
lpIni.WriteInteger('MeterInfo','4_Len',6);
end;
for i:= 1 to 4 do
begin
s:= IntToStr(i);
ComInfo.cCommNum:= 'COM'+
IntToStr(lpIni.ReadInteger('MeterInfo',s+'_No',i));
ComInfo.cBaudRate:= lpIni.ReadInteger('MeterInfo',s+'_BaudRate',1200);
ComInfo.cParity:= lpIni.ReadInteger('MeterInfo',s+'_Parity',2);
MeterInfo.DatPos:= lpIni.ReadInteger('MeterInfo',s+'_Pos',4);
MeterInfo.DatLen:= lpIni.ReadInteger('MeterInfo',s+'_Len',6);
end;
result:= True;
finally
lpIni.Free;
end;
end;

// 打开并设置串口
procedure OpenComm(num: integer);
var
ComDCB: TDCB;
CTO: TCOMMTIMEOUTS;
begin
ComInfo[num].cHandle:= CreateFile( pchar(ComInfo[num].cCommNum),
GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0,0);
if ComInfo[num].cHandle=INVALID_HANDLE_VALUE then
raise Exception.Create('ERR1');
// 提交异常退出
try
GetCommState(ComInfo[num].cHandle, ComDCB);
ComDCB.BaudRate:= ComInfo[num].cBaudRate;
ComDCB.ByteSize:= 7;
ComDCB.Parity:= ComInfo[num].cParity;
ComDCB.StopBits:= 2;
if SetCommState(ComInfo[num].cHandle, ComDCB) = false then
raise Exception.Create('ERR1');
// 提交异常退出
CTO.ReadIntervalTimeout:= 0;
// 读区间超时
CTO.ReadTotalTimeoutConstant:= 0;
// 读超时常数
CTO.ReadTotalTimeoutMultiplier:= 50;
// 读总超时
CTO.WriteTotalTimeoutConstant:= 0;
// 写超时常数
CTO.WriteTotalTimeoutMultiplier:= 50;
// 写总超时
if SetCommTimeOUTs( ComInfo[num].cHandle, CTO ) = false then
raise Exception.Create('ERR1');
// 提交异常退出
except
CloseComm(num);
raise;
// 重新提交异常
end;
end;

// 关闭串口
procedure CloseComm(num: integer);
begin
if ComInfo[num].cHandle <> INVALID_HANDLE_VALUE then
CloseHandle( ComInfo[num].cHandle );
ComInfo[num].cHandle:= INVALID_HANDLE_VALUE;
end;

end.
 
请问,楼上,你使用的是哪个控件啊?spcomm还是mscomm啊?
 
没有使用控件,直接调用WIN API函数CreateFile(),GetCommState(),SetCommState()
SetCommState(),CloseHandle(),ReadFile(),WriteFile()。
 
to kk98
高手,佩服!!!!!
[:)][8D][:)][8D]
 
to kk98 :
超级高手!怎样才能跟您保持长期联系。
 
我也不是什么高手,只是以前对常洲托利多地磅仪表的串口读取程序写得比较多,较为
熟悉而已,现在我从事的是网络设计安装工作,和编程没有多大关系了。所以也没什么必
要联系了!
 
写了读COM串口的程序后,不在地磅边怎样进行测试呀?
 
如果你是帮地磅的销售商开发软件,那问他们借一个很小的地磅模拟器和一台仪表进
行模拟!如果是给地磅用户开发的,那你只能去现场了!
 
to kk98
谢谢大哥,在你的程序里,我学到了不少东西!
 
最好要知道电子秤发出的数据格式,要不就得花时间好好分析了
对了,你要做的电子秤是哪家公司的,它的型号是什么的?
 
to: wwolf
我只知道称重显示器是台湾弘邦HB-8210,大屏幕和电脑都是从这里接出来的,你有没有做过呀
请多指教!
 
后退
顶部