在做济钢项目的时候遇到一个很大的挑战,第一济钢要求采用AB的RsLogix5000系列,第二该系统需要联入本公司自己生产的红外测位系统。由于我们的系统的通信协议是内部协议,而AB的PLC不像西门子的200系列的PLC可以对自由口编程,可以很方便的获取到数据,而AB的则不然,目前AB已经不在生产第三方接口的模块,而有其合作的ProSoft公司专门生产第三方模块。ProSoft生产的模块有很多种,由于没有经验,很不幸,我们选择的是MVI56的模块,而这个模块却是全部自由编程,不含有任何默认协议。去退货确要报价的30%作为补偿,八个模块要赔好几万,唉!... ...
剩下的事,只有研究了,花了五千银子,请了一个“专家”,对AB的产品非常熟。一星期后,终于有点眉目了,原来这个模块就是一个典型的嵌入式系统,相当一个带三个串口的386的电脑,操作系统为小型的DOS系统(TINY DOS),用C++为其开发程序。对DOS C我是非常熟的,可是如何与AB通信确不熟悉,幸好那个“专家”对此比较熟,我们二者一结合,果然成功了--效果出奇的好,不用AB PLC编一行代码,就可以实现把数据写入到变量区。下面是PLC的配置界面:
//基于 TINY DOS 的C++ 的核心通信程序
//*************************************************************************
//**函 数 名:Com_GetWHData
//**输 入:intAddr - 红外标尺地址
//** :intState - 标尺状态 0~9 -1 表示校验错误
//**输 出:无
//**功能描述:获取红外标尺的信息
//**全局变量:
//**调用模块:
//**作 者:叶帆
//**日 期:2004-11-24 16:56:57
//**修 改 人:
//**日 期:
//**版 本:V1.0.0
//*************************************************************************
void Com_GetWHData(WORD *intAddr,WORD *intState)
{
BYTE ch;
BYTE bytData[6];
BYTE bytFlag=0;
BYTE bytNum=0;
while(bytNum<7)
{
if (MVIsp_Getch(Commport,&ch,1000) != MVI_SUCCESS)
{
*intAddr=0;
*intState=9;
return;
}
if(bytFlag==1)
{
bytData[bytNum++]=ch;
}
if(ch==0xAC && bytNum==0)
{
bytFlag=1; //开始接收
}
}
//正副本校验
if(bytData[0]==bytData[1] && bytData[2]==bytData[3] && bytData[4]==bytData[5])
{
//地址信息
*intAddr=(bytData[0]>>4)*(WORD)10000+(bytData[0] & 0x0f)*(WORD)1000+(bytData[2]>>4)*(WORD)100+(bytData[2] & 0x0f)*(WORD)10+(bytData[4]>>4);
//状态信息
*intState=(bytData[4] & 0x0f);
}
else
{
*intAddr=0;
*intState=0xFF;
}
}
//*************************************************************************
//**函 数 名:ProcessCommand
//**输 入:无
//**输 出:无
//**功能描述:命令处理
//**全局变量:
//**调用模块:
//**作 者:叶帆
//**日 期:2004-11-24 16:56:57
//**修 改 人:
//**日 期:
//**版 本:V1.0.0
//*************************************************************************
int ProcessCommand(void)
{
WORD intAddr;
WORD intState;
WORD intData[2];
//读取红外标尺信息
Com_GetWHData (&intAddr,&intState);
//MVIbp_SetUserLED(handle, MVI_LED_USER1, MVI_LED_STATE_OFF);
//读取背板数据(注意,AB PLC在配置模块时,输出缓冲区的大小必须为0)
if (MVI_SUCCESS == MVIbp_ReadOutputImage(handle, intData, 0, 2))
{
//数据改变或有效才写入数据
if (intState!=0xFF && (intData[0]!=intAddr ||intData[1]!=intState))
{
intData[0]=intAddr;
intData[1]=intState;
if (MVI_SUCCESS != MVIbp_WriteInputImage(handle,intData, 0, 2))
{
return(0); //原来为1,现改为0 2005年6月8日
}
//MVIbp_SetUserLED(handle, MVI_LED_USER1, MVI_LED_STATE_ON);
}
}
return(0);
}
------------------------------------------------------------
目前我敢说,只要还是基于这种模块,只要知道协议,我就可以实现AB PLC与第三方模块的通信。其实我也这样做了,我用业余时间已经实现了 Modbus Rtu协议,实际测试后,效果不错!