运用VC#编程通过OPC方式实现PC机与西门子PLC通讯
1、 在类的开头部分生名变量
private string serverType="";
private IOPCServer pIOPCServer; // OPC server接口
private Object pobjGroup1; // Pointer to group object
private int nSvrGroupID; // server group handle for the added group
private System.Collections.Hashtable groupsID=new Hashtable(11); //用于记录组名和组ID号
private System.Collections.Hashtable hitemsID=new Hashtable(17); //用于记录项名和项ID号
private Guid iidRequiredInterface;
private int hClientGroup = 0; //客户组号
private int hClientItem=0; //Item号
2、 创建服务器,编写Open()方法
/// 创建一个OPC Server接口
///
/// 返回错误信息
/// 若为true,创建成功,否则创建失败
public bool Open(out string error)
{
error="";bool success=true;
Type svrComponenttyp ;
//获取 OPC Server COM 接口
iidRequiredInterface = typeof(IOPCItemMgt).GUID;
svrComponenttyp = System.Type.GetTypeFromProgID(serverType);
try
{
//创建接口
pIOPCServer =(IOPCServer)System.Activator.CreateInstance(svrComponenttyp);
error="";
}
catch (System.Exception err) //捕捉失败信息
{
error="错误信息:"+err.Message;success=false;
}
Return true;
}
3、 在服务器上添加用于添加Group的函数
/// 添加组
/// 组名
/// /创建时,组是否被激活
/// //组的刷新频率,以ms为单位
/// 返回错误信息
/// 若为true,添加成功,否则添加失败
public bool AddGroup(string groupName,int bActive,int updateRate,out string error)
{
error="";
int dwLCID = 0x407; //本地语言为英语
int pRevUpdateRate;
float deadband = 0;
// 处理非托管COM内存
GCHandle hDeadband;
IntPtr pTimeBias = IntPtr.Zero;
hDeadband = GCHandle.Alloc(deadband,GCHandleType.Pinned);
try
{
pIOPCServer.AddGroup(groupName, //组名
bActive, //创建时,组是否被激活
updateRate, //组的刷新频率,以ms为单位
hClientGroup, //客户号
pTimeBias, //这里不使用
(IntPtr)hDeadband,
dwLCID, //本地语言
out nSvrGroupID, //移去组时,用到的组ID号
out pRevUpdateRate, //返回组中的变量改变时的最短通知时间间隔
ref iidRequiredInterface,
out pobjGroup1); //指向要求的接口
hClientGroup=hClientGroup+1;
int groupID=nSvrGroupID;
groupsID.Add(groupName,groupID);
}
catch (System.Exception err) //捕捉失败信息
{
error="错误信息:"+err.Message;
}
finally
{
if (hDeadband.IsAllocated) hDeadband.Free();
}
if(error=="")
return true;
else
return false;
}
GetGroupByName()这个方法是OPC方式吧,不是有.NET的程序集体直接读写PLC吗?
PPI是200系列的串口485通讯,提供一段代码:
WinComS7.ComPPI PLC = new WinComS7.ComPPI();
WinComS7.ComPPI.PlcMemory I = WinComS7.ComPPI.PlcMemory.DI;
WinComS7.ComPPI.PlcMemory Q = WinComS7.ComPPI.PlcMemory.DQ;
WinComS7.ComPPI.PlcMemory M = WinComS7.ComPPI.PlcMemory.MR;
WinComS7.ComPPI.PlcMemory V = WinComS7.ComPPI.PlcMemory.DR;
bool EntLink;
public void butLink_Click(System.Object sender, System.EventArgs e)
{
short re = 0;
string restr = "";
re = PLC.ComLink(Convert.ToUInt16(txtStation.Text),Convert.ToUInt16(txtPort.Text), Convert.ToUInt32(txtRate.Text), 8, 1, WinComS7.ComPPI.ParityType.Even, Convert.ToUInt16(txtDelay.Text), "DEMO");
txtReLink.Text = re.ToString();
if (re == 0)
{
EntLink = true;
MessageBox.Show("PLC联接成功: " + restr);
}
else
{
EntLink = false;
MessageBox.Show("PLC联接失败: " + restr);
}
}
public void butClose_Click(System.Object sender, System.EventArgs e)
{
short re = 0;
if (!EntLink)
{
MessageBox.Show("还未与PLC建立联接!");
return;
}
re = PLC.DeLink();
txtReClose.Text = re.ToString();
}
public void butRead_Click(System.Object sender, System.EventArgs e)
{
short i = 0;
object[] RD = null;
RD = new object[Convert.ToUInt16(System.Convert.ToString(double.Parse(txtReadCnt.Text) - 1)) + 1];
if (!EntLink)
{
MessageBox.Show("还未与PLC建立联接!");
return;
}
int var1 = cmbReadType.SelectedIndex + 1;
WinComS7.ComPPI.DataType typ = (WinComS7.ComPPI.DataType)var1;
switch (cmbReadMry.SelectedIndex)
{
case 0:
ScanRet = PLC.CmdRead(Convert.ToUInt16(txtStation.Text), I, typ, Convert.ToUInt16(txtReadAdd.Text), Convert.ToUInt16(txtReadCnt.Text), ref RD);
break;
case 1:
ScanRet = PLC.CmdRead(Convert.ToUInt16(txtStation.Text), Q, typ, Convert.ToUInt16(txtReadAdd.Text), Convert.ToUInt16(txtReadCnt.Text), ref RD);
break;
case 2:
ScanRet = PLC.CmdRead(Convert.ToUInt16(txtStation.Text), M, typ, Convert.ToUInt16(txtReadAdd.Text), Convert.ToUInt16(txtReadCnt.Text), ref RD);
break;
case 3:
ScanRet = PLC.CmdRead(Convert.ToUInt16(txtStation.Text), V, typ, Convert.ToUInt16(txtReadAdd.Text), Convert.ToUInt16(txtReadCnt.Text), ref RD);
break;
}
txtReRead.Text = ScanRet.ToString();
lstRead.Items.Clear();
for (i = 0; i <= (RD.Length - 1); i++)
{
if (!(RD[i] == null))
{
lstRead.Items.Add(RD[i]);
}
else
{
lstRead.Items.Add("0");
}
}
}
public void butWrite_Click(System.Object sender, System.EventArgs e)
{
short i = 0;
string[] temp = null;
object[] WD = null;
if (!EntLink)
{
MessageBox.Show("还未与PLC建立联接!");
return;
}
WD = new object[Convert.ToUInt16(txtWriteCnt.Text) - 1 + 1];
temp = txtWrite.Text.Split('\n');
for (i = 0; i <= (WD.Length - 1); i++)
{
if (i > (temp.Length - 1))
{
WD[i] = 0;
}
else
{
WD[i] = temp[i].Trim();
}
}
int var1 = cmbWriteType.SelectedIndex + 1;
WinComS7.ComPPI.DataType typ = (WinComS7.ComPPI.DataType)var1;
switch (cmbWriteMry.SelectedIndex)
{
case 0:
ScanRet = PLC.CmdWrite(Convert.ToUInt16(txtStation.Text), I, typ, Convert.ToUInt16(txtWriteAdd.Text), Convert.ToUInt16(txtWriteCnt.Text), ref WD);
break;
case 1:
ScanRet = PLC.CmdWrite(Convert.ToUInt16(txtStation.Text), Q, typ, Convert.ToUInt16(txtWriteAdd.Text), Convert.ToUInt16(txtWriteCnt.Text), ref WD);
break;
case 2:
ScanRet = PLC.CmdWrite(Convert.ToUInt16(txtStation.Text), M, typ, Convert.ToUInt16(txtWriteAdd.Text), Convert.ToUInt16(txtWriteCnt.Text), ref WD);
break;
case 3:
ScanRet = PLC.CmdWrite(Convert.ToUInt16(txtStation.Text), V, typ, Convert.ToUInt16(txtWriteAdd.Text), Convert.ToUInt16(txtWriteCnt.Text), ref WD);
break;
}
txtReWrite.Text = ScanRet.ToString();
}
叶帆写过相关ppi