Files

237 lines
6.1 KiB
C#
Raw Permalink Normal View History

2026-04-30 11:34:41 +08:00

using S7.Net;
using S7.Net.Types;
using SamplePre.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace SamplePre.Communication
{
public class S7PlcCommunicator : ICommunication, IDisposable
{
public Plc _plc;
private readonly string _ipAddress;
private readonly int _rack;
private readonly int _slot;
private readonly CpuType _cpuType;
/// <summary>
/// 是否连接
/// </summary>
private bool _isConnected = false;
/// <summary>
/// 是否连接
/// </summary>
public bool IsConnected
{
get => _isConnected;
set
{
if (_isConnected != value)
{
_isConnected = value;
ConnectionStatusChanged?.Invoke(value);
}
}
}
/// <summary>
/// 连接状态变化事件
/// </summary>
public event Action<bool> ConnectionStatusChanged;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="cpuType">PLC型号</param>
/// <param name="ipAddress">IP地址</param>
/// <param name="rack">机架号</param>
/// <param name="slot">插槽号</param>
public S7PlcCommunicator(CpuType cpuType, string ipAddress, int rack = 0, int slot = 1)
{
_cpuType = cpuType;
_ipAddress = ipAddress;
_rack = rack;
_slot = slot;
_plc = new Plc(cpuType, ipAddress, (short)rack, (short)slot);
}
/// <summary>
/// 连接PLC
/// </summary>
/// <returns>是否连接成功</returns>
public bool Connect()
{
try
{
if (IsConnected)
{
LoggerHelper.Logger.Info("已经处于连接状态!");
return true;
}
// 如果之前的连接对象已释放,创建新的
if (_plc == null)
{
_plc = new Plc(_cpuType, _ipAddress, (short)_rack, (short)_slot);
}
_plc.Open();
bool connected = _plc.IsConnected;
LoggerHelper.Logger.Info(connected ? "PLC连接成功" : "PLC连接失败");
IsConnected = connected;
return connected;
}
catch (Exception ex)
{
LoggerHelper.Logger.Info($"连接PLC失败: {ex.Message}");
IsConnected = false;
return false;
}
}
/// <summary>
/// 断开连接
/// </summary>
public void Disconnect()
{
try
{
if (IsConnected)
{
_plc.Close();
IsConnected = false;
LoggerHelper.Logger.Info("PLC连接已断开");
}
}
catch (Exception ex)
{
LoggerHelper.Logger.Info($"断开PLC连接失败: {ex.Message}");
}
}
/// <summary>
/// 写入数组数据
/// </summary>
/// <param name="Dbno"></param>
/// <param name="start"></param>
/// <param name="bytes"></param>
/// <returns></returns>
public bool WriteArraysBtye<T>(int Dbno, int start, T[] bytes)
{
try
{
if (!IsConnected && !Connect())
{
return false;
}
byte[] data = bytes.Cast<byte>().ToArray();
_plc.WriteBytes(DataType.DataBlock, Dbno, start, data);
return true;
}
catch (Exception ex)
{
LoggerHelper.Logger.Info($"写入数组失败: {ex.Message}");
return false;
}
}
/// <summary>
/// 读取数组
/// </summary>
/// <returns></returns>
public ushort[] ReadArraysShort(int Dbno,int start,int lenth)
{
try
{
if (!IsConnected && !Connect())
{
return null;
}
//public object? Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount, byte bitAdr = 0)
ushort[] datas = _plc.Read(DataType.DataBlock, Dbno, start, VarType.Word, lenth) as ushort[];
return datas;
}
catch (Exception ex)
{
LoggerHelper.Logger.Info($"读取数组失败: {ex.Message}");
return null;
}
}
/// <summary>
/// 写入数据
/// </summary>
/// <param name="address">地址(如"M0.0", "DB1.DBW2"</param>
/// <param name="value">要写入的值</param>
/// <returns>是否写入成功</returns>
public bool WriteSingleData(string address, object value)
{
try
{
if (!IsConnected && !Connect())
{
return false;
}
_plc.Write(address, value);
Console.WriteLine($"写入 {address} 成功: {value}");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"写入 {address} 失败: {ex.Message}");
return false;
}
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
// 释放托管资源
Disconnect();
//_plc?.Dispose();
_plc = null;
}
~S7PlcCommunicator()
{
Dispose();
}
}
}