在与PLC通讯时,反馈的信息出现时好时坏的现象(乱码),已头痛了半个月多了,帮助!
解决方案 »
- delphi程序设计基础问题
- 各位大哥帮我看看这个问题,出错在哪?在线等...........
- 图像处理的怪怪问题,急。。。请各位大侠帮忙。
- 急啊!怎么从定义好的子界类型变量里取它的第n个值
- 在存储过程中调用exec的问题
- 为什么我在做asp组件时为什么TChart用不成?找到解决办法立即给分!
- 那位大虾能告诉我DELPHI6的产品号,我这厢有礼了!!!
- 如何取得音量电平?
- 请教!自定义函数怎么使用,加在程序哪里?
- 关于数型结构数据库的存储问题!
- 请朋友解决拦路虎--DBNavigator的使用,当连接上datesourse时,按扭怎么变成灰色
- socket通讯数据丢失问题(有挑战难度,解决后另加50分)
用线情况,设备距离,拓扑结构,延时和设备号的协议设置都有关系有可能时上位机端误读 也有可能是PLC端分时抢用错误具体情况 具体分析贴点错误信息和源代码上来看看。
proc_initcom(ps_crn_ip);
s_crnhead := #0+#0+#0+#0+#0+#6+#$FF+#3+#0+#$A+#0+#$1E;
Send(sk,pointer(s_crnhead)^,Length(s_crnhead),0);
n:=recv(sk,Buf,209,0);
for i:=1 to 30 do
begin
m:=i;
num:=256*ord(buf[i*2 + 8]) + ord(buf[i*2 + 9]);
dev_sts[m]:=num; s_recstr:=s_recstr+inttostr(num);
end;
Closesocket(sk);
sleep(ci_CRNtimeInterval);写:procedure TMXCraneThread1.proc_SetCrn_ID(i_type1,i_srow1,i_sbay1,i_slev1,i_drow1,i_dbay1,i_dlev1 : integer);
var s_crnhead,s_chksum,s_SendString : String;
s_RecStr : String;
i_nRetry : integer;
b_OK : Boolean;
s_mess,s_type,s_srow,s_sbay,s_slev,s_drow,s_dbay,s_dlev,add:string;
bte :array [1..14] of byte;
bte1:array [1..2] of byte;
begin
i_nRetry := 1;
b_OK := False;
repeat
s_type :=inttohex(i_type1,4);
bte[1] :=hextodec(copy(s_type,1,2));
bte[2] :=hextodec(copy(s_type,3,2)); s_srow :=inttohex(i_srow1,4);
bte[3] :=hextodec(copy(s_srow,1,2));
bte[4] :=hextodec(copy(s_srow,3,2)); s_sbay :=inttohex(i_sbay1,4);
bte[5] :=hextodec(copy(s_sbay,1,2));
bte[6] :=hextodec(copy(s_sbay,3,2)); s_slev :=inttohex(i_slev1,4);
bte[7] :=hextodec(copy(s_slev,1,2));
bte[8] :=hextodec(copy(s_slev,3,2)); s_drow :=inttohex(i_drow1,4);
bte[9] :=hextodec(copy(s_drow,1,2));
bte[10]:=hextodec(copy(s_drow,3,2)); s_dbay :=inttohex(i_dbay1,4);
bte[11]:=hextodec(copy(s_dbay,1,2));
bte[12]:=hextodec(copy(s_dbay,3,2)); s_dlev :=inttohex(i_dlev1,4);
bte[13]:=hextodec(copy(s_dlev,1,2));
bte[14]:=hextodec(copy(s_dlev,3,2)); add :=inttohex(100,4);
bte1[1]:=hextodec(copy(add,1,2));
bte1[2]:=hextodec(copy(add,3,2)); proc_initcom(ps_crn_ip);
s_crnhead := #0+#1+#0+#0+#0+#$15+#$FF+#$10+chr(bte1[1])+chr(bte1[2])+#0+#$7+#$E+chr(bte[1])+chr(bte[2])+chr(bte[3])+chr(bte[4])+chr(bte[5])+chr(bte[6])+chr(bte[7])+chr(bte[8])+chr(bte[9])+chr(bte[10])+chr(bte[11])+chr(bte[12])+chr(bte[13])+chr(bte[14]);
Send(sk,pointer(s_crnhead)^,Length(s_crnhead),0); ps_crnthr_mess_sendtocrn :='01000$15$FF$1010007$E'+s_type+s_srow+s_sbay+s_slev+s_drow+s_dbay+s_dlev;
Synchronize(proc_Update_ptmemo_crnthr_mess_send);
Sleep(ci_CRNtimeInterval);
Closesocket(sk); Inc(i_nRetry);
if i_nRetry=3 then
begin
b_OK := True;
end;
until (b_OK=TRUE);
end;
这是用TCP/IP控件(都有相同的问题):读:
s_crnhead := #0+#0+#0+#0+#0+#6+#$FF+#3+#0+#$A+#0+#$1E;
ps_crnthr_mess_sendtocrn :='000006$FF30$A0$1E';
Synchronize(proc_Update_ptmemo_crnthr_mess_send); p_TcpClient_crn.Active:=true;
p_TcpClient_crn.Sendln(s_crnhead) ;
pi_return:=p_TcpClient_crn.ReceiveFrom(buf,209,p_TcpClient_crn.GetSocketAddr(p_TcpClient_crn.RemoteHost,p_TcpClient_crn.RemotePort),n,0); if pi_return>0 then
begin
recstr:='';
for i:=1 to 30 do
begin
m:=i+99;
num:=256*ord(buf[i*2 + 8]) + ord(buf[i*2 + 9]);
dev_sts[i]:=num;
recstr:=recstr+inttostr(num);
end; ps_crnthr_mess_response := recstr; proc_Show_crn_response_MSG;
end; Sleep(ci_CRNtimeInterval);
p_TcpClient_crn.Disconnect;
p_TcpClient_crn.Active:=false; proc_Add_crn_Seqcount;
if Trim(ps_crnthr_mess_response)<>'' then
begin
proc_crnstatus(ps_crnthr_mess_response);
end;写: i_nRetry := 1;
b_OK := False; s_type :=inttohex(i_type1,4);
bte[1] :=hextodec(copy(s_type,1,2));
bte[2] :=hextodec(copy(s_type,3,2)); s_srow :=inttohex(i_srow1,4);
bte[3] :=hextodec(copy(s_srow,1,2));
bte[4] :=hextodec(copy(s_srow,3,2)); s_sbay :=inttohex(i_sbay1,4);
bte[5] :=hextodec(copy(s_sbay,1,2));
bte[6] :=hextodec(copy(s_sbay,3,2)); s_slev :=inttohex(i_slev1,4);
bte[7] :=hextodec(copy(s_slev,1,2));
bte[8] :=hextodec(copy(s_slev,3,2)); s_drow :=inttohex(i_drow1,4);
bte[9] :=hextodec(copy(s_drow,1,2));
bte[10]:=hextodec(copy(s_drow,3,2)); s_dbay :=inttohex(i_dbay1,4);
bte[11]:=hextodec(copy(s_dbay,1,2));
bte[12]:=hextodec(copy(s_dbay,3,2)); s_dlev :=inttohex(i_dlev1,4);
bte[13]:=hextodec(copy(s_dlev,1,2));
bte[14]:=hextodec(copy(s_dlev,3,2)); add :=inttohex(100,4);
bte1[1]:=hextodec(copy(add,1,2));
bte1[2]:=hextodec(copy(add,3,2));
s_crnhead := #0+#1+#0+#0+#0+#$15+#$FF+#$10+chr(bte1[1])+chr(bte1[2])+#0+#$7+#$E+chr(bte[1])+chr(bte[2])+chr(bte[3])+chr(bte[4])+chr(bte[5])+chr(bte[6])+chr(bte[7])+chr(bte[8])+chr(bte[9])+chr(bte[10])+chr(bte[11])+chr(bte[12])+chr(bte[13])+chr(bte[14]); ps_crnthr_mess_sendtocrn :='01000$15$FF$1010007$E'+s_type+s_srow+s_sbay+s_slev+s_drow+s_dbay+s_dlev;
Synchronize(proc_Update_ptmemo_crnthr_mess_send);
p_TcpClient_crn.Active:=true;
p_TcpClient_crn.Sendln(s_crnhead) ;
Sleep(ci_CRNtimeInterval);
p_TcpClient_crn.Disconnect;
p_TcpClient_crn.Active:=false; Inc(i_nRetry);
if i_nRetry=3 then
begin
b_OK := True;
end;
因为我们用的是TCP/IP协议 但是底层协议的物理电气层协议的本质还是串口所以如果用我们和服务器交流的概念和PLC交流
可能PLC的速度不能满足你的软件设置速度误差累计到了一段时间 就可能造成缓冲区接收池溢出
重新启动 等于清空了缓冲区 试着改变延时试试
现在设备故障不在于软件的缓冲区的问题
而是因为底层的串口硬件的缓存区问题
所以增加线程不能根本解决误差问题
用2个串口还差不多
的叠加呢?
我刚刚从事这方面,也是做上位TCP/IP机和PLC通讯的,用的是三菱的产品,在搜集资料中,请多多指教。
TClient=class
Socket:TSocket;
SocketBuf:Array of Byte;
SocketBufIndex:Integer;
end;
//保存所有客户端的列表
TClientList=class
FList:TList;end;
//SOCKET对象收到数据
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
obj:TClient;
begin
先通过SOCKET查找到对应的客户端对象
obj:=TClientList.FindClient(Socket);
Socket.ReceiveBuf(obj.SocketBuf,数据长度);//这里是关键,将所客户端发来的数据保存在客户端对象
各自的缓冲区中
obj.SocketBufIndex:=obj.SocketBufIndex+这次收到的数据长度;
end;现在每个客户端自己的数据都保存在自己对应的缓冲区了。每个客户端的缓冲区可以设置成10K
如果数据满了则在扩大。
在另外搞一个线程,检查TClientList中的每个客户端的缓冲区,如果有数据就将数据业务处理,然后
SocketBufIndex也相应该的缩短要注意的是如果向缓冲区写数据和处理数据不是一个对象的话,要进行线程保护。