namespace LB_VisionProcesses.Communicators { public abstract class BaseCommunicator : ICommunicator { /// /// 子类名称 /// public string ClassName { get; set; } = string.Empty; /// /// 通讯名称 /// public string CommunicatorName { get; set; } = string.Empty; /// /// 通讯类名 /// public CommunicatorBrand CommunicatorBrand { get; set; } = CommunicatorBrand.UARTPort; /// /// 是否连接 /// public bool bConnected = true; /// /// 是否有心跳 /// protected bool bHeart = true; /// /// 连接参数 /// public CommunicatorCollections CommunicatorConnections = new CommunicatorCollections(); /// /// 运行日志 /// public string Msg = string.Empty; /// /// 接受到的消息 /// protected string strReceiveMsg = string.Empty; /// /// 发送的消息 /// protected string strSendMsg = string.Empty; /// /// 获取消息回调 /// public Action MessageReceived; /// /// 获取消息回调 /// public Action TriggerRunMessageReceived; /// /// 心跳信号 /// public string strHeartbeat = "\0"; /// /// 心跳间隔 /// private const int HeartbeatInterval = 30; // 心跳间隔(30秒) /// /// 心跳发送线程 /// public Thread heartbeatThread; public BaseCommunicator(string name = "") { CommunicatorName = name; } public virtual void SendHeartbeat() { while (true) { Thread.Sleep(50); if (!bConnected) return; try { // 发送失败则重连 if (!SendMessage(strHeartbeat) || !bHeart) { bHeart = false; Connect(); } else bHeart = true; // 为避免心跳延时导致关闭软件延时采用for循环,过程中判断是否连接已断开 for (int i = 0; i < HeartbeatInterval; i++) { Thread.Sleep(1000); if (!bConnected) return; } } catch (Exception ex) { Msg = $"心跳丢失+{ex.Message}"; return; } } } public abstract bool Connect(); public abstract bool Disconnect(); public virtual string ReceiveMsg() { string msg = string.Empty; for (int i = 0; i <= 3; i++) { if (string.IsNullOrEmpty(strReceiveMsg)) Thread.Sleep(25); else { msg = strReceiveMsg; strReceiveMsg = string.Empty; return msg; } } return msg; } public abstract bool SendMessage(string message); public abstract bool SendMessage(byte[] message); // 清空缓冲区 public void ClearMessage() { strReceiveMsg = string.Empty; } public virtual void Dispose() { Disconnect(); } public static ushort[] CRC_TABLE = new ushort[]{ 0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7, 0x8108,0x9129,0xA14A,0xB16B,0xC18C,0xD1AD,0xE1CE,0xF1EF }; public static ushort CRC16Calculate(byte[] data, int length) { ushort uwCRC = 0xFFFF; byte ucTemp; for (int index = 0; index < length; index++) { ucTemp = (byte)(uwCRC >> 0x0C); // 提取CRC的高4位 uwCRC <<= 4; // CRC左移4位 uwCRC ^= CRC_TABLE[ucTemp ^ data[index] >> 0x04]; // 高4位数据与CRC表进行异或 ucTemp = (byte)(uwCRC >> 0x0C); // 再次提取CRC的高4位 uwCRC <<= 4; // CRC再次左移4位 uwCRC ^= CRC_TABLE[ucTemp ^ data[index] & 0x0F]; // 低4位数据与CRC表进行异或 } return uwCRC; } public static byte[] strToHexByte(string hexString) { try { hexString = hexString.Replace(" ", ""); if (hexString.Length % 2 != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } catch { return new byte[] { }; } } } }