LuJiaYi/PlcContorl.cs
2024-08-17 18:00:59 +08:00

359 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using HslCommunication;
using HslCommunication.Profinet.Melsec;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using static OpenCvSharp.FileStorage;
public class MelsecPLCTCPDriver
{
private MelsecMcNet melsecMc = new MelsecMcNet();
// private HslCommunication.ModBus.ModbusTcpNet melsecMc = new HslCommunication.ModBus.ModbusTcpNet();
//HslCommunication.Profinet.Melsec.MelsecMcServer melsecMc = new HslCommunication.Profinet.Melsec.MelsecMcServer();
#region PLCBase
public List<int> Read(string startAddress, int length)
{
PLCItem item = new PLCItem();
item.Address = startAddress;
item.ItemLength = length;
ReadItem(item);
//List<int> valueList = new List<int>();
//if (!string.IsNullOrWhiteSpace(item.ItemValue))
//{
// valueList = item.ItemValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList().ConvertAll(s => int.Parse(s)).ToList();
//}
return item.ItemValues;
}
public void ReadItem(PLCItem item)
{
// item.PLCOpType = PLCOpType.Read;
item.ItemValues.Clear();
try
{
// 读取Int变量
var result = melsecMc.ReadInt32("D" + item.Address, (ushort)item.ItemLength);
if (result.IsSuccess)
{
for (int i = 0; i < result.Content.Length; i++)
{
item.ItemValues.Add(result.Content[i]);
}
}
else
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + item.Address + ";长度:" + item.ItemLength + ";提示:" + result.Message);
}
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
}
}
public int ReadInt(string address)
{
try
{
// 读取Int变量
var result = melsecMc.ReadInt32("D" + address);
if (result.IsSuccess)
{
return result.Content;
}
else
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址:" + address + ";提示:" + result.Message);
return -1;
}
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}读取异常:" + ex.GetExceptionMessage());
return -1;
}
}
public void WriteItem(PLCItem item, bool waitForReply = true)
{
item.PLCOpType = PLCOpType.Write;
if (item.ItemValues == null || item.ItemValues.Count < 1)
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入值不能为空");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write(item.Address, item.ItemValues.First());
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
//LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} WriteItem{item.GetDisplayText()},写入 {item.ItemValues.First()}完成,耗时:{sw.ElapsedMilliseconds} ms");
}
/// <summary>
/// 写单独地址
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
public void WriteInt(string address, int writeValue, bool waitForReply = true)
{
if (string.IsNullOrEmpty(address))
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write("D" + address, writeValue);
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入 {writeValue} 完成,耗时:{sw.ElapsedMilliseconds} ms");
}
/// <summary>
/// 写单独地址 string值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
public void WriteString(string address, string writeValue, bool waitForReply = true)
{
if (string.IsNullOrEmpty(address) || string.IsNullOrEmpty(writeValue))
{
// LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write(address, writeValue);
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms");
}
/// <summary>
/// 写单独地址 float值
/// </summary>
/// <param name="address">地址</param>
/// <param name="writeValue"></param>
/// <param name="waitForReply"></param>
public void WriteFloat(string address, float writeValue, bool waitForReply = true)
{
if (string.IsNullOrEmpty(address))
{
//LogAsync(DateTime.Now, LogLevel.Error, $"{Name} 数据写入参数不能为空!");
return;
}
int repeatTime = 3;
Stopwatch sw = new Stopwatch();
do
{
try
{
var result = melsecMc.Write(address, writeValue);
if (result.IsSuccess)
{
repeatTime = 0;
}
}
catch (Exception ex)
{
if (repeatTime < 0)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}数据写入异常:{ex.GetExceptionMessage()}");
}
}
} while (repeatTime > 0);
sw.Stop();
// LogAsync(DateTime.Now, LogLevel.Assist, $"{Name} {address},写入{writeValue}完成,耗时:{sw.ElapsedMilliseconds} ms");
}
#endregion
#region DeviceBase
public void Start()
{
// IConfig.ip
melsecMc = new MelsecMcNet("192.168.3.39", 502);
// 如果网络不太理想,配置了两个端口,一个有问题,立即切换另一个的话,可以配置如下的代码
// melsecMc.GetPipeSocket().SetMultiPorts(new int[] { 6000, 6001 });
//melsecMc = new HslCommunication.ModBus.ModbusTcpNet();
//melsecMc.IpAddress = "192.168.3.39";
//melsecMc.Port = 502;
//melsecMc.ConnectTimeOut = 10000; // 连接超时,单位毫秒
//melsecMc.ReceiveTimeOut = 5000; // 接收超时,单位毫秒
//melsecMc.Station = 1;
//melsecMc.AddressStartWithZero = true;
//melsecMc.IsStringReverse = false;
//melsecMc.DataFormat = HslCommunication.Core.DataFormat.CDAB;
// melsecMc.ServerStart(6000);
// 连接对象
OperateResult connect = melsecMc.ConnectServer();
if (connect.IsSuccess)
{
Task.Run(() =>
{
HeartbeatMonitor();
});
}
else
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}已开启异常:{connect.Message}");
}
}
protected void Stop()
{
try
{
// 断开连接
// melsecMc.RemoteStop();
// OmronUDPNet.Stop();
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{Name}关闭异常:{ex.GetExceptionMessage()}");
}
}
#endregion
#region IMonitor
readonly byte[] scanBuffer = new byte[2048];
public List<int> GetMonitorValues(int startAddress, int length)
{
List<int> res = new List<int>();
// var result = melsecMc.ReadUInt16(startAddress.ToString(), (ushort)length);
// var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
var result = melsecMc.ReadInt32("D" + startAddress, (ushort)length);
if (result.IsSuccess)
{
res = new List<int>(result.Content);
}
else
{
//LogAsync(DateTime.Now, LogLevel.Error, $"{Name}未读取到数据:" + "地址W" + startAddress + ";长度:" + length + ";提示:" + result.Message);
}
return res;
}
#endregion
int HeartbeatCycle = 2;
string HeartbeatAddress = "D800";
bool CurrentState = false;
public event Action<int> Heartbeat;
public async void HeartbeatMonitor()
{
if (HeartbeatCycle <= 0)
{
return;
}
await Task.Run(async () =>
{
if (!string.IsNullOrEmpty(HeartbeatAddress)
&& HeartbeatCycle > 0)
{
while (CurrentState != false)
{
if (HeartbeatCycle <= 0)
{
return;
}
try
{
await Task.Delay(HeartbeatCycle * 1000);
var result = melsecMc.Write(HeartbeatAddress, 1);
if (!result.IsSuccess)
{
Heartbeat?.Invoke(1);
//LogAsync(DateTime.Now, LogLevel.Error, $"{this.Name} 心跳监听失败");
}
}
catch (Exception ex)
{
}
}
}
});
}
}