搞了很久终于来博客上记录自己的学习笔记;前段时间老板要我做一个项目,就是要写一个上位软件,能与三菱通讯,进行数据交换,查了很多资料研究了几天,自己写通讯协议很麻烦,网上有很多说法,我采取了简便的方法,通过MX Component软件提供的控件来编程实现PC与PLC通讯。
在三菱官网上下载MX Component软件,如图:
注意:在安装软件的时候需要序列号,需要大家在官网上注册自己的信息就可以获取;在这里我也可以提供一个免费的序列号:998-598638072。
傻瓜式的安装软件直到完成;完成以后在自己电脑开始找到Communication Setup Utility 与PLC Monitor先打开Communication Setup Utility设置通讯事项如图:
打开软件后点击Wizard出现设置站点号:
这里的站点号设置了记清楚,后面程序会用到;设置好以后点击next,设置串口信息:
选择自己对应的串口后以后点击Next
选择你要通讯的PLC型号,点击Next
点击Next以后就完成了通讯的配置,接着打开PLC Monitor与PLC通讯测试:
点击OK就完成了测试,读取数据:
打开Visual Studio软件新建C#窗体程序,这里要安装三菱的控件包:
安装完成以后会在工具栏底部出现需要调用的控件:
然后就可以编写上位代码了:
private void PLC_Connect()
{
string szCpuName = "";
int iCpuType = 0;
try
{
axActUtlType1.ActPassword = "";
axActUtlType1.ActLogicalStationNumber = Convert.ToInt16(0);//PLC逻辑站点号
iReturn = axActUtlType1.Open();
} catch
{
MessageBox.Show("PLC连接失败!");
}
if (iReturn == 0)
{
int CpuType = axActUtlType1.GetCpuType(out szCpuName, out iCpuType);
MessageBox.Show("PLC连接成功!");
// button6.Enabled = false;
button6.BackColor = Color.Red;
}
else
{
MessageBox.Show("PLC连接失败!");
}
}
/********************************************************
* 功能:读取PLC寄存器中的值
* Address:起始地址,如D0
* Datasize:寄存器大小 16位/32位
* Databitnum:读取数据的个数
* DataValue:读取到的数据,以数组输出
*********************************************************/
private void Read_PLC_DRegisterValue(string Address, int Datasize, int Databitnum, ref int[] DataValue)
{
try
{
int iReturnCode;
String[] arrdata = null;
short[] arrDeviceValue = null;
int iNum;
if (Datasize == 16 || Datasize == 32)
{
if (Datasize == 16)
{
arrdata = new String[Databitnum];
DataValue = new int[Databitnum];
arrDeviceValue = new short[Databitnum];
iReturnCode = axActUtlType1.ReadDeviceBlock2(Address, Databitnum, out arrDeviceValue[0]);
for (iNum = 0; iNum < Databitnum; iNum++)
{
DataValue[iNum] = arrDeviceValue[iNum];
}
}
else
{
arrdata = new String[2 * Databitnum];
DataValue = new int[Databitnum];
Databitnum = 2 * Databitnum;
arrDeviceValue = new short[2 * Databitnum];
iReturnCode = axActUtlType1.ReadDeviceBlock2(Address, Databitnum, out arrDeviceValue[0]);
if (iReturnCode == 0)
{
for (iNum = 0; iNum < Databitnum; iNum++)
{
arrdata[iNum] = arrDeviceValue[iNum].ToString();
}
for (iNum = 0; iNum < Databitnum; iNum = iNum + 2)
{
if (arrDeviceValue[iNum] < 0 && arrDeviceValue[iNum + 1] <= 0)
{
DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1]) + 1) + Convert.ToInt16(arrdata[iNum]);
}
else if (arrDeviceValue[iNum] > 0 && arrDeviceValue[iNum + 1] <= 0)
{
DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1])) + Convert.ToInt16(arrdata[iNum]);
}
else if (arrDeviceValue[iNum] < 0 && arrDeviceValue[iNum + 1] >= 0)
{
DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1])) + 65536 + Convert.ToInt16(arrdata[iNum]);
}
else
{
DataValue[iNum / 2] = 65536 * (Convert.ToInt16(arrdata[iNum + 1])) + Convert.ToInt16(arrdata[iNum]);
}
}
}
}
}
else
{
MessageBox.Show("参数有误!");
return;
}
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/********************************************************
* 功能:写入PLC寄存器中的值
* Address:起始地址,如D0
* Datasize:寄存器大小 16位/32位
* Data:写入PLC的数据
*********************************************************/
private void Write_PLC_DRegister(string Address, int Datasize, string[] Data)
{
try
{
int iReturnCode;
short[] arrDeviceValue = null;
String[] arrdata = null;
int flagData;
int iNum;
if (Datasize == 16 || Datasize == 32)
{
if (Datasize == 16)
{
arrDeviceValue = new short[Data.Count()];
arrdata = new String[Data.Count()];
for (iNum = 0; iNum < Data.Count(); iNum++)
{
arrDeviceValue[iNum] = Convert.ToInt16(Convert.ToInt32(Data[iNum]).ToString());
iReturnCode = axActUtlType1.WriteDeviceBlock2(Address, Data.Count(), ref arrDeviceValue[0]);
}
}
else
{
arrDeviceValue = new short[2 * Data.Count()];
arrdata = new String[2 * Data.Count()];
for (iNum = 0; iNum < Data.Count(); iNum++)
{
arrDeviceValue[2 * iNum + 1] = Convert.ToInt16((Convert.ToInt32(Data[2 * iNum]) / 65535 - 1).ToString());
flagData = Convert.ToInt32((Convert.ToInt32(Data[iNum]) - arrDeviceValue[2 * iNum + 1] * 65535).ToString());
if (flagData % 65535 == 0)
{
arrDeviceValue[2 * iNum + 1] = Convert.ToInt16(arrDeviceValue[2 * iNum + 1] + 1);
}
else if (flagData > 32767)
{
arrDeviceValue[2 * iNum] = Convert.ToInt16(-65535 + flagData);
}
else
{
arrDeviceValue[2 * iNum] = Convert.ToInt16(flagData);
}
}
iReturnCode = axActUtlType1.WriteDeviceBlock2(Address, 2 * Data.Count(), ref arrDeviceValue[0]);
}
}
else
{
MessageBox.Show("输入参数有误,重新输入!");
return;
}
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}