| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- 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));
- /// <summary>
- /// RS485通信对象
- /// </summary>
- /// 选用RJCP.IO.Ports 而不是微软自带的,整体框架基于core,怕会出现跨平台的可能
- public static SerialPort Sport { get; set; }
- public static IModbusMaster Master { get; set; }
- /// <summary>
- /// 发送命令时锁定
- /// </summary>
- private static readonly object SnedLocker = new();
- /// <summary>
- /// 延时等待的单位间隔,默认20ms
- /// </summary>
- private static int DelayUnit { get; set; }
- /// <summary>
- /// 超时时长,默认1000ms
- /// </summary>
- private static int Timeout { get; set; }
- /// <summary>
- /// 端口状态:
- /// True=打开,False=关闭
- /// </summary>
- public static bool IsValid => Sport is not null && Sport.IsOpen;
- /// <summary>
- /// 初始化
- /// </summary>
- 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;
- }
- /// <summary>
- /// 打开COM通信端口,使用指定参数
- /// </summary>
- /// <param name="portName">端口号</param>
- /// <returns>是否正常打开</returns>
- 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;
- }
- }
- /// <summary>
- /// 关闭COM通信端口
- /// </summary>
- /// <returns>true=已关闭,false=未关闭</returns>
- public static void Close()
- {
- if (!Sport.IsOpen)
- {
- return;
- }
- Sport.Close();
- Sport.Dispose();
- }
- #region
- /// <summary>
- /// 向端口发送指令,并等待回复。
- /// 以lastChar字符作为回复的结尾识别字符,收到该字符后返回。
- /// 失败时,返回string.Empty
- /// </summary>
- /// <param name="cmdStr">指令</param>
- /// <param name="lastChar">结尾识别字符</param>
- /// <returns>完整的应答数据,含结尾识别字符</returns>
- 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
- /// <summary>
- /// 向端口发送指令,并等待回复。
- /// 以lastStr字符串作为回复的结尾识别字符,收到该字符串后返回。
- /// 失败时,返回string.Empty
- /// </summary>
- /// <param name="cmdStr">指令</param>
- /// <param name="lastStr"></param>
- /// <returns>收到的回复数据,含结尾识别字符串</returns>
- 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());
- }
- }
- }
- /// <summary>
- /// 向端口发送指令,并等待回复。
- /// 以lastStr字符串作为回复的结尾识别字符,收到该字符串后返回。
- /// 失败时,返回string.Empty
- /// </summary>
- /// <param name="cmdStr">指令</param>
- /// <param name="lastStr"></param>
- /// <returns>收到的回复数据,含结尾识别字符串</returns>
- //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++ };
- }
- }
- }
- }
|