三菱FX3U系列PLC网络通信(MC1E帧),封装方法如下:
1.方法一
public class SvMitsubishiMC1E
{
private SvSocketClient Client;
string fbt = "01";//"00";未读//"01"批量读
string plchao = "FF";
string time = "0A00";//L_H
string start = "";
string A_dress = "";
string count = "";
string r_or_w = "";
public override void Initial()
{
base.Initial();
Client = new SvSocketClient(Host, "PLC");
Client.Initial();
}
public override void Close()
{
Client.Close();
}
public override void ReadBlock16(string startAddress, ref short[] addressValues)
{
var addrType = startAddress.Substring(0, 1);
var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));
fbt = "01";
start = startAddr.ToString("X8");
start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
count = addressValues.Length.ToString("X2");
r_or_w = "00";
string str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);
byte[] OML = new byte[str.Length / 2];
for (int I = 0; I < OML.Length; I++)
{
OML[I] = Convert.ToByte(str.Substring(2 * I, 2), 16);
}
// 發送數據
var recByte = Client.SendData(OML);
// 數據解析
//for (int i = 0; i < addressValues.Length; i++)
//{
// addressValues[i] = BitConverter.ToInt16(recByte, 11 + i * 2);
//}
for (int i = 0; i < addressValues.Length; i++)
{
string SS = recByte[2 * i + 3].ToString("x2").ToUpper();
string FDDS = recByte[2 * i + 2].ToString("x2").ToUpper();
addressValues[i] = Convert.ToInt16(recByte[2 * i + 3].ToString("x2").ToUpper() + recByte[2 * i + 2].ToString("x2").ToUpper(), 16);
}
}
public override void WriteBlock16(string startAddress, short[] addressValues)
{
var addrType = startAddress.Substring(0, 1);
var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));
byte[] bu_write = new byte[addressValues.Length * 2];
for (int i = 0; i < addressValues.Length; i++)
{
bu_write[i * 2] = Convert.ToByte(addressValues[i].ToString("X4").Substring(2, 2), 16);
bu_write[2 * i + 1] = Convert.ToByte(addressValues[i].ToString("X4").Substring(0, 2), 16);
}
fbt = "03";
start = startAddr.ToString("X8");
start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
count = addressValues.Length.ToString("X2");
r_or_w = "00";
string str = "";
str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);
byte[] buffer = new byte[str.Length / 2 + addressValues.Length * 2];// NEWSystem.Text.Encoding.ASCII.GetBytes(str);
for (int i = 0; i < str.Length / 2 + addressValues.Length * 2; i++)
{
if (i < str.Length / 2)
{
buffer[i] = (byte)Convert.ToByte(str.Substring(i * 2, 2), 16);
}
else
{
buffer[i] = Convert.ToByte(addressValues[(i - str.Length / 2) / 2].ToString("X4").Substring(2, 2), 16);
i++;
buffer[i] = Convert.ToByte(addressValues[(i - 1 - str.Length / 2) / 2].ToString("X4").Substring(0, 2), 16);
}
}
string[] ASD = new string[buffer.Length];
for (int I = 0; I < ASD.Length; I++)
{
ASD[I] = buffer[I].ToString("X2");
}
// 發送數據
var recByte = Client.SendData(buffer);
}
private int GetAddrTypeByte(string addrType)
{
switch (addrType)
{
case "D": return 17440;
case "M": return 19744;
case "R": return 21024;
case "SM": return 145;
default: return 145;
}
}
}
2.方法二
public class SvMitsubishiMC1E
{
private Socket Client;
private string Host;
string fbt = "01";//"00";未读//"01"批量读
string plchao = "FF";
string time = "0A00";//L_H
string start = "";
string A_dress = "";
string count = "";
string r_or_w = "";
public SvMitsubishiMC1E(string host)
{
Host = host;
}
public void Initial()
{
try
{
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Client.SendTimeout = 10000;
Client.ReceiveTimeout = 10000;
Client.Connect(ConvertIP(Host));
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(Name + "建立連接" + Host + "失敗", ex);
}
}
public void Close()
{
try
{
Client.Close();
}
catch (Exception ex)
{
// SvMaster.Log.WriteError(Name + "關閉連接" + Host + "失敗", ex);
}
}
public void ReadBlock16(string startAddress, ref short[] addressValues)
{
var addrType = startAddress.Substring(0, 1);
var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));
fbt = "01";
start = startAddr.ToString("X8");
start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
count = addressValues.Length.ToString("X2");
r_or_w = "00";
string str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);
byte[] OML = new byte[str.Length / 2];
for (int I = 0; I < OML.Length; I++)
{
OML[I] = Convert.ToByte(str.Substring(2 * I, 2), 16);
}
// 發送數據
var recByte = SendData(OML);
// 數據解析
//for (int i = 0; i < addressValues.Length; i++)
//{
// addressValues[i] = BitConverter.ToInt16(recByte, 11 + i * 2);
//}
for (int i = 0; i < addressValues.Length; i++)
{
string SS = recByte[2 * i + 3].ToString("x2").ToUpper();
string FDDS = recByte[2 * i + 2].ToString("x2").ToUpper();
addressValues[i] = Convert.ToInt16(recByte[2 * i + 3].ToString("x2").ToUpper() + recByte[2 * i + 2].ToString("x2").ToUpper(), 16);
}
}
public void WriteBlock16(string startAddress, short[] addressValues)
{
var addrType = startAddress.Substring(0, 1);
var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));
byte[] bu_write = new byte[addressValues.Length * 2];
for (int i = 0; i < addressValues.Length; i++)
{
bu_write[i * 2] = Convert.ToByte(addressValues[i].ToString("X4").Substring(2, 2), 16);
bu_write[2 * i + 1] = Convert.ToByte(addressValues[i].ToString("X4").Substring(0, 2), 16);
}
fbt = "03";
start = startAddr.ToString("X8");
start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
count = addressValues.Length.ToString("X2");
r_or_w = "00";
string str = "";
str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);
byte[] buffer = new byte[str.Length / 2 + addressValues.Length * 2];// NEWSystem.Text.Encoding.ASCII.GetBytes(str);
for (int i = 0; i < str.Length / 2 + addressValues.Length * 2; i++)
{
if (i < str.Length / 2)
{
buffer[i] = (byte)Convert.ToByte(str.Substring(i * 2, 2), 16);
}
else
{
buffer[i] = Convert.ToByte(addressValues[(i - str.Length / 2) / 2].ToString("X4").Substring(2, 2), 16);
i++;
buffer[i] = Convert.ToByte(addressValues[(i - 1 - str.Length / 2) / 2].ToString("X4").Substring(0, 2), 16);
}
}
string[] ASD = new string[buffer.Length];
for (int I = 0; I < ASD.Length; I++)
{
ASD[I] = buffer[I].ToString("X2");
}
// 發送數據
var recByte = SendData(buffer);
}
private int GetAddrTypeByte(string addrType)
{
switch (addrType)
{
case "D": return 17440;
case "M": return 19744;
case "R": return 21024;
case "SM": return 145;
default: return 145;
}
}
public byte[] SendData(byte[] data)
{
var recByte = new byte[8192];
lock (Client)
{
try
{
ReConnection();
if (Client.Available > 0)
{
var buffer = new byte[8192];
Client.Receive(buffer);
}
Client.Send(data);
if (WaitTask(() => Client.Available > 0, 5) == true)
{
Client.Receive(recByte);
}
else
{
//SvMaster.Log.WriteError("未接收到" + Name + Host + "的資料回傳");
}
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(ex);
}
return recByte;
}
}
public string SendData(string data)
{
var recByte = new byte[8192];
lock (Client)
{
try
{
ReConnection();
if (Client.Available > 0)
{
var buffer = new byte[8192];
Client.Receive(buffer);
}
Client.Send(Encoding.ASCII.GetBytes(data));
if (WaitTask(() => Client.Available > 0, 5) == true)
{
Client.Receive(recByte);
}
else
{
//SvMaster.Log.WriteError("未接收到" + Name + Host + "的資料回傳");
}
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(ex);
}
return Encoding.ASCII.GetString(recByte).Trim('\0');
}
}
private void ReConnection()
{
try
{
if (Client.Connected == false)
{
Client.Close();
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Client.SendTimeout = 5000;
Client.ReceiveTimeout = 5000;
Client.Connect(ConvertIP(Host));
}
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(Name + "重新連接" + Host + "失敗", ex);
}
}
public static IPEndPoint ConvertIP(string host)
{
try
{
var ip = host.Split(':')[0];
var port = host.Split(':')[1];
return new IPEndPoint(IPAddress.Parse(ip), Convert.ToInt32(port));
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(ex);
return null;
}
}
public static bool WaitTask(Func<bool> task, double timeOutSeconds)
{
var startTime = DateTime.Now;
while (true)
{
try
{
if (DateTime.Now.Subtract(startTime).TotalSeconds > timeOutSeconds)
{
return false;
}
else
{
Thread.Sleep(10);
}
if (task.Invoke() == true)
{
return true;
}
}
catch (Exception)
{
return false;
}
}
}
}
3.方法三
public class SvMitsubishiMC1E
{
private Socket Client;
private string Host;
string fbt = "01";//"00";未读//"01"批量读
string plchao = "FF";
string time = "0A00";//L_H
string start = "";
string A_dress = "";
string count = "";
string r_or_w = "";
//public SvMitsubishiMC1E(string host)
//{
// Host = host;
//}
//public void Initial()
//{
// try
// {
// Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Client.SendTimeout = 10000;
// Client.ReceiveTimeout = 10000;
// Client.Connect(ConvertIP(Host));
// }
// catch (Exception ex)
// {
// //SvMaster.Log.WriteError(Name + "建立連接" + Host + "失敗", ex);
// }
//}
public bool Connect(string ServerIP, int ServerProt)//首先使用时需要判断是否已经进行plc的连接
{
Host = "" + ServerIP + ":" + ServerProt + "";
try
{
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Client.SendTimeout = 10000;
Client.ReceiveTimeout = 10000;
Client.Connect(ConvertIP(Host));
return true;
}
catch (Exception ex)
{
return false;
}
}
public void Close()
{
try
{
Client.Close();
}
catch (Exception ex)
{
// SvMaster.Log.WriteError(Name + "關閉連接" + Host + "失敗", ex);
}
}
public void ReadBlock16(string startAddress, ref short[] addressValues)
{
var addrType = startAddress.Substring(0, 1);
var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));
fbt = "01";
start = startAddr.ToString("X8");
start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
count = addressValues.Length.ToString("X2");
r_or_w = "00";
string str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);
byte[] OML = new byte[str.Length / 2];
for (int I = 0; I < OML.Length; I++)
{
OML[I] = Convert.ToByte(str.Substring(2 * I, 2), 16);
}
// 發送數據
var recByte = SendData(OML);
// 數據解析
//for (int i = 0; i < addressValues.Length; i++)
//{
// addressValues[i] = BitConverter.ToInt16(recByte, 11 + i * 2);
//}
for (int i = 0; i < addressValues.Length; i++)
{
string SS = recByte[2 * i + 3].ToString("x2").ToUpper();
string FDDS = recByte[2 * i + 2].ToString("x2").ToUpper();
addressValues[i] = Convert.ToInt16(recByte[2 * i + 3].ToString("x2").ToUpper() + recByte[2 * i + 2].ToString("x2").ToUpper(), 16);
}
}
public void WriteBlock16(string startAddress, short[] addressValues)
{
var addrType = startAddress.Substring(0, 1);
var startAddr = Convert.ToInt32(startAddress.Substring(1, startAddress.Length - 1));
byte[] bu_write = new byte[addressValues.Length * 2];
for (int i = 0; i < addressValues.Length; i++)
{
bu_write[i * 2] = Convert.ToByte(addressValues[i].ToString("X4").Substring(2, 2), 16);
bu_write[2 * i + 1] = Convert.ToByte(addressValues[i].ToString("X4").Substring(0, 2), 16);
}
fbt = "03";
start = startAddr.ToString("X8");
start = start.Substring(6, 2) + start.Substring(4, 2) + start.Substring(2, 2) + start.Substring(0, 2);
A_dress = (GetAddrTypeByte(addrType)).ToString("X4");
A_dress = A_dress.Substring(2, 2) + A_dress.Substring(0, 2);
count = addressValues.Length.ToString("X2");
r_or_w = "00";
string str = "";
str = string.Format("{0}{1}{2}{3}{4}{5}{6}", fbt, plchao, time, start, A_dress, count, r_or_w);
byte[] buffer = new byte[str.Length / 2 + addressValues.Length * 2];// NEWSystem.Text.Encoding.ASCII.GetBytes(str);
for (int i = 0; i < str.Length / 2 + addressValues.Length * 2; i++)
{
if (i < str.Length / 2)
{
buffer[i] = (byte)Convert.ToByte(str.Substring(i * 2, 2), 16);
}
else
{
buffer[i] = Convert.ToByte(addressValues[(i - str.Length / 2) / 2].ToString("X4").Substring(2, 2), 16);
i++;
buffer[i] = Convert.ToByte(addressValues[(i - 1 - str.Length / 2) / 2].ToString("X4").Substring(0, 2), 16);
}
}
string[] ASD = new string[buffer.Length];
for (int I = 0; I < ASD.Length; I++)
{
ASD[I] = buffer[I].ToString("X2");
}
// 發送數據
var recByte = SendData(buffer);
}
private int GetAddrTypeByte(string addrType)
{
switch (addrType)
{
case "D": return 17440;
case "M": return 19744;
case "R": return 21024;
case "SM": return 145;
default: return 145;
}
}
public byte[] SendData(byte[] data)
{
var recByte = new byte[8192];
lock (Client)
{
try
{
ReConnection();
if (Client.Available > 0)
{
var buffer = new byte[8192];
Client.Receive(buffer);
}
Client.Send(data);
if (WaitTask(() => Client.Available > 0, 5) == true)
{
Client.Receive(recByte);
}
else
{
//SvMaster.Log.WriteError("未接收到" + Name + Host + "的資料回傳");
}
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(ex);
}
return recByte;
}
}
public string SendData(string data)
{
var recByte = new byte[8192];
lock (Client)
{
try
{
ReConnection();
if (Client.Available > 0)
{
var buffer = new byte[8192];
Client.Receive(buffer);
}
Client.Send(Encoding.ASCII.GetBytes(data));
if (WaitTask(() => Client.Available > 0, 5) == true)
{
Client.Receive(recByte);
}
else
{
//SvMaster.Log.WriteError("未接收到" + Name + Host + "的資料回傳");
}
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(ex);
}
return Encoding.ASCII.GetString(recByte).Trim('\0');
}
}
private void ReConnection()
{
try
{
if (Client.Connected == false)
{
Client.Close();
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Client.SendTimeout = 5000;
Client.ReceiveTimeout = 5000;
Client.Connect(ConvertIP(Host));
}
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(Name + "重新連接" + Host + "失敗", ex);
}
}
public static IPEndPoint ConvertIP(string host)
{
try
{
var ip = host.Split(':')[0];
var port = host.Split(':')[1];
return new IPEndPoint(IPAddress.Parse(ip), Convert.ToInt32(port));
}
catch (Exception ex)
{
//SvMaster.Log.WriteError(ex);
return null;
}
}
public static bool WaitTask(Func<bool> task, double timeOutSeconds)
{
var startTime = DateTime.Now;
while (true)
{
try
{
if (DateTime.Now.Subtract(startTime).TotalSeconds > timeOutSeconds)
{
return false;
}
else
{
Thread.Sleep(10);
}
if (task.Invoke() == true)
{
return true;
}
}
catch (Exception)
{
return false;
}
}
}
}
4.应用实例
4.1向PLC写时间(整数)
#region 三菱PLC--MC1E
SvMitsubishiMC1E plcsMC1E = new SvMitsubishiMC1E();
private void WriteTime1E(String IP, int Port)
{
DateTime currentTime = DateTime.Now; // 获取当前时间
DateTime minusOneMinute = currentTime.AddMinutes(-1); // 减去1分钟
y = minusOneMinute.Year;
mon = minusOneMinute.Month;
d = minusOneMinute.Day;
h = minusOneMinute.Hour;
min = minusOneMinute.Minute;
s = minusOneMinute.Second;
if (plcsMC1E.Connect(IP, Convert.ToInt16(Port.ToString().Trim())))
{
short[] READ = new short[10];
READ[0] = Convert.ToInt16(y.ToString().Trim());
READ[1] = Convert.ToInt16(mon.ToString().Trim());
READ[2] = Convert.ToInt16(d.ToString().Trim());
READ[3] = Convert.ToInt16(h.ToString().Trim());
READ[4] = Convert.ToInt16(min.ToString().Trim());
READ[5] = Convert.ToInt16(s.ToString().Trim());
READ[9] = 1;
plcsMC1E.WriteBlock16("D60", READ);
label1.Text = ReadSingle16("D70").ToString();
label2.Text = ReadSingle16("D71").ToString();
label3.Text = ReadSingle16("D72").ToString();
label4.Text = ReadSingle16("D73").ToString();
label5.Text = ReadSingle16("D74").ToString();
label6.Text = ReadSingle16("D75").ToString();
plcsMC1E.Close();
}
else
{
MessageBox.Show("連接失敗!");
}
}
public int ReadSingle16(string address)
{
try
{
var temp = new short[1];
plcsMC1E.ReadBlock16(address, ref temp);
return temp[0];
}
catch (Exception ex)
{
MessageBox.Show("读取失敗!");
return -999;
}
}
/// <summary>
/// 写入整数
/// </summary>
/// <param name="address"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool WriteSingle16(string address, int value)
{
try
{
var temp = new short[] { (short)value };
plcsMC1E.WriteBlock16(address, temp);
return true;
}
catch (Exception ex)
{
MessageBox.Show("写入失敗!");
return false;
}
}
#endregion
4.2向PLC写字符串
#region 三菱PLC--MC1E
SvMitsubishiMC1E plcsMC1E = new SvMitsubishiMC1E();
//读取PLC的线别(R32200三位)
private void ReadMachineLine1E(String IP, int Port)
{
if (plcsMC1E.Connect(IP, Convert.ToInt16(Port.ToString().Trim())))
{
label1.Text = ReadString1E("R32200", 3);
plcsMC1E.Close();
}
else
{
MessageBox.Show("連接失敗!");
}
}
//向PLC写入的线别(R32200三位)
private void WriteMachineLine1E(string IP, int Port)
{
string value = comboBox2.Text.Trim();
string input = "";
if (value.Length == 5)
{
input = value;
}
else if (value.Length < 5)
{
input = value.ToString().PadRight(6, ' ');
}
else
{
input = value.Substring(0, 6);
}
int aaa = input.Length;
if (plcsMC1E.Connect(IP, Port))
{
WriteStringMC1E("R32200", input);
}
plcsMC1E.Close();
MessageBox.Show("寫入成功!");
}
public int ReadSingle161E(string address)
{
try
{
var temp = new short[1];
plcsMC1E.ReadBlock16(address, ref temp);
return temp[0];
}
catch (Exception ex)
{
MessageBox.Show("读取失敗!");
return -999;
}
}
public string ReadString1E(string address, int length)
{
try
{
var temp = new short[length];
plcsMC1E.ReadBlock16(address, ref temp);
byte[] READ1 = new byte[2 * length];
//將數據轉換成machine名稱,
for (int i = 0; i < READ1.Length; i = i + 2)
{
string qw = temp[i / 2].ToString("X4");
READ1[i] = Convert.ToByte(qw.Substring(2, 2), 16);
READ1[i + 1] = Convert.ToByte(qw.Substring(0, 2), 16);
}
string aa = (Convert.ToString(System.Text.Encoding.ASCII.GetString(READ1))).Trim();
//var tempByte = temp.Select(x => BitConverter.GetBytes(x)[0]).ToArray();
//return Encoding.ASCII.GetString(tempByte).Trim('\0');
return aa;
}
catch (Exception ex)
{
MessageBox.Show("读取失敗!");
return "";
}
}
public bool WriteStringMC1E(string address, string value)//写入
{
try
{
byte[] tempByte = System.Text.Encoding.ASCII.GetBytes(value);
var temp = new short[tempByte.Length / 2];
for (int i = 0; i < temp.Length; i++)
{
temp[i] = BitConverter.ToInt16(tempByte, 2 * i);
}
plcsMC1E.WriteBlock16(address, temp);
return true;
}
catch (Exception ex)
{
return false;
}
}
#endregion
本文主要分享PLC网络通信连接方法,需要自行在程式中调用测试。该方法可以从PLC读写寄存器数据,测试可用。