C#与西门子plc 做通讯的例子 会的高手请给个例子

2024年11月19日 21:28
有3个网友回答
网友(1):

运用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;

}

网友(2):

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();
}

网友(3):

叶帆写过相关ppi