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.
178 lines
4.8 KiB
178 lines
4.8 KiB
using System.Collections;
|
|
using HslCommunication;
|
|
using HslCommunication.ModBus;
|
|
using HybirdFrameworkCore.Utils;
|
|
using log4net;
|
|
|
|
namespace HybirdFrameworkDriver.ModbusTcpMaster;
|
|
|
|
public class ModbusTcpMaster
|
|
{
|
|
private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusTcpMaster));
|
|
|
|
public string Ip { get; set; } = "127.0.0.1";
|
|
|
|
public int Port { get; set; } = 502;
|
|
|
|
public int Duration { get; set; } = 1000;
|
|
public bool Connected { get; set; } = false;
|
|
|
|
public delegate void MyReadAction(ModbusTcpMaster str);
|
|
|
|
public MyReadAction ReadAction { get; set; }
|
|
|
|
private bool StopFlag { get; set; } = false;
|
|
|
|
private ModbusTcpNet ModbusTcpNet;
|
|
|
|
|
|
ILog GetLog()
|
|
{
|
|
return Log;
|
|
}
|
|
|
|
public bool Connect()
|
|
{
|
|
GetLog().Info($"begin to connect {Ip}:{Port}");
|
|
|
|
try
|
|
{
|
|
if (ModbusTcpNet == null)
|
|
{
|
|
ModbusTcpNet = new ModbusTcpNet(Ip, Port);
|
|
OperateResult result = ModbusTcpNet.ConnectServer();
|
|
if (result.IsSuccess)
|
|
{
|
|
Connected = true;
|
|
GetLog().Info($"connect {Ip}:{Port} success");
|
|
StartListen();
|
|
}
|
|
else
|
|
{
|
|
GetLog().Info($"connect {Ip}:{Port} failed {result.Message}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
GetLog().Error($"connect {Ip}:{Port} exception {e.Message}");
|
|
}
|
|
|
|
return Connected;
|
|
}
|
|
|
|
public void StartListen()
|
|
{
|
|
StopListen();
|
|
StopFlag = false;
|
|
Thread readThread = new Thread(ReadFunc)
|
|
{
|
|
IsBackground = true,
|
|
Name = $"{Ip}:{Port}-reader-thread"
|
|
};
|
|
readThread.Start();
|
|
}
|
|
|
|
public void StopListen()
|
|
{
|
|
StopFlag = true;
|
|
Thread.Sleep(500);
|
|
}
|
|
|
|
private void ReadFunc()
|
|
{
|
|
while (!StopFlag)
|
|
{
|
|
try
|
|
{
|
|
ReadAction(this);
|
|
Thread.Sleep(Duration);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error(e);
|
|
}
|
|
}
|
|
|
|
GetLog().Info("stop listen");
|
|
}
|
|
|
|
public byte[]? ReadRegister(int registerNo, int start, int length)
|
|
{
|
|
start = start % 16 == 0 ? start / 16 : start / 16 + 1;
|
|
length = length % 8 == 0 ? length / 8 : length / 8 + 1;
|
|
OperateResult<byte[]> result = ModbusTcpNet.Read("x=3;" + (registerNo + start), (ushort)length);
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
return result.Content;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public byte[]? BatchRead(int registerNo, int length)
|
|
{
|
|
OperateResult<byte[]> result = ModbusTcpNet.Read("x=3;" + registerNo, (ushort)length);
|
|
if (result.IsSuccess)
|
|
{
|
|
return result.Content;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public bool WriteValue<T>(ModbusProperty<T> property)
|
|
{
|
|
T value = property.Value;
|
|
if (value == null)
|
|
{
|
|
GetLog().Warn($"write property{property.RegisterNo} null value");
|
|
return false;
|
|
}
|
|
|
|
bool result = false;
|
|
ModbusDataType dataType = property.Type;
|
|
int start = property.Start;
|
|
int length = property.Length;
|
|
byte[] setValue = BitUtls.Value2Bytes(value, property.Scale, property.Offset);
|
|
switch (dataType)
|
|
{
|
|
case ModbusDataType.Byte:
|
|
|
|
start = start % 2 == 0 ? start / 2 : start / 2 + 1;
|
|
ModbusTcpNet.Write("x=6;" + start, setValue);
|
|
break;
|
|
case ModbusDataType.Register:
|
|
ModbusTcpNet.Write("x=10;" + start, setValue);
|
|
break;
|
|
case ModbusDataType.Bit:
|
|
|
|
start = start % 16 == 0 ? start / 16 : start / 16 + 1;
|
|
length = length % 8 == 0 ? length / 8 : length / 8 + 1;
|
|
OperateResult<byte[]> readResult =
|
|
ModbusTcpNet.Read("x=3;" + (property.RegisterNo + start), (ushort)length);
|
|
|
|
if (readResult.IsSuccess)
|
|
{
|
|
byte[] bytes = readResult.Content;
|
|
BitArray bitArray = new BitArray(bytes);
|
|
int index = 0;
|
|
for (int i = property.Start % 16; i < property.Length; i++)
|
|
{
|
|
bitArray[i] = (setValue[index / 8] & (1 << (index % 8))) > 0;
|
|
index++;
|
|
}
|
|
|
|
bitArray.CopyTo(bytes, 0);
|
|
|
|
OperateResult write = ModbusTcpNet.Write("x=6;" + (property.RegisterNo + start), bytes);
|
|
result = write.IsSuccess;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
} |