You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
6.2 KiB
179 lines
6.2 KiB
using NModbus;
|
|
using System.Net.Sockets;
|
|
using VOL.Data.IServices.modbus;
|
|
using VOL.Core.Utils;
|
|
using VOL.Core.Extensions;
|
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
|
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
|
|
|
|
namespace VOL.Data.Services.modbus
|
|
{
|
|
public class ModbusTcpService : IModbusService
|
|
{
|
|
// IP
|
|
private string ip { set; get; } = "127.0.0.1";
|
|
|
|
// 端口
|
|
private int port { set; get; } = 502;
|
|
|
|
// 从站地址
|
|
private int slaveNo { set; get; } = 1;
|
|
|
|
private TcpClient client;
|
|
|
|
private IModbusMaster modbusMaster;
|
|
|
|
public ModbusTcpService(string ip, int port) {
|
|
this.ip = ip;
|
|
this.port = port;
|
|
this.client = new TcpClient(ip, port);
|
|
this.createModbusClient();
|
|
}
|
|
|
|
public void createModbusClient()
|
|
{
|
|
ModbusFactory modbusFactory = new();
|
|
modbusMaster = modbusFactory.CreateMaster(client);
|
|
modbusMaster.Transport.ReadTimeout = 3000; //读超时
|
|
modbusMaster.Transport.WriteTimeout = 3000;//写超时
|
|
modbusMaster.Transport.Retries = 3;
|
|
modbusMaster.Transport.WaitToRetryMilliseconds = 500;//尝试重复连接间隔
|
|
}
|
|
|
|
|
|
// 是否已连接
|
|
public bool isConnected
|
|
{
|
|
get => client.Connected;
|
|
}
|
|
|
|
|
|
// 写寄存器数据
|
|
public void writeData(byte slaveAddress, ushort startAddress, object data)
|
|
{
|
|
var type = data.GetType().Name.ToLower();
|
|
dynamic val ;
|
|
ushort[]? units; // 单元数
|
|
switch (type) {
|
|
case "int16":
|
|
val = data.ToShort();
|
|
units = new ushort[1];
|
|
DataConvertUtil.SetShort(units, 0, val);
|
|
break;
|
|
case "int32":
|
|
val = data.ToInt();
|
|
units = new ushort[2];
|
|
DataConvertUtil.SetInt(units, 0, val);
|
|
break;
|
|
case "single":
|
|
val = data.ToFloat();
|
|
units = new ushort[2];
|
|
DataConvertUtil.SetReal(units, 0, val);
|
|
break;
|
|
case "string":
|
|
val = data.ToString();
|
|
int length = (int) Math.Ceiling((double) val.Length / 2);
|
|
units = new ushort[length]; // 先不考虑中文字符,一个寄存器地址存放两个字符
|
|
DataConvertUtil.SetString(units, 0, val); // units 25690 25690
|
|
break;
|
|
default:
|
|
throw new ArgumentException("暂未实现写入此类型:"+ type);
|
|
}
|
|
if (units != null) {
|
|
this.WriteMultipleRegisters(slaveAddress, startAddress, units);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 读寄存器数据
|
|
public dynamic readData(byte slaveAddress, ushort startAddress, string type, int units = 1)
|
|
{
|
|
type = type.ToLower();
|
|
ushort[]? source;
|
|
dynamic? data = null;
|
|
switch (type)
|
|
{
|
|
case "int16":
|
|
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 1);
|
|
data = DataConvertUtil.GetShort(source, 0);
|
|
break;
|
|
case "int32":
|
|
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2);
|
|
data = DataConvertUtil.GetInt(source, 0);
|
|
break;
|
|
case "single":
|
|
source = this.ReadHoldingRegisters(slaveAddress, startAddress, 2);
|
|
data = DataConvertUtil.GetReal(source, 0);
|
|
break;
|
|
case "string":
|
|
//units = val.Length * 2; // 先不考虑中文字符
|
|
source = this.ReadHoldingRegisters(slaveAddress, startAddress, (ushort) units); // 25690 25690 0 0
|
|
data = DataConvertUtil.GetString(source, 0, units);
|
|
break;
|
|
default:
|
|
throw new ArgumentException("暂未实现读取此类型:" + type);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
|
|
|
|
// 读线圈 0x01 0x
|
|
public bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort num)
|
|
{
|
|
return modbusMaster.ReadCoils(slaveAddress, startAddress, num);
|
|
}
|
|
|
|
// 读离散输入 0x02 1x
|
|
public bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort num)
|
|
{
|
|
return modbusMaster.ReadInputs(slaveAddress, startAddress, num);
|
|
}
|
|
|
|
// 读保持寄存器 0x03 4x
|
|
public ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort num)
|
|
{
|
|
return modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, num);
|
|
}
|
|
|
|
// 读输入寄存器 0x04 3x
|
|
public ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort num)
|
|
{
|
|
return modbusMaster.ReadInputRegisters(slaveAddress, startAddress, num);
|
|
}
|
|
|
|
// 写单个线圈 0x05
|
|
public void WriteSingleCoil(byte slaveAddress, ushort startAddress, bool value)
|
|
{
|
|
modbusMaster.WriteSingleCoil(slaveAddress, startAddress, value);
|
|
}
|
|
|
|
|
|
// 写单个保持寄存器 0x06
|
|
public void WriteSingleRegister(byte slaveAddress, ushort startAddress, ushort value)
|
|
{
|
|
modbusMaster.WriteSingleRegister(slaveAddress, startAddress, value);
|
|
}
|
|
|
|
// 写多个线圈 0x0F
|
|
public void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] value)
|
|
{
|
|
modbusMaster.WriteMultipleCoils(slaveAddress, startAddress, value);
|
|
}
|
|
|
|
// 写多个保持寄存器 0x10
|
|
public void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] value)
|
|
{
|
|
modbusMaster.WriteMultipleRegisters(slaveAddress, startAddress, value);
|
|
}
|
|
|
|
|
|
// 关闭Socket
|
|
public void disConnent() {
|
|
client.Close();
|
|
modbusMaster.Dispose();
|
|
}
|
|
}
|
|
}
|