using Modbus.Device;
using System.IO.Ports;
///**********************************************************
///System.Ports 可以使用
///RJCP.IO.Ports 可以使用
///**********************************************************
namespace SHJX.Service.PortClient.OptionClient.RS485
{
public static class Rs485Client
{
private static readonly ILogger logger = LogFactory.BuildLogger(typeof(Rs485Client));
///
/// RS485通信对象
///
/// 选用RJCP.IO.Ports 而不是微软自带的,整体框架基于core,怕会出现跨平台的可能
public static SerialPort Sport { get; set; }
public static IModbusMaster Master { get; set; }
///
/// 发送命令时锁定
///
private static readonly object SnedLocker = new();
///
/// 延时等待的单位间隔,默认20ms
///
private static int DelayUnit { get; set; }
///
/// 超时时长,默认1000ms
///
private static int Timeout { get; set; }
///
/// 端口状态:
/// True=打开,False=关闭
///
public static bool IsValid => Sport is not null && Sport.IsOpen;
///
/// 初始化
///
public static void InitPort()
{
// 创建COM通信对象
Sport ??= new SerialPort
{
BaudRate = 9600,
DataBits = 8,
StopBits = StopBits.One,
Parity = Parity.None
};
Master = ModbusSerialMaster.CreateRtu(Sport);
DelayUnit = 10;
Timeout = 1000;
}
///
/// 打开COM通信端口,使用指定参数
///
/// 端口号
/// 是否正常打开
public static bool Open(string portName)
{
try
{
lock (SnedLocker)
{
if (Sport.IsOpen) Sport.Close();
Sport.PortName = portName;
try
{
Sport.Open();
}
catch (Exception ex)
{
logger.LogError(ex.Message);
}
}
return Sport.IsOpen;
}
catch (UnauthorizedAccessException exIo)
{
logger.LogError(exIo.ToString());
return false;
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
return false;
}
}
///
/// 关闭COM通信端口
///
/// true=已关闭,false=未关闭
public static void Close()
{
if (!Sport.IsOpen)
{
return;
}
Sport.Close();
Sport.Dispose();
}
#region
///
/// 向端口发送指令,并等待回复。
/// 以lastChar字符作为回复的结尾识别字符,收到该字符后返回。
/// 失败时,返回string.Empty
///
/// 指令
/// 结尾识别字符
/// 完整的应答数据,含结尾识别字符
public static string SendData(string cmdStr, char lastChar)
{
if (Sport.IsOpen.Equals(false)) return string.Empty;
lock (SnedLocker)
{
for (; ; )
{
try
{
var strRes = string.Empty;
Sport.DiscardInBuffer();
Sport.DiscardOutBuffer();
Sport.Write(cmdStr);// 发送指令
// 等待回复
for (var i = 0; i < Timeout / DelayUnit; i++)
{
// 判断数据是否接收完整
if (Sport.BytesToRead > 0)
strRes += Sport.ReadExisting();
if (strRes.IndexOf(lastChar) != -1)
break;
Thread.Sleep(DelayUnit);
}
if (strRes.Length.Equals(0))
{
strRes = string.Empty;
}
return strRes;
}
catch (UnauthorizedAccessException exIo)
{
logger.LogError(exIo.ToString());
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
}
}
}
#endregion
///
/// 向端口发送指令,并等待回复。
/// 以lastStr字符串作为回复的结尾识别字符,收到该字符串后返回。
/// 失败时,返回string.Empty
///
/// 指令
///
/// 收到的回复数据,含结尾识别字符串
public static string SendData(string cmdStr, string lastStr)
{
using TaskMutexUtil mutex = new("comm"); //lock (SnedLocker)
if (Sport.IsOpen == false)
{
return string.Empty;
}
for (; ; )
{
try
{
var strRes = string.Empty;
Sport.DiscardInBuffer();
Sport.DiscardOutBuffer();
Sport.Write(cmdStr);// 发送指令
// 等待回复
for (var i = 0; i < Timeout / DelayUnit; i++)
{
// 判断数据是否接收完整
if (Sport.BytesToRead > 0)
{
strRes += Sport.ReadExisting();
}
if (strRes.IndexOf(lastStr, StringComparison.Ordinal) > 0)
{
break;
}
Thread.Sleep(DelayUnit);
}
if (strRes.Length == 0)
{
strRes = string.Empty;
}
return strRes;
}
catch (UnauthorizedAccessException exIo)
{
logger.LogError(exIo.ToString());
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
}
}
///
/// 向端口发送指令,并等待回复。
/// 以lastStr字符串作为回复的结尾识别字符,收到该字符串后返回。
/// 失败时,返回string.Empty
///
/// 指令
///
/// 收到的回复数据,含结尾识别字符串
//public static string SendDataByte(byte[] cmdStr)
//{
// using TaskMutexUtil mutex = new("comm"); //lock (SnedLocker)
// if (Sport.IsOpen == false)
// {
// return string.Empty;
// }
// for (; ; )
// {
// try
// {
// var strRes = string.Empty;
// Sport.DiscardInBuffer();
// Sport.DiscardOutBuffer();
// Sport.Write(cmdStr,0,8);// 发送指令
// // 等待回复
// for (var i = 0; i < Timeout / DelayUnit; i++)
// {
// // 判断数据是否接收完整
// if (Sport.BytesToRead > 0)
// {
// strRes += Sport.ReadExisting();
// }
// if (strRes.IndexOf(lastStr, StringComparison.Ordinal) > 0)
// {
// break;
// }
// Thread.Sleep(DelayUnit);
// }
// if (strRes.Length == 0)
// {
// strRes = string.Empty;
// }
// return strRes;
// }
// catch (UnauthorizedAccessException exIo)
// {
// logger.LogError(exIo.ToString());
// }
// catch (Exception ex)
// {
// logger.LogError(ex.ToString());
// }
// }
//}
private static ushort temp = 100;
private static ushort hli = 200;
public static object HumitureRead()
{
using TaskMutexUtil mutex = new("comm"); //lock (SnedLocker)
if (!Sport.IsOpen)
{
return null;
}
try
{
byte slaveAddress = byte.Parse("8");//站号
ushort temperatureStartAddress = ushort.Parse("1");
ushort numberOfPoints = ushort.Parse("2");
ushort[] registerBuffer = Master.ReadInputRegisters(slaveAddress, temperatureStartAddress, numberOfPoints);
return registerBuffer;
}
catch
{
return new ushort[] { temp++, hli++ };
}
}
}
}