2026-04-30 11:34:41 +08:00
|
|
|
|
using Modbus.Device;
|
|
|
|
|
|
using S7.Net;
|
|
|
|
|
|
using SamplePre.Common;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
namespace SamplePre.Communication.Communication
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2026-05-09 17:49:46 +08:00
|
|
|
|
public class ModbusTcpCommunicator : CommunicationBase, IDisposable
|
2026-04-30 11:34:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
IModbusMaster _modbusMaster = null;
|
|
|
|
|
|
TcpClient _tcpClient = null;
|
|
|
|
|
|
private readonly string _ipAddress;
|
|
|
|
|
|
private readonly int _port;
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-05-09 17:49:46 +08:00
|
|
|
|
|
2026-04-30 11:34:41 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构造函数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ipAddress">IP地址</param>
|
|
|
|
|
|
/// <param name="port">端口号</param>
|
|
|
|
|
|
public ModbusTcpCommunicator(string ipAddress, int port=502)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
_ipAddress = ipAddress;
|
|
|
|
|
|
_port = port;
|
|
|
|
|
|
|
|
|
|
|
|
_tcpClient = new TcpClient(ipAddress, port);//Modbus主设备
|
|
|
|
|
|
|
|
|
|
|
|
_modbusMaster = ModbusIpMaster.CreateIp(_tcpClient);
|
|
|
|
|
|
_modbusMaster.Transport.ReadTimeout = 2000;
|
|
|
|
|
|
_modbusMaster.Transport.Retries = 3;
|
|
|
|
|
|
|
|
|
|
|
|
IsConnected = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
LoggerHelper.Logger.Error("初始化ModbusTcpCommunicator失败!" + ex.Message);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 连接PLC
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>是否连接成功</returns>
|
|
|
|
|
|
public bool Connect()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsConnected)
|
|
|
|
|
|
{
|
|
|
|
|
|
LoggerHelper.Logger.Info("已经处于连接状态!");
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果之前的连接对象已释放,创建新的
|
|
|
|
|
|
if (_modbusMaster == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_tcpClient = new TcpClient(_ipAddress, _port);//Modbus主设备
|
|
|
|
|
|
|
|
|
|
|
|
_modbusMaster = ModbusIpMaster.CreateIp(_tcpClient);
|
|
|
|
|
|
_modbusMaster.Transport.ReadTimeout = 2000; //
|
|
|
|
|
|
_modbusMaster.Transport.Retries = 3;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LoggerHelper.Logger.Info("PLC连接成功");
|
|
|
|
|
|
IsConnected = true;
|
|
|
|
|
|
|
|
|
|
|
|
return IsConnected;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
LoggerHelper.Logger.Info($"连接PLC失败: {ex.Message}");
|
|
|
|
|
|
IsConnected = false;
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 断开连接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Disconnect()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (IsConnected)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
_modbusMaster.Dispose();
|
|
|
|
|
|
_tcpClient.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>
|
2026-05-09 17:49:46 +08:00
|
|
|
|
public override bool WriteArraysBtye<T>(int Dbno, int start, T[] data)
|
2026-04-30 11:34:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!IsConnected && !Connect())
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] ushorts = data.Cast<ushort>().ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
_modbusMaster.WriteMultipleRegisters((byte)Dbno, (ushort)start, ushorts);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
LoggerHelper.Logger.Info($"写入数组失败: {ex.Message}");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 读取数组
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
2026-05-09 17:49:46 +08:00
|
|
|
|
public override ushort[] ReadArraysShort(int Dbno, int start, int lenth)
|
2026-04-30 11:34:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//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;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 释放资源
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 释放托管资源
|
|
|
|
|
|
Disconnect();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-09 17:49:46 +08:00
|
|
|
|
public override bool WriteSingleData(string address, object value)
|
2026-04-30 11:34:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
~ModbusTcpCommunicator()
|
|
|
|
|
|
{
|
|
|
|
|
|
Dispose();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|