本篇文章讲述的是使用C++ mfc与三菱plc成功建立连接,并在程序中实现与PLC的数据交换。
三菱公司提供了三菱PLC和上位机的通讯辅助软件:MX Component
1. 下载并安装MX Component软件:网上搜索MX Component下载安装即可,此处不做详细描述;
2. 安装完成后打开Communication Setup Utility,软件图标如图所示:(注意,打开软件时请以管理员身份运行,否则设置完测试连接时会出现权限不够的提示)
3. 点击Wizard向导,随着向导进行连接相关配置;
4.逻辑站点号随便填一个数字即可,后面可以在总览中看到这个(但请注意,如果使用的utl方式,这个会在程序中使用):
5.这一步选择连接方式和连接的PLC种类,以及设置连接超时时间。此处我用的是以太网连接方式,连接的是三菱FX5U PLC,设置如下图:
6.这一步是输入PLC的IP地址
可点击
7.此处一般用默认即可,不需要更改,直接进入下一步;
8.这一步是填写注释,用于说明这一次的连接配置,可以不写,此处我填个1:
9.选到Connection test栏进行连接测试
点test按钮,出现如下连接成功标志则说明配置成功,否则检查前面几步再重新测试。
到此连接配置已经完成,关掉软件,下面开始讲述程序编写。
下面我将以我编写的测试程序为例对具体的步骤进行详细讲解。
1.新建MFC应用程序,编辑主界面,我的测试程序主界面如下
这两个图标是三菱厂商提供的activex控件,在主界面中右键“插入ActiveX控件”,这两个控件分别对应下面两个:
本文中的实际连接测试中只用到了第一种操作方式,但包含了两种方式的操作代码。
点击添加的activex控件,右键“添加变量”,
两个添加的控件都要进行如下操作,名字自己定义。
添加完activex控件后,会自动往工程中添加两个头文件,再加上actDefine文件,总共三个和PLC相关的头文件,
编辑代码,在主对话框的头文件中包含上面三个文件:
此外,可以在头文件中看到,头文件中自动加了这两句代码:
下面开始具体讲代码实现,包括:创建连接、关闭连接、获取指定端口值、设置指定端口值。每一个功能都专门写成一个函数,
下面先讲创建打开连接函数,代码如下:
void Cplctest1Dlg::OnBnClickedOpenButton()
{
// TODO: 在此添加控件通知处理程序代码
long lRet;
CString MsgStr;
UpdateData(TRUE);
m_return_edit = L""; //界面上的控件,用于显示操作返回值,返回0代表操作成功
// ActProgType Control
try
{
if (0 == m_nCurType) //UTL连接
{
//此处的参数1就是我们在MX COMPONENT中设置向导里面设置的逻辑站号1,实际设置的数字是 几这里就是几
m_ActUltType.put_ActLogicalStationNumber(1); // Exec set-property method
lRet = m_ActUltType.Open(); // Open method exec
}
//此种方法程序中其实没用,但是也加了进来,后面几个函数也是如此
else if (1 == m_nCurType)
{
////m_ActProType.put_ActHostAddress(L"192.168.3.250");
m_ActProType.put_ActUnitType(UNIT_FXVETHER);// Exec set-property method 0x2001 // Ethernet(FX5CPU) IP
m_ActProType.put_ActProtocolType(PROTOCOL_TCPIP);// Exec set-property method
lRet = m_ActProType.Open(); // Exec OPEN method
}
//输出
m_return_edit.Format(L"0x%08x", lRet);
}
catch (COleDispatchException *Exception){
// OLE IDispatch Interface Error
//MsgStr.LoadString(IDS_STRING103);
AfxMessageBox(L"打开连接失败");
//Exception->Delete();
}
//显示到界面
UpdateData(FALSE);
}
再是获取端口值函数代码:
void Cplctest1Dlg::OnBnClickedGetvalueButton()
{
// TODO: 在此添加控件通知处理程序代码
long lRet;
long lValue;
CString MsgStr;
UpdateData(TRUE); //获取界面中填写的端口号
m_return_edit = "";
m_retval1 = ""; //获取数值显示控件
m_retval2 = ""; //此控件用于显示PLC型号,此函数没用
//判断设备名是否为空
if (L"" == m_devicename_edit)
{
AfxMessageBox(L"选择软原件名为空,请正确输入软原件名");
return;
}
try
{
if (0 == m_nCurType) //UTL连接模式
{
lRet = m_ActUltType.GetDevice(m_devicename_edit, &lValue);// 获取数值
}
else if (1 == m_nCurType) //prog连接模式
{
// ActProgType Control
lRet = m_ActProType.GetDevice(m_devicename_edit, &lValue); //获取数值
}
if (lRet == 0x00){ // 返回值为0,说明获取成功,用两种形式显示数值
m_retval1.Format(L"0x%04x(%d)", lValue, lValue); // Device Value
}
// Renew ReturnValue
m_return_edit.Format(L"0x%08x", lRet);
}
catch (COleDispatchException *Exception)
{
// OLE IDispatch Interface Error
//MsgStr.LoadString(IDS_STRING103);
AfxMessageBox(L"获取软原件值出错");
//Exception->Delete();
}
UpdateData(FALSE);
}
然后是设置端口值函数代码:
void Cplctest1Dlg::OnBnClickedSetvalueButton()
{
// TODO: 在此添加控件通知处理程序代码
long lValue;
long lRet;
CString MsgStr;
UpdateData(TRUE);
m_return_edit = "";
m_retval1 = "";
m_retval2 = "";
if (m_devicename_edit == ""){
// Not Enter DeviceName Error
AfxMessageBox(L"选择的软原件名为空");
return;
}
lValue = m_devicevalue_edit;
try
{
// ActUtlType Control
if (0 == m_nCurType)
{
lRet = m_ActUltType.SetDevice(m_devicename_edit, lValue); // 设置值
}
else if (1 == m_nCurType)
{
// ActProgType Control
lRet = m_ActProType.SetDevice(m_devicename_edit, lValue); // 设置值
}
// Renew ReturnValue
m_return_edit.Format(L"0x%08x", lRet);
}
catch (COleDispatchException *Exception){
// OLE IDispatch Interface Error
AfxMessageBox(L"获取软原件值出错");
}
UpdateData(FALSE); //在界面上更新得到的数据
}
再是关闭连接函数代码:
void Cplctest1Dlg::OnBnClickedCloseButton()
{
// TODO: 在此添加控件通知处理程序代码
long lValue;
long lRet;
CString MsgStr;
UpdateData(TRUE);
m_return_edit = "";
m_retval1 = "";
m_retval2 = "";
try
{
if (0 == m_nCurType)
{
lRet = m_ActUltType.Close(); // 关闭连接
}
else if (1 == m_nCurType)
{
lRet = m_ActProType.Close(); // 关闭连接
}
// Renew ReturnValue
m_return_edit.Format(L"0x%08x", lRet);
}
catch (COleDispatchException *Exception){
// OLE IDispatch Interface Error
AfxMessageBox(L"连接关闭失败");
}
UpdateData(FALSE);
}
点击打开连接,返回值为0后设置软元件“D1”的值为1,然后再读取,显示结果如下:
至此,C++ MFC和PLC的通讯就讲解完了,欢迎大家在评论区提出问题和不同意见,需要文中演示程序的也可以在评论区和我说,谢谢!