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.

165 lines
4.4 KiB

7 months ago
using System.Collections;
using HslCommunication;
using HslCommunication.ModBus;
using HybirdFrameworkCore.Utils;
using log4net;
namespace HybirdFrameworkDriver.ModbusTcpMaster;
7 months ago
public abstract class ModbusTcpMaster
{
private static readonly ILog Log = LogManager.GetLogger(typeof(ModbusTcpMaster));
7 months ago
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;
private bool StopFlag { get; set; } = false;
public Action? Action { get; set; }
private ModbusTcpNet ModbusTcpNet;
ILog GetLog()
{
return Log;
}
public bool Connect()
{
7 months ago
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;
}
7 months ago
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
{
Action?.Invoke();
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 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;
}
}