using FlyADBase.Inc;
using NLog;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FlyADBase
{
public class FlyAd2021Core : IFlyAd2021Core
{
Logger logger = NLog.LogManager.GetCurrentClassLogger();
public event PropertyChangedEventHandler PropertyChanged;
#region 测量速度
public bool IsMeasuring { get; private set; }
///
/// 通讯速度 byte/s
///
public double CommSpeed { get; private set; }
///
/// 传输速度 单位 pack/s
///
public double PackSpeed { get; private set; }
#endregion
///
/// 包出错次数
///
public int ErrCnt { get; private set; }
///
/// 连接成功;
/// 当命令多次发送失败,IsConnected = false
///
public bool IsConnected { get; private set; }
///
/// 有数据需要发送
///
public event SendMsgEventHander SendMsgEvent;
///
/// 数据推送事件
///
public event PushDataEventHandler PushDataEvent;
///
/// 运行状态推送事件
///
public event PushRunResultEventHandler PushRunResultEvent;
List currPack = new List();
int packCnt = 0;
int recCnt = 0;
Stopwatch stopwatch = new Stopwatch();
CancellationTokenSource cancellationTokenSource;
///
/// 全部指令类别
///
Dictionary COMMREQs;
///
/// 指令队列,必须等上1条指令回复了,才能发下条指令
///
List Transactions;
///
/// 当前正在等待回复的指令
///
COMMREQ_Transaction currTran;
///
/// currTran 发送后,开始计时
///
Stopwatch stopwatch_timeOut;
///
/// currTran 重发次数
///
int retryCnt = 0;
COMMREQ COMMREQ_RN;
public FlyAd2021Core()
{
//COMMREQ_RN 作为事件,会触发一次,作为指令,也会回复一次
COMMREQ_RN = new COMMREQ(COMMREQ_Type.RN, 5, (pack, dataIdx) =>
{
DRIVE_MAN_STATUS result = (DRIVE_MAN_STATUS)pack[dataIdx];
dataIdx += 1;
UInt32 serial = BitConverter.ToUInt32(pack, dataIdx);
dataIdx += 4;
return new GetRunResult_Reponse()
{
result = result,
serial = serial
};
});
var _COMMREQs = new List
{
COMMREQ_RN,
#region IOComm IO指令
new COMMREQ(COMMREQ_Type.IGI,2,(pack,dataIdx)=>BitConverter.ToUInt16(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.IGO,2,(pack,dataIdx)=>BitConverter.ToUInt16(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.IGP0,4,(pack,dataIdx)=>BitConverter.ToInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.IGP1,4,(pack,dataIdx)=>BitConverter.ToInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.IGPA,8,(pack,dataIdx)=>{
int pos1 = BitConverter.ToInt32(pack, dataIdx);
dataIdx += 4;
int pos2 = BitConverter.ToInt32(pack, dataIdx);
dataIdx += 4;
return new GetEncAll_Reponse()
{
pos1 = pos1,
pos2 = pos2
};
}),
new COMMREQ(COMMREQ_Type.ISO),
#endregion
#region RunComm 运行指令 SetRunParam
new COMMREQ(COMMREQ_Type.RPV),
new COMMREQ(COMMREQ_Type.RPS),
new COMMREQ(COMMREQ_Type.RPU),
new COMMREQ(COMMREQ_Type.RPD),
new COMMREQ(COMMREQ_Type.RP1),
new COMMREQ(COMMREQ_Type.RP2),
#endregion
#region RunComm 运行指令 GetRunParam
new COMMREQ(COMMREQ_Type.RpV,4,(pack,dataIdx)=>BitConverter.ToUInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.RpS,4,(pack,dataIdx)=>BitConverter.ToUInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.RpU,4,(pack,dataIdx)=>BitConverter.ToUInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.RpD,4,(pack,dataIdx)=>BitConverter.ToUInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.Rp1,4,(pack,dataIdx)=>BitConverter.ToUInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.Rp2,4,(pack,dataIdx)=>BitConverter.ToUInt32(pack, dataIdx)),
#endregion
#region RunComm 运行指令
new COMMREQ(COMMREQ_Type.RR),
new COMMREQ(COMMREQ_Type.RO),
new COMMREQ(COMMREQ_Type.RF),
new COMMREQ(COMMREQ_Type.RB),
new COMMREQ(COMMREQ_Type.RS),
new COMMREQ(COMMREQ_Type.RT),
#endregion
#region 同步运行指令
new COMMREQ(COMMREQ_Type.RD0x80,new byte[]{ (byte)'R', (byte)'D',0x80}),
new COMMREQ(COMMREQ_Type.RD0x81,new byte[]{ (byte)'R', (byte)'D',0x81}),
new COMMREQ(COMMREQ_Type.RD0x02,new byte[]{ (byte)'R', (byte)'D',0x02}),
new COMMREQ(COMMREQ_Type.RD0x03,new byte[]{ (byte)'R', (byte)'D',0x03}),
new COMMREQ(COMMREQ_Type.RD0x04,new byte[]{ (byte)'R', (byte)'D',0x04}),
new COMMREQ(COMMREQ_Type.RD0xE0,new byte[]{ (byte)'R', (byte)'D',0xE0}),
new COMMREQ(COMMREQ_Type.RD0xE1,new byte[]{ (byte)'R', (byte)'D',0xE1}),
new COMMREQ(COMMREQ_Type.RD0xE2,new byte[]{ (byte)'R', (byte)'D',0xE3}),
new COMMREQ(COMMREQ_Type.RGD,2),
#endregion
#region SysParamComm 系统参数指令
new COMMREQ(COMMREQ_Type.ST,4,(pack,dataIdx)=>BitConverter.ToInt32(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.SI0,1,(pack,dataIdx)=> pack[dataIdx] == (byte)'O'),
new COMMREQ(COMMREQ_Type.SA,2,(pack,dataIdx)=>{
short ret = BitConverter.ToInt16(pack, dataIdx);
if(ret == 0)
return AREA_ERR.NO_ERR;
else if(ret == -105)
return AREA_ERR.DUP_ACCESS;
else// if(ret == -101)
return AREA_ERR.ERR_ACCESS;
}),
new COMMREQ(COMMREQ_Type.Sa,18,(pack,dataIdx)=>{
GetAccess_Reponse reponse = new GetAccess_Reponse();
int idx = dataIdx;
reponse.status = (AREA_STATUS)pack[idx];
idx++;
reponse.ret = (AREA_ERR)pack[idx];
idx++;
Array.Copy(pack, idx, reponse.code, 0, 6);
idx += 6;
reponse.surplus = BitConverter.ToUInt16(pack, idx);
idx += 2;
Array.Copy(pack, idx, reponse.access, 0, 8);
idx += 8;
return reponse;
}),
new COMMREQ(COMMREQ_Type.S1),
#endregion
#region GetSysParam 读运行参数
new COMMREQ(COMMREQ_Type.SpM,1,(pack,dataIdx)=>{
byte motorType = pack[dataIdx];
motorType &= 3;
return (MOTORTYPE)motorType;
}),
new COMMREQ(COMMREQ_Type.Spm,2,(pack,dataIdx)=>BitConverter.ToUInt16(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.SpE,2,(pack,dataIdx)=>BitConverter.ToUInt16(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.SpZ,2,(pack,dataIdx)=>BitConverter.ToInt16(pack, dataIdx)),
new COMMREQ(COMMREQ_Type.SpJ,4,(pack,dataIdx)=>BitConverter.ToUInt32(pack, dataIdx)),
#endregion
#region SetSysParam 读运行参数
new COMMREQ(COMMREQ_Type.SPM),
new COMMREQ(COMMREQ_Type.SPm),
new COMMREQ(COMMREQ_Type.SPE),
new COMMREQ(COMMREQ_Type.SPZ),
new COMMREQ(COMMREQ_Type.SPJ),
#endregion
};
COMMREQs = new Dictionary();
foreach (var commreq in _COMMREQs)
{
COMMREQs.Add(commreq.CType, commreq);
}
Transactions = new List();
stopwatch_timeOut = new Stopwatch();
}
#region 测量
public void StartMeasure()
{
if (IsMeasuring)
return;
IsMeasuring = true;
cancellationTokenSource = new CancellationTokenSource();
//启动线程,测量速度
Task.Factory.StartNew(MeasureTask, cancellationTokenSource.Token);
}
public void StopMeasure()
{
cancellationTokenSource.Cancel();
//停止线程
IsMeasuring = false;
}
async void MeasureTask()
{
stopwatch.Start();
while (!cancellationTokenSource.IsCancellationRequested)
{
if (stopwatch.Elapsed > TimeSpan.FromSeconds(1))
{
//1秒均值
CommSpeed = recCnt / stopwatch.Elapsed.TotalSeconds;
PackSpeed = packCnt / stopwatch.Elapsed.TotalSeconds;
recCnt = 0;
packCnt = 0;
stopwatch.Restart();
}
await Task.Delay(100);
}
stopwatch.Stop();
}
#endregion
///
/// 发送指令的超时判断
///
public void OnPoll_TimeOut()
{
//TODO 要处理 TimeOut / ParseFuncPack / GetSendMsg 线性同步问题
if (!IsConnected)
return;
if (currTran == null)
return;//没有指令
if (!stopwatch_timeOut.IsRunning)
return;//还没开始发送
if (stopwatch_timeOut.Elapsed < TimeSpan.FromSeconds(1))
return;//发送到现在,还没到1秒,继续等
//大于1秒也没回复,异常
//重试3次
retryCnt++;
stopwatch_timeOut.Stop();//停止,等下次发送
if (retryCnt >= 3)
{
//已经重试了3次,放弃
IsConnected = false;
currTran = null;
//清空 指令队列
Transactions.Clear();
return;
}
else
{
//再发一次指令
SendMsgEvent?.Invoke(this);
}
}
public void RecMsg(byte[] recBuf)
{
IsConnected = true;
for (int i = 0; i < recBuf.Count(); i++)
{
if (recBuf[i] == 0x7e)
{
//找到头了
//结束之前的包
if (currPack.Count > 0)
{
var pack = currPack.ToArray();
ParsePack(pack);
currPack.Clear();
packCnt++;
}
}
currPack.Add(recBuf[i]);
}
//OnPoll_TimeOut();
}
///
/// 获取 发送队列 第1条msg
///
///
public byte[] GetSendMsg()
{
//TODO 要处理 TimeOut / ParseFuncPack / GetSendMsg 线性同步问题
if (currTran == null)
{
//当前没有指令正在发送
if (Transactions.Count() == 0)//队列没有需要发送的指令
return null;
currTran = Transactions.First();
retryCnt = 0;
Transactions.RemoveAt(0);
}
else
{
//发送出去中,等待回复
if (stopwatch_timeOut.IsRunning)
return null;//已经发送了,计时器都启动了
}
//找出 COMMREQ
var commReq = COMMREQs[currTran.ctype];
List pack = new List();
pack.AddRange(commReq.Prefix);
if (currTran.datas != null)
pack.AddRange(currTran.datas);
if (currTran.datasObj == null)
logger.Debug($"REQ {commReq.CType}");
else
logger.Debug($"REQ {commReq.CType} {Newtonsoft.Json.JsonConvert.SerializeObject(currTran.datasObj)}");
//获取需要发送出去的数据
var buf = GetSendPack(pack).ToArray();
//开始计时
stopwatch_timeOut.Restart();
return buf;
}
///
/// 复位全部状态,通常由于通讯模块检测到连接断开导致的
///
public void ResetMsg()
{
currTran = null;
stopwatch_timeOut.Stop();
recCnt = 0;
IsConnected = false;
Transactions.Clear();
}
/// 包解析
///
void ParsePack(byte[] pack)
{
//第0个肯定是7E
if (pack.Count() == 1)
{
//只有一个 7E
return;
}
//转义数据
if (!ProtocolCommon.Pdu2Data(pack, out List datas))
{
//异常
return;
}
pack = datas.ToArray();
//解析后的 datas 没有了 帧包装 7E
byte crc8 = Misc.CRC.CRC8(pack, 0, pack.Count() - 1);
if (pack.Last() != crc8)
{
//CRC8 出错
ErrCnt++;
return;
}
byte B0 = pack[0];
bool PT = Misc.MyBase.CHECKBIT(B0, 7);
if (!PT)
{
ParseDataPack(pack);
}
else
{
ParseFuncPack(pack);
}
}
void ParseDataPack(byte[] pack)
{
PushDataEventArgs eventArgs = new PushDataEventArgs();
int ReponseLen = 4;
if (ReponseLen > pack.Count())
{
//失败,指令长度不对!!
ErrCnt++;
return;
}
byte systick = pack[0];
Misc.MyBase.CLEARBIT(ref systick, 7);
eventArgs.SysTick = systick;
byte B1 = pack[1];
bool hasIn = Misc.MyBase.CHECKBIT(B1, 7);
bool hasENC1 = Misc.MyBase.CHECKBIT(B1, 6);
bool hasENC2 = Misc.MyBase.CHECKBIT(B1, 5);
bool hasOut = Misc.MyBase.CHECKBIT(B1, 4);
var buf = pack;
int index = 2;
eventArgs.AD = BitConverter.ToUInt16(buf, index);
index += 2;
if (hasIn)
{
ReponseLen += 4;
if (ReponseLen > pack.Count())
{
//失败,指令长度不对!!
ErrCnt++;
return;
}
eventArgs.In = BitConverter.ToUInt16(buf, index);
index += 2;
eventArgs.InChange = BitConverter.ToUInt16(buf, index);
index += 2;
}
if (hasENC1)
{
ReponseLen += 2;
if (ReponseLen > pack.Count())
{
//失败,指令长度不对!!
ErrCnt++;
return;
}
eventArgs.ENC1 = BitConverter.ToUInt16(buf, index);
index += 2;
}
if (hasENC2)
{
ReponseLen += 2;
if (ReponseLen > pack.Count())
{
//失败,指令长度不对!!
ErrCnt++;
return;
}
eventArgs.ENC2 = BitConverter.ToUInt16(buf, index);
index += 2;
}
if (hasOut)
{
ReponseLen += 2;
if (ReponseLen > pack.Count())
{
//失败,指令长度不对!!
ErrCnt++;
return;
}
eventArgs.Out = BitConverter.ToUInt16(buf, index);
index += 2;
}
PushDataEvent?.Invoke(this, eventArgs);
}
void ParseFuncPack_PushRunResultEvent(byte[] pack)
{
PushRunResultEventArgs eventArgs = new PushRunResultEventArgs();
var retData = COMMREQ_RN.ParseFuncPack(pack, 1 + COMMREQ_RN.Prefix.Count()) as GetRunResult_Reponse;
eventArgs.Status = retData.result;
eventArgs.Serial = retData.serial;
logger.Debug($"REQ RN {Newtonsoft.Json.JsonConvert.SerializeObject(retData)}");
byte systick = pack[0];
Misc.MyBase.CLEARBIT(ref systick, 7);
eventArgs.SysTick = systick;
PushRunResultEvent?.Invoke(this, eventArgs);
}
///
/// 功能包解析
///
///
void ParseFuncPack(byte[] pack)
{
//TODO 要处理 TimeOut / ParseFuncPack / GetSendMsg 线性同步问题
//优先处理 PushRunResultEvent 事件
if (IsMatch(COMMREQ_RN, pack))
{
//还有B0
if (COMMREQ_RN.ReponseLen + 1 > pack.Count())
{
//失败,指令长度不对!!
ErrCnt++;
return;
}
ParseFuncPack_PushRunResultEvent(pack);
}
if (currTran == null)
{
//没有请求。。。
return;
}
var commReq = COMMREQs[currTran.ctype];
if (!IsMatch(commReq, pack))
{
logger.Error($"ACK expect:{commReq.CType} ,but reponse: {Newtonsoft.Json.JsonConvert.SerializeObject(pack)}");
//回复对不上请求
return;
}
//还有B0
if (commReq.ReponseLen + 1 > pack.Count())
{
//失败,指令长度不对!!
ErrCnt++;
return;
}
//处理指令
//还有B0
object retData = null;
if (commReq.ParseFuncPack != null)//解析回复数据
retData = commReq.ParseFuncPack(pack, commReq.Prefix.Count() + 1);
if (retData == null)
logger.Debug($"ACK {commReq.CType}");
else
logger.Debug($"ACK {commReq.CType} {Newtonsoft.Json.JsonConvert.SerializeObject(retData)}");
//有很多指令是没有回复数据的, 回调只是通知 指令已经执行了而已
//调用回调
currTran.asyncDelegate?.Invoke(currTran.asyncContext, retData);
stopwatch_timeOut.Stop();
currTran = null;
if (Transactions.Count() > 0)
{
//队列还有需要发送的指令
SendMsgEvent?.Invoke(this);
}
}
bool IsMatch(COMMREQ commreq, byte[] datas)
{
//datas[0] 是B0, 不应该用于判断
if (datas.Count() < commreq.Prefix.Length + 1)
return false;
for (int i = 0; i < commreq.Prefix.Length; i++)
{
if (commreq.Prefix[i] != datas[1 + i])
{
return false;
}
}
return true;
}
///
/// 数据发送,不需要包含开头的7E
///
///
List GetSendPack(List datas)
{
datas.Insert(0, 0x80);//插入B0
//需要在后面添加CRC8
byte crc8 = Misc.CRC.CRC8(datas, 0, datas.Count);
datas.Add(crc8);
ProtocolCommon.Data2Pdu(datas, out List pack);
pack.Add(0x7E);//一定要加0x7E
return pack;
}
void AddTran(COMMREQ_Transaction tran)
{
//放入 交易队列
Transactions.Add(tran);
if (currTran == null)
{
//当前没有指令正在发送
SendMsgEvent?.Invoke(this);
}
}
#region IOComm IO指令
///
/// 获取输入口状态
///
///
///
[CallBack(typeof(UInt16))]
public void GetIn(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.IGI,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
///
/// 获取输出口状态
///
///
///
[CallBack(typeof(UInt16))]
public void GetOut(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.IGO,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
[CallBack(typeof(Int32))]
public void GetEnc1(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.IGP0,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
[CallBack(typeof(Int32))]
public void GetEnc2(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.IGP1,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
[CallBack(typeof(GetEncAll_Reponse))]
public void GetEncAll(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.IGPA,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void SetOutPorts(UInt16 mask, UInt16 value, CallBackHandler asyncDelegate, object asyncContext)
{
List datas = new List();
datas.AddRange(BitConverter.GetBytes(mask));
datas.AddRange(BitConverter.GetBytes(value));
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.ISO,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = datas.ToArray(),
datasObj = new { mask, value }
});
}
#endregion
#region RunComm 运行指令 SetRunParam
public void SetRunParam_V(UInt32 velocity, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RPV,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(velocity),
datasObj = velocity
});
}
public void SetRunParam_SV(UInt32 sv, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RPS,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(sv),
datasObj = sv
});
}
public void SetRunParam_AccTime(UInt32 accTime, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RPU,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(accTime),
datasObj = accTime
});
}
public void SetRunParam_DecTime(UInt32 decTime, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RPD,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(decTime),
datasObj = decTime
});
}
public void SetRunParam_HSpd1(UInt32 homespd1, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RP1,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(homespd1),
datasObj = homespd1,
});
}
public void SetRunParam_HSpd2(UInt32 homespd2, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RP2,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(homespd2),
datasObj = homespd2
});
}
#endregion
#region RunComm 运行指令 GetRunParam
public void GetRunParam_V(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RpV,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void GetRunParam_SV(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RpS,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void GetRunParam_AccTime(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RpU,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void GetRunParam_DecTime(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RpD,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void GetRunParam_HSpd1(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.Rp1,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void GetRunParam_HSpd2(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.Rp2,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
#endregion
#region RunComm 运行指令
public void GetRunResult(CallBackHandler asyncDelegate, object asyncContext)
{
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RN,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
}
public void Forw(Int32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RF,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(serial),
datasObj = serial
});
}
public void Backw(Int32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RB,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(serial),
datasObj = serial
});
}
public void Org(Int32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RO,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(serial),
datasObj = serial
});
}
public void RunTo(int targetPos, Int32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
List datas = new List();
datas.Add((byte)'P');
datas.AddRange(BitConverter.GetBytes(targetPos));
datas.AddRange(BitConverter.GetBytes(serial));
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RR,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = datas.ToArray(),
datasObj = new { targetPos, serial }
});
}
public void Stop(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RS,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void EStop(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RT,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
#endregion
#region 同步运行指令
public void SyncRun_SetHShift(int hShift, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0x80,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(hShift),
datasObj = hShift
});
}
public void SyncRun_SetVShift(int vShift, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0x81,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(vShift),
datasObj = vShift
});
}
public void SyncRun_Start(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0x02,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void SyncRun_Stop(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0x03,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
public void SyncRun_Clear(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0x04,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
///
/// 同步扫描至;
/// D+0xE0+开始主轴位置+结束主轴位置+结束横向脉冲位置(逻辑位置)+命令识标号(4B)
///
///
///
///
///
public void SyncRun_RunAtLC(int pos2_begin, int pos2_end, int pos1lc, UInt32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
List datas = new List();
datas.AddRange(BitConverter.GetBytes(pos2_begin));
datas.AddRange(BitConverter.GetBytes(pos2_end));
datas.AddRange(BitConverter.GetBytes(pos1lc));
datas.AddRange(BitConverter.GetBytes(serial));
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0xE0,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = datas.ToArray(),
datasObj = new { pos2_begin, pos2_end, pos1lc, serial }
});
}
///
/// 位于队列头时运行,归零;
/// D+0xE1+命令识标号(4B)
///
///
public void SyncRun_Origin(UInt32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0xE1,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(serial),
datasObj = serial
});
}
///
/// 位于队列头时运行,以速度运行至物理位置;
/// D+0xE2+横向脉冲位置(4B:int32,物理位置)+速度(4B:int32)+命令识标号(4B)
///
///
///
///
public void SyncRun_RunTo(int pos1, UInt32 velocity, UInt32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
List datas = new List();
datas.AddRange(BitConverter.GetBytes(pos1));
datas.AddRange(BitConverter.GetBytes(velocity));
datas.AddRange(BitConverter.GetBytes(serial));
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0xE2,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = datas.ToArray(),
datasObj = new { pos1, velocity, serial }
});
}
///
/// 位于队列头时运行,以速度运行至逻辑位置;
/// D+0xE3+横向脉冲位置(4B:int32,逻辑位置)+速度(4B:int32)+命令识标号(4B)
///
///
///
///
///
public void SyncRun_RunToLC(int pos1lc, UInt32 velocity, UInt32 serial, CallBackHandler asyncDelegate, object asyncContext)
{
List datas = new List();
datas.AddRange(BitConverter.GetBytes(pos1lc));
datas.AddRange(BitConverter.GetBytes(velocity));
datas.AddRange(BitConverter.GetBytes(serial));
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RD0xE3,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = datas.ToArray(),
datasObj = new { pos1lc, velocity, serial }
});
}
///
/// 获取队列长度
///
///
///
public void SyncRun_GetListCount(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.RGD,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
#endregion
#region SysParamComm 系统参数指令
///
/// 获取系统当前Tick
///
[CallBack(typeof(UInt32))]
public void GetSysTick(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.ST,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
///
/// 初始化系统信息区
///
///
///
[CallBack(typeof(bool))]
public void InitArea(CallBackHandler asyncDelegate, object asyncContext)
{
string password = "@flymeasure!";
List datas = new List();
datas.AddRange(password.Select(p => (byte)p));
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SI0,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = datas.ToArray(),
datasObj = new { password }
});
}
///
/// 输入系统授权码
///
///
///
///
[CallBack(typeof(AREA_ERR))]
public void CheckAccessCode(byte[] access, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SA,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = access,
datasObj = access
});
}
///
/// 获取系统授权信息
///
///
///
[CallBack(typeof(GetAccess_Reponse))]
public void GetAccess(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.Sa,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
///
/// 系统运行时间+1
///
///
///
public void AddAccess(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.S1,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
#endregion
#region GetSysParam 读运行参数
[CallBack(typeof(MOTORTYPE))]
public void GetSysParam_MotorType(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SpM,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
[CallBack(typeof(UInt16))]
public void GetSysParam_Ratio01(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.Spm,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
[CallBack(typeof(UInt16))]
public void GetSysParam_Ratio02(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SpE,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
[CallBack(typeof(Int16))]
public void GetSysParam_Zero(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SpZ,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
[CallBack(typeof(UInt32))]
public void GetSysParam_Jog(CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SpJ,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext
});
}
#endregion
#region SetSysParam 设置运行参数
public void SetSysParam_MotorType(MOTORTYPE motorType, CallBackHandler asyncDelegate, object asyncContext)
{
byte request = (byte)motorType;
Misc.MyBase.SIGNBIT(ref request, 5);
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SPM,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = new byte[] { request },
datasObj = motorType
});
}
public void SetSysParam_Ratio01(UInt16 ratio01, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SPm,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(ratio01),
datasObj = ratio01
});
}
public void SetSysParam_Ratio02(UInt16 ratio02, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SPE,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(ratio02),
datasObj = ratio02
});
}
public void SetSysParam_Zero(Int16 zero, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SPZ,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(zero),
datasObj = zero
});
}
public void SetSysParam_Jog(UInt32 jog, CallBackHandler asyncDelegate, object asyncContext)
{
//放入 交易队列
AddTran(
new COMMREQ_Transaction()
{
ctype = COMMREQ_Type.SPJ,
asyncDelegate = asyncDelegate,
asyncContext = asyncContext,
datas = BitConverter.GetBytes(jog),
datasObj = jog
});
}
#endregion
}
///
/// 通知指令
///
class COMMREQ
{
public COMMREQ_Type CType;
///
/// 指令 前缀
///
public byte[] Prefix;
public string PrefixString
{
get
{
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < Prefix.Count(); i++)
{
stringBuilder.Append((char)Prefix[i]);
}
return stringBuilder.ToString();
}
}
///
/// 回复数据 总长度,含前序
///
public int ReponseLen;
public delegate object ParseFuncPackHandler(byte[] pack, int dataIdx);
public ParseFuncPackHandler ParseFuncPack;
public COMMREQ(COMMREQ_Type ctype)
{
CType = ctype;
string prefixString = CType.ToString();
Prefix = new byte[prefixString.Count()];
this.Prefix = prefixString.Select(p => (byte)p).ToArray();
this.ReponseLen = Prefix.Length;
}
public COMMREQ(COMMREQ_Type ctype, int reponseLen)
{
CType = ctype;
string prefixString = CType.ToString();
Prefix = new byte[prefixString.Count()];
this.Prefix = prefixString.Select(p => (byte)p).ToArray();
this.ReponseLen = reponseLen;
}
public COMMREQ(COMMREQ_Type ctype, int dataLen, ParseFuncPackHandler parseFuncPack)
{
CType = ctype;
string prefixString = CType.ToString();
Prefix = new byte[prefixString.Count()];
this.Prefix = prefixString.Select(p => (byte)p).ToArray();
this.ParseFuncPack = parseFuncPack;
this.ReponseLen = Prefix.Count() + dataLen;
}
public COMMREQ(COMMREQ_Type ctype, string prefix, int reponseLen, ParseFuncPackHandler parseFuncPack)
{
CType = ctype;
Prefix = new byte[prefix.Count()];
this.Prefix = prefix.Select(p => (byte)p).ToArray();
this.ParseFuncPack = parseFuncPack;
this.ReponseLen = reponseLen;
}
public COMMREQ(COMMREQ_Type ctype, byte[] prefixs, int reponseLen, ParseFuncPackHandler parseFuncPack)
{
CType = ctype;
this.Prefix = prefixs;
this.ParseFuncPack = parseFuncPack;
this.ReponseLen = reponseLen;
}
public COMMREQ(COMMREQ_Type ctype, byte[] prefixs)
{
CType = ctype;
this.Prefix = prefixs;
this.ReponseLen = prefixs.Length;
}
}
enum COMMREQ_Type
{
#region IOComm IO指令
IGI,
IGO,
IGP0,
IGP1,
IGPA,
ISO,
#endregion
#region RunComm 运行指令 SetRunParam
RPV,
RPS,
RPU,
RPD,
RP1,
RP2,
#endregion
#region RunComm 运行指令 GetRunParam
RpV,
RpS,
RpU,
RpD,
Rp1,
Rp2,
#endregion
#region RunComm 运行指令
RF,
RB,
RO,
RR,
RS,
RT,
RN,
#endregion
#region D,同步运行指令
RD0x80,
RD0x81,
RD0x02,
RD0x03,
RD0x04,
RD0xE0,
RD0xE1,
RD0xE2,
RD0xE3,
RGD,
#endregion
#region SysParamComm 系统参数指令
ST,
SI0,
SA,
Sa,
S1,
#endregion
#region GetSysParam 读运行参数
SpM,
Spm,
SpE,
SpZ,
SpJ,
#endregion
#region SetSysParam 设置运行参数
SPM,
SPm,
SPE,
SPZ,
SPJ,
#endregion
}
class COMMREQ_Transaction
{
///
/// 请求的前缀
///
public COMMREQ_Type ctype;
///
/// 回复 callback
///
public CallBackHandler asyncDelegate;
///
/// 上下文
///
public object asyncContext;
///
/// 数据
///
public byte[] datas;
///
/// 数据的object 表达,只用于调试而已
///
public object datasObj;
}
}