前言
最近的一个项目,使用三菱MC协议通讯,一开始自己查了通讯协议的报文,简单的写了M区的BOOL量的读取写入,单独测试是OK的,但是运行过程中会出现异常的反馈(例如:实际为True的值读出来是False),后来是在是找不到原因,而且急用,就尝试使用三菱的官方插件,并使用c++做二次开发,最后实际运用没有再发现异常反馈了。
一 、三菱插件
(一)三菱插件安装请自行安装(偷懒。。。)
(二)连接PLC并配置通讯
1.首先打开刚安装的Communication Settings Utility软件;
2.软件打开后点击Wizard进行配置;
3.设置逻辑工站编号:当前设置为1(记住这个,连接时需要用到)
4.设置基本参数:注意,本文使用的是Q13UDVCPU型号的三菱PLC,使用网线连接到了PLC,大家需要根据实际硬件选择对应的连接模式和通讯方式
5.设置PLC的IP地址:其他的连接模式有不同的界面,当前的CPU Module模式只需要输入连接的PLC地址即可(注意主机与PLC要同一网段!)
6.设置网络:选择Host station、选择对应型号的标签
7.设置通讯的别称:Comment,本文直接设置为123
8.然后直接点击Finish,完成基本PLC的设置;
9.测试通讯:选择软件的Communication test页面,点击Test
10.弹出以下界面表示通讯成功,即可开始二次开发!
二、C++二次开发
(一)基本操作
1.创建MFC窗体工程:正常创建对话框即可,不需要文档
2.在空白处右键菜单选择插入控件
3.插入的控件有两种,ActProgType Control、ActUtlType Control(本文使用的是这个)
4.选择后界面会出现图标
5.右键添加变量m_ActUltType
完成变量添加后会自动在解决方案目录下生成文件
(二)实际功能
至此完成了基本操作,接下来将完成实际功能;
1.简单绘制UI界面
2.连接
long lRet;
CString MsgStr;
try
{
//注意:前面设置的逻辑站号在这里使用
m_ActUltType.put_ActLogicalStationNumber(1);
lRet = m_ActUltType.Open();
if (lRet == 0x00)
{
MsgStr.Format(_T("打开成功:0x%08x [HEX]"), lRet);
}
else
{
MsgStr.Format(_T("打开失败:0x%08x [HEX]"), lRet);
}
}
catch (const std::exception&)
{
MsgStr.Format(_T("打开失败:0x%08x [HEX]—异常退出"), lRet);
}
AfxMessageBox(MsgStr);
3.断开
long lRet;
CString MsgStr;
UpdateData(TRUE);
try
{
lRet = m_ActUltType.Close();
if (lRet == 0x00)
{
MsgStr.Format(_T("断开成功:0x%08x [HEX]"), lRet);
}
else
{
MsgStr.Format(_T("断开失败:0x%08x [HEX]"), lRet);
}
}
catch (const std::exception&)
{
MsgStr.Format(_T("断开失败:0x%08x [HEX]—异常退出"), lRet);
}
AfxMessageBox(MsgStr);
4.读取
UpdateData(TRUE);
long lRet, lValue;
CString MsgStr, strName;
GetDlgItem(IDC_EDIT_NAME)->GetWindowTextW(strName);
if (_T("") == strName)
{
MsgStr = _T("选择软原件名为空,请正确输入软原件名");
AfxMessageBox(MsgStr);
return;
}
try
{
LPTSTR lpszText = strName.GetBuffer();
lRet = m_ActUltType.GetDevice(lpszText, &lValue);
if (lRet == 0x00)
{
MsgStr.Format(_T("%s读取成功:0x%08x [HEX]"), strName, lValue);
}
else
{
MsgStr.Format(_T("%s读取失败:0x%08x [HEX]"), strName, lRet);
}
}
catch (const std::exception&)
{
MsgStr.Format(_T("%s读取失败:0x%08x [HEX]—异常退出"), strName, lRet);
}
AfxMessageBox(MsgStr);
5.写入
UpdateData(TRUE);
long lRet, lValue;
CString MsgStr, strName, strValue;
GetDlgItem(IDC_EDIT_NAME)->GetWindowTextW(strName);
GetDlgItem(IDC_EDIT_VALUE)->GetWindowTextW(strValue);
if (_T("") == strName)
{
MsgStr = _T("选择软原件名为空,请正确输入软原件名");
AfxMessageBox(MsgStr);
return;
}
lValue = _ttoi64(strValue);
try
{
LPTSTR lpszText = strName.GetBuffer();
lRet = m_ActUltType.SetDevice(lpszText, lValue);
if (lRet == 0x00)
{
MsgStr.Format(_T("%s写入成功:0x%08x [HEX]"), strName, lValue);
}
else
{
MsgStr.Format(_T("%s写入失败:0x%08x [HEX]"), strName, lRet);
}
}
catch (const std::exception&)
{
MsgStr.Format(_T("%s写入失败:0x%08x [HEX]—异常退出"), strName, lRet);
}
AfxMessageBox(MsgStr);