C++ MFC与三菱PLC通讯

本篇文章讲述的是使用C++ mfc与三菱plc成功建立连接,并在程序中实现与PLC的数据交换。

1.建立连接

三菱公司提供了三菱PLC和上位机的通讯辅助软件:MX Component

1. 下载并安装MX Component软件:网上搜索MX Component下载安装即可,此处不做详细描述;
 2. 安装完成后打开
Communication Setup Utility,软件图标如图所示:(注意,打开软件时请以管理员身份运行,否则设置完测试连接时会出现权限不够的提示

3. 点击Wizard向导,随着向导进行连接相关配置;

4.逻辑站点号随便填一个数字即可,后面可以在总览中看到这个(但请注意,如果使用的utl方式,这个会在程序中使用):

C++ MFC与三菱PLC通讯_第1张图片然后点击next到下一步。

5.这一步选择连接方式和连接的PLC种类,以及设置连接超时时间。此处我用的是以太网连接方式,连接的是三菱FX5U PLC,设置如下图:

C++ MFC与三菱PLC通讯_第2张图片设置完成后点next进行到下一步。

6.这一步是输入PLC的IP地址

C++ MFC与三菱PLC通讯_第3张图片

可点击

按钮,它会自动查找当前与电脑连接的设备

C++ MFC与三菱PLC通讯_第4张图片完成后进行下一步

7.此处一般用默认即可,不需要更改,直接进入下一步;

C++ MFC与三菱PLC通讯_第5张图片

8.这一步是填写注释,用于说明这一次的连接配置,可以不写,此处我填个1:

C++ MFC与三菱PLC通讯_第6张图片完成后点finish

9.选到Connection test栏进行连接测试

C++ MFC与三菱PLC通讯_第7张图片

test按钮,出现如下连接成功标志则说明配置成功,否则检查前面几步再重新测试。

C++ MFC与三菱PLC通讯_第8张图片

到此连接配置已经完成,关掉软件,下面开始讲述程序编写。

2.程序设计

下面我将以我编写的测试程序为例对具体的步骤进行详细讲解。

1.新建MFC应用程序,编辑主界面,我的测试程序主界面如下

C++ MFC与三菱PLC通讯_第9张图片

这两个图标是三菱厂商提供的activex控件,在主界面中右键“插入ActiveX控件”,这两个控件分别对应下面两个:

C++ MFC与三菱PLC通讯_第10张图片

C++ MFC与三菱PLC通讯_第11张图片

本文中的实际连接测试中只用到了第一种操作方式,但包含了两种方式的操作代码。

点击添加的activex控件,右键“添加变量”,

C++ MFC与三菱PLC通讯_第12张图片

两个添加的控件都要进行如下操作,名字自己定义。

添加完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);
}

3.软件测试结果演示

点击打开连接,返回值为0后设置软元件“D1”的值为1,然后再读取,显示结果如下:

C++ MFC与三菱PLC通讯_第13张图片

至此,C++ MFC和PLC的通讯就讲解完了,欢迎大家在评论区提出问题和不同意见,需要文中演示程序的也可以在评论区和我说,谢谢!

你可能感兴趣的:(C++,C++,MFC,PLC,通讯)