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++ }; } } } }