using Newtonsoft.Json;
|
|
namespace LB_VisionProcesses.Communicators
|
{
|
[JsonObject(MemberSerialization.OptOut)]
|
public abstract class BaseCommunicator : ICommunicator
|
{
|
/// <summary>
|
/// 子类名称
|
/// </summary>
|
public string ClassName { get; set; } = string.Empty;
|
/// <summary>
|
/// 通讯名称
|
/// </summary>
|
public string CommunicatorName { get; set; } = string.Empty;
|
|
/// <summary>
|
/// 通讯类名
|
/// </summary>
|
public CommunicatorBrand CommunicatorBrand { get; set; } = CommunicatorBrand.UARTPort;
|
|
/// <summary>
|
/// 是否连接
|
/// </summary>
|
public bool bConnected = true;
|
|
/// <summary>
|
/// 是否有心跳
|
/// </summary>
|
protected bool bHeart = true;
|
|
/// <summary>
|
/// 连接参数
|
/// </summary>
|
public CommunicatorCollections<object> CommunicatorConnections = new CommunicatorCollections<object>();
|
|
/// <summary>
|
/// 运行日志
|
/// </summary>
|
public string Msg = string.Empty;
|
|
/// <summary>
|
/// 接受到的消息
|
/// </summary>
|
public string strReceiveMsg = string.Empty;
|
|
/// <summary>
|
/// 发送的消息
|
/// </summary>
|
public string strSendMsg = string.Empty;
|
|
/// <summary>
|
/// 获取消息回调
|
/// </summary>
|
[JsonIgnore]
|
public Action<string> MessageReceived;
|
/// <summary>
|
/// 获取消息回调
|
/// </summary>
|
[JsonIgnore]
|
public Action<string, string> TriggerRunMessageReceived;
|
|
/// <summary>
|
/// 心跳信号
|
/// </summary>
|
public string strHeartbeat = "\0";
|
|
/// <summary>
|
/// 心跳间隔
|
/// </summary>
|
private const int HeartbeatInterval = 2; // 心跳间隔(2秒)
|
|
/// <summary>
|
/// 心跳发送线程
|
/// </summary>
|
[JsonIgnore]
|
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 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[] { }; }
|
}
|
}
|
}
|