最近需要做个界面读取三菱PLC数据存入数据库,记录c#使用MXComponent4插件与模拟三菱PLC实验。
GX Works2设置
新建一个工程
打开PLC参数设置
设置PLC文件
设置软元件
开始模拟
打开软元件监视
设置软元件,例如D0
开始监视软元件,在后续的测试中修改数据值
MXComponent4插件配置
安装完MXComponent4后以管理员身份打开插件
然后打开设置站点,例如66
进行模拟方式选择GX Simulator2
填写备注完成
测试与模拟PLC通信
然后就可以使用C#做界面通信了
C#编程
在工程添加引用库
创建实例对象
private ActUtlTypeLib.ActUtlTypeClass m_plc;
m_plc = new ActUtlTypeLib.ActUtlTypeClass();
设置站点密码
m_plc.ActLogicalStationNumber = 66; //设置站点,之前设置的66
m_plc.ActPassword = ""; //密码为空
打开PLC连接
try
{
int iReturnCode = m_plc.Open(); //直接使用Open方法打开
if (iReturnCode != 0)
{
string err = String.Format("0x{0:x8} [HEX]", iReturnCode);
button1.BackColor = Color.Gray;
button1.Text = "未建立链接";
MessageBox.Show($"通断PLC连接错误:{err}");
m_plc.Close();
}
else
{
button1.BackColor = Color.Green;
button1.Text = "已连接";
}
}
catch (Exception ex)
{
if (ex != null)
{
log.Error(ex);
}
MessageBox.Show(ex.Message, Name,
MessageBoxButtons.OK, MessageBoxIcon.Error);
Console.WriteLine("通断PLC连接错误");
}
软元件数据测试,批量读取,使用ReadDeviceBlock2(string szDevice, int lSize, out short lpsData)方法读取
int iReturnCode; //返回值
short[] arrDeviceValue; //接收的值
string szDeviceName = ""; //软元件名称
System.String[] arrData;
int iNumberOfData = 0; //读取数据数量
szDeviceName = string.Join("\n", "D0");
iNumberOfData = 3;
arrDeviceValue = new short[iNumberOfData];
try
{
iReturnCode = m_plc.ReadDeviceBlock2(szDeviceName, iNumberOfData, out arrDeviceValue[0]);
if (iReturnCode == 0)
{
arrData = new System.String[iNumberOfData];
for (int i = 0; i < iNumberOfData; i++)
{
arrData[i] = arrDeviceValue[i].ToString();
Console.WriteLine(arrData[i]);
}
}
else
{
string err = String.Format("0x{0:x8} [HEX]", iReturnCode);
MessageBox.Show($"通断PLC数据获取失败:{err}");
}
}
catch (Exception ex)
{
if (ex != null)
{
log.Error(ex);
}
MessageBox.Show(ex.Message, Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
测试,设置D0为20,D1为30,D2为40,查看返回结果
监视功能测试
监视功能类似于订阅的方式,监视软元件例如:D0,监视的值为2,当D0的值为2的时候,PLC将会以设置的频率通知上位机,上位机通过事件来处理通知。
软元件监视登录
使用EntryDeviceStatus(string szDeviceList, int lSize, int lMonitorCycle, ref int lplData)方法登录软元件监视。
/***************监视D0的值为2,当D0为2的时候以一秒一次触发通知************/
int iReturnCode;
String szDeviceName = ""; //软元件名
int iNumberOfData = 1; //数量
int iMonitorCycle = 1; //监视周期
int[] arrDeviceValue; //监视数值
szDeviceName = String.Join("\n", "D0");
arrDeviceValue = new int[] { 2 };
try
{
iReturnCode = m_plc.EntryDeviceStatus(szDeviceName,
iNumberOfData,
iMonitorCycle,
ref arrDeviceValue[0]);
if (iReturnCode == 0) {
Console.WriteLine("监视成功");
}
else {
string err = String.Format("0x{0:x8} [HEX]", iReturnCode);
MessageBox.Show($"通断PLC数据连接错误:{err}");
}
}
catch (Exception ex)
{
if (ex != null)
{
log.Error(ex);
}
MessageBox.Show(ex.Message, Name,
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
通知事件,我们可以在事件通知里进行接到通知后的操作。
/*****szDevice为软元件名,iData数据,iReturnCode返回值,打印出软元件值******/
private void m_plc_OnDeviceStatus(String szDevice, int iData, int iReturnCode)
{
System.String[] arrData;
arrData = new System.String[txt_Data.Lines.Length + 1];
Array.Copy(txt_Data.Lines, arrData, txt_Data.Lines.Length);
arrData[txt_Data.Lines.Length]
= String.Format("OnDeviceStatus [{0}={1}]", szDevice, iData);
txt_Data.Lines = arrData;
Console.WriteLine(String.Format("0x{0:x8}", iReturnCode));
}
添加通知事件
m_plc.OnDeviceStatus +=
new ActUtlTypeLib._IActUtlTypeEvents_OnDeviceStatusEventHandler(m_plc_OnDeviceStatus);
把D0的值改为2,进行测试
结果以1秒的频率触发通知事件
到此实验完成