| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- ///**********************************************************
- ///RJCP.IO.Ports 可以跨平台,同样System.Ports也同样可以使用
- ///**********************************************************
- using System;
- using RJCP.IO.Ports;
- using System.Threading;
- using SHJX.Service.Common.Logging;
- using Microsoft.Extensions.Logging;
- namespace SHJX.Service.ServerClient.RS485
- {
- public static class Rs485Client
- {
- private static readonly ILogger logger = LogFactory.BuildLogger(typeof(Rs485Client));
- /// <summary>
- /// RS485通信对象
- /// </summary>
- public static SerialPortStream Sport { 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 SerialPortStream
- {
- BaudRate = 9600,
- DataBits = 8,
- StopBits = StopBits.One,
- Parity = Parity.None
- };
- 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()
- {
- //var open = Sport.IsOpen;
- if (!Sport.IsOpen) return;
- Sport.Close();
- //Sport.Dispose();
- }
- /// <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());
- }
- }
- }
- }
- /// <summary>
- /// 向端口发送指令,并等待回复。
- /// 以lastStr字符串作为回复的结尾识别字符,收到该字符串后返回。
- /// 失败时,返回string.Empty
- /// </summary>
- /// <param name="cmdStr">指令</param>
- /// <param name="lastStr"></param>
- /// <returns>收到的回复数据,含结尾识别字符串</returns>
- public static string SendData(string cmdStr, string lastStr)
- {
- if (Sport.IsOpen == 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(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());
- }
- }
- }
- }
- }
- }
|