Commit 02d521f5 authored by 潘栩锋's avatar 潘栩锋 :bicyclist:

添加 GeneralGommunication 添加 ModbusASCII,ModbusRTU 客户端,服务端,

......@@ -21,7 +21,7 @@ namespace GeneralGommunication
/// </summary>
public abstract class Dev7E:IDev7E
{
public Logger logger = NLog.LogManager.GetCurrentClassLogger();
protected Logger logger = NLog.LogManager.GetCurrentClassLogger();
public event PropertyChangedEventHandler PropertyChanged;
......@@ -313,13 +313,33 @@ namespace GeneralGommunication
}
protected abstract void ParsePackAfterCheckCRC8(byte[] buf);
string bytes2hex(byte[] pack)
public string bytes2hexChar(byte[] pack)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pack.Count(); i++)
{
if (pack[i] >= 0x21 && pack[i] <= 0x7e)
{
//这个字符可以打印
sb.Append($"{pack[i]:X2}({(char)pack[i]}) ");
}
else {
sb.Append($"{pack[i]:X2}( ) ");
}
}
return sb.ToString();
}
public string bytes2hex(byte[] pack)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pack.Count(); i++)
{
sb.Append($"{pack[i]:X2} ");
}
return sb.ToString();
}
/// <summary>
......@@ -351,10 +371,10 @@ namespace GeneralGommunication
var commReq = tran.commReq;
//还有B0
if (commReq.ReponseTotalLen + PrefixIndex > pack.Count())
if (commReq.ResponseTotalLen + PrefixIndex > pack.Count())
{
//失败,指令长度不对!!
logger.Error($"ACK expect:{commReq.PrefixString} len={commReq.ReponseTotalLen + 1}, but reponse len ={pack.Count()} reponse: {bytes2hex(pack)}");
logger.Error($"ACK expect:{commReq.PrefixString} len={commReq.ResponseTotalLen + 1}, but reponse len ={pack.Count()} reponse: {bytes2hexChar(pack)}");
ErrCnt++;
return false;
}
......@@ -364,7 +384,7 @@ namespace GeneralGommunication
if (!commReq.IsMatch(commReq, pack, PrefixIndex, commReq.IsMatchContext, ref retData))
{
//回复对不上请求
logger.Error($"ACK expect:{commReq.PrefixString} len={commReq.ReponseTotalLen + 1}, but reponse len ={pack.Count()} reponse: {bytes2hex(pack)}");
logger.Error($"ACK expect:{commReq.PrefixString} len={commReq.ResponseTotalLen + 1}, but reponse len ={pack.Count()} reponse: {bytes2hexChar(pack)}");
ErrCnt++;
return false;
}
......@@ -374,7 +394,7 @@ namespace GeneralGommunication
if (!IsMatch(commReq, pack))
{
//回复对不上请求
logger.Error($"ACK expect:{commReq.PrefixString} len={commReq.ReponseTotalLen + 1}, but reponse len ={pack.Count()} reponse: {bytes2hex(pack)}");
logger.Error($"ACK expect:{commReq.PrefixString} len={commReq.ResponseTotalLen + 1}, but reponse len ={pack.Count()} reponse: {bytes2hexChar(pack)}");
ErrCnt++;
return false;
}
......@@ -424,7 +444,7 @@ namespace GeneralGommunication
bool IsMatch2(COMMREQ commReq, byte[] pack, ref object retData)
{
//还有B0
if (commReq.ReponseTotalLen + PrefixIndex > pack.Count())
if (commReq.ResponseTotalLen + PrefixIndex > pack.Count())
{
//失败,指令长度不对!!
//logger.Error($"ACK expect:{commReq.PrefixString} len={commReq.ReponseTotalLen + 1}, but reponse len ={pack.Count()} reponse: {bytes2hex(pack)}");
......@@ -482,7 +502,7 @@ namespace GeneralGommunication
if (commReq == null) {
//不能解析
logger.Error($"ACK multi reponse len ={pack.Count()} reponse: {bytes2hex(pack)}");
logger.Error($"ACK multi reponse len ={pack.Count()} reponse: {bytes2hexChar(pack)}");
ErrCnt++;
return false;
}
......
This diff is collapsed.
......@@ -60,13 +60,14 @@ namespace GeneralGommunication
{
this.sp = serialPort;
}
public void Write(byte[] buf)
public void Write(IEnumerable<byte> buf)
{
if (!IsConnected)
return;
try
{
sp.Write(buf, 0, buf.Length);
var buffer = buf.ToArray();
sp.Write(buffer, 0, buffer.Length);
ErrMsg = null;
}
catch (Exception e)
......
......@@ -285,7 +285,7 @@ namespace GeneralGommunication
/// 发送数据
/// </summary>
/// <param name="buf"></param>
public void Write(byte[] buf)
public void Write(IEnumerable<byte> buf)
{
if (!IsConnected)
return;
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace GeneralGommunication
{
public class GComm_TcpListen
{
/// <summary>
/// IP 地址 and 端口号
/// </summary>
public string Addr { get; set; }
IPEndPoint LocalEp => Misc.StringConverter.ToIPEndPoint(Addr);
/// <summary>
/// 运行中
/// </summary>
public bool IsRunning { get; private set; }
public event Action<Socket> NewConnection;
Socket fd_listen;
CancellationTokenSource cts;
public GComm_TcpListen()
{
}
/// <summary>
/// 开始
/// </summary>
public void Start()
{
if (IsRunning)
return;
cts = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
IsRunning = true;
fd_listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
fd_listen.Bind(LocalEp);
fd_listen.Listen(5);
//1秒内,需要收到信息
fd_listen.ReceiveTimeout = 1000;
//1秒内,必须发送完
fd_listen.SendTimeout = 1000;
fd_listen.Blocking = true;
while (true)
{
if (cts.IsCancellationRequested)
{
//关闭全部连接
break;
}
Socket connsd;
try
{
connsd = fd_listen.Accept();
}
catch (Exception e)
{
//肯定被强制退出
break;
}
NewConnection(connsd);
}
fd_listen.Close();
IsRunning = false;
});
}
/// <summary>
/// 接收
/// </summary>
public void Stop()
{
if (!IsRunning)
return;
fd_listen.Close();
cts.Cancel();
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace GeneralGommunication
{
public class GComm_TcpServer : IGeneralComm,IDisposable
{
/// <summary>
/// IP 地址 and 端口号
/// </summary>
public string Addr { get; set; }
IPEndPoint LocalEp => Misc.StringConverter.ToIPEndPoint(Addr);
/// <summary>
/// 是否异常
/// </summary>
public bool IsError => !string.IsNullOrEmpty(ErrMsg);
/// <summary>
/// 异常信息
/// </summary>
public string ErrMsg { get; private set; }
/// <summary>
/// 运行中
/// </summary>
public bool IsRunning { get; private set; }
/// <summary>
/// 连接成功
/// </summary>
public bool IsConnected { get; private set; }
/// <summary>
/// 接收task调用
/// </summary>
public event IGeneralCommDataReceivedHandler DataReceived;
public event PropertyChangedEventHandler PropertyChanged;
Socket sock;
CancellationTokenSource cts_readTask;
CancellationTokenSource cts_waitForSend;
CancellationTokenSource cts_sendTask;
public GComm_TcpServer(Socket sock)
{
this.sock = sock;
IsConnected = true;
}
/// <summary>
/// 开始
/// </summary>
public void Start()
{
if (IsRunning)
return;
IsRunning = true;
cts_readTask = new CancellationTokenSource();
Task.Factory.StartNew(OnTask, cts_readTask.Token);
}
/// <summary>
/// 接收
/// </summary>
public void Stop()
{
if (!IsRunning)
return;
IsRunning = false;
IsConnected = false;
cts_readTask.Cancel();
if (sock != null && sock.Connected)
{
sock.Close();
sock = null;
}
}
void OnTask()
{
sendBuf.Clear();
//启动发送task
cts_sendTask = new CancellationTokenSource();
var sendtask = Task.Factory.StartNew(SendTask, cts_sendTask.Token);
//进入接收task
ReceiveTask();
//退出了,肯定连接断开了
//需要等待 SendTask 也退出了
cts_sendTask.Cancel();
sendtask.Wait();
if (sock != null)
{
sock.Close();
sock = null;
}
IsConnected = false;
IsRunning = false;
}
/// <summary>
/// 接收任务
/// </summary>
void ReceiveTask()
{
byte[] buf = new byte[0x10000];
while (!cts_readTask.IsCancellationRequested)
{
int len;
try
{
len = sock.Receive(buf);
if (len == 0)
{
continue;//没收到数据,继续等
}
}
catch (SocketException e)
{
if (e.SocketErrorCode == SocketError.TimedOut)
continue;//超时而已
else if ((e.SocketErrorCode == SocketError.ConnectionAborted)
|| (e.SocketErrorCode == SocketError.ConnectionRefused)
|| (e.SocketErrorCode == SocketError.ConnectionReset))
{
IsConnected = false;
return;
}
//Console.WriteLine($"ReceiveTask() {e}");
//肯定断开连接了
IsConnected = false;
break;
}
DataReceived?.Invoke(this, buf.Take(len).ToArray());
}
IsConnected = false;
}
/// <summary>
/// 发送任务
/// </summary>
void SendTask()
{
while (!cts_sendTask.IsCancellationRequested)
{
CancellationTokenSource cts3;
while (true)
{
byte[] buffer;
lock (sendBuf)
{
if (sendBuf.Count <= 0)
break;
buffer = sendBuf.ToArray();
}
int slen;
try
{
slen = sock.Send(buffer);
}
catch (Exception e)
{
//连接断开了
IsConnected = false;
break;
}
if (slen <= 0)
{
//连接断开了
IsConnected = false;
break;
}
else
{
lock (sendBuf)
{
sendBuf.RemoveRange(0, slen);
}
}
}
//重新等 下次被呼醒
lock (sendBuf)
{
// 呼醒 发送task
if (cts_waitForSend == null)
{
cts_waitForSend = new CancellationTokenSource();
}
//cts_waitForSend 与 cts_sendTask 合体, 任意一个都会呼醒 delay
cts3 = CancellationTokenSource.CreateLinkedTokenSource(cts_waitForSend.Token, cts_sendTask.Token);
}
try
{
Task.Delay(-1, cts3.Token).Wait();
}
catch (Exception e)
{
//被打断, 有数据需要发送
}
lock (sendBuf)
{
cts_waitForSend = null;
}
}
}
/// <summary>
/// 无限大,发送缓存
/// </summary>
List<byte> sendBuf = new List<byte>();
/// <summary>
/// 发送数据
/// </summary>
/// <param name="buf"></param>
public void Write(IEnumerable<byte> buf)
{
if (!IsConnected)
return;
lock (sendBuf)
{
//放入,发送缓存区
sendBuf.AddRange(buf);
//呼醒 发送task
if (cts_waitForSend == null)
{
cts_waitForSend = new CancellationTokenSource();
}
cts_waitForSend.Cancel();
}
}
/// <summary>
/// 清空输入缓存
/// </summary>
public void DiscardInBuffer()
{
//TODO
}
public void Dispose()
{
Stop();
}
}
}
......@@ -44,14 +44,21 @@
<ItemGroup>
<Compile Include="CommSpeedMeasuring.cs" />
<Compile Include="Dev7E.cs" />
<Compile Include="Dev7EServer.cs" />
<Compile Include="GComm_SerialPort.cs" />
<Compile Include="GComm_TcpListen.cs" />
<Compile Include="GComm_TcpServer.cs" />
<Compile Include="GComm_TcpClient.cs" />
<Compile Include="IDev7E.cs" />
<Compile Include="IGeneralComm.cs" />
<Compile Include="IModbusBase.cs" />
<Compile Include="ModbusASCII.cs" />
<Compile Include="ModbusRTUAsync.cs" />
<Compile Include="ModbusRTU.cs" />
<Compile Include="ModbusAscii.cs" />
<Compile Include="ModbusAsciiAsync.cs" />
<Compile Include="ModbusRtuServer.cs" />
<Compile Include="ModbusAsciiServer.cs" />
<Compile Include="ModbusRtuAsync.cs" />
<Compile Include="ModbusRtu.cs" />
<Compile Include="ModbusServer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Protocol7ECommon.cs" />
<Compile Include="ProtocolModbusCommon.cs" />
......
......@@ -24,6 +24,11 @@ namespace GeneralGommunication
/// </summary>
bool IsConnected { get; }
/// <summary>
/// 有数据需要发送
/// </summary>
event SendMsgEventHander SendMsgEvent;
#region 模块运行接口
/// <summary>
/// 超时判断,长时间收不到数据,会触发,0.5s调用一次
......@@ -108,12 +113,12 @@ namespace GeneralGommunication
/// <summary>
/// 回复数据 长度, 不含前序
/// </summary>
public int ReponseLen;
public int ResponseLen;
/// <summary>
/// 回复数据 总长度, 含前序
/// </summary>
public int ReponseTotalLen => Prefix.Length + ReponseLen;
public int ResponseTotalLen => Prefix.Length + ResponseLen;
public delegate object ParseFuncPackHandler(byte[] pack, int dataIdx);
......
......@@ -53,7 +53,7 @@ namespace GeneralGommunication
/// 发送数据
/// </summary>
/// <param name="buf"></param>
void Write(byte[] buf);
void Write(IEnumerable<byte> buf);
/// <summary>
......
......@@ -3,12 +3,11 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GeneralGommunication
{
public class ModbusASCII : IModbusBase
public class ModbusAscii : IModbusBase
{
/// <summary>
/// 通讯中
......@@ -47,7 +46,7 @@ namespace GeneralGommunication
Stopwatch stopwatch_lastRecPack = new Stopwatch();
TimeSpan maxElapsed;
Stopwatch stopwatch_maxElapsed = new Stopwatch();
public ModbusASCII()
public ModbusAscii()
{
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -11,7 +11,7 @@ namespace GeneralGommunication
/// <summary>
/// 完全不用, 时间间隔不能确保对,导致经常数据异常。 ASCII 好很多
/// </summary>
public class ModbusRTU : IModbusBase
public class ModbusRtu : IModbusBase
{
/// <summary>
/// 通讯中
......@@ -49,7 +49,7 @@ namespace GeneralGommunication
Stopwatch stopwatch_lastRecPack = new Stopwatch();
TimeSpan maxElapsed;
Stopwatch stopwatch_maxElapsed = new Stopwatch();
public ModbusRTU()
public ModbusRtu()
{
}
......
......@@ -16,7 +16,7 @@ namespace GeneralGommunication
/// <summary>
/// 异步modbus RTU
/// </summary>
public class ModbusRTUAsync:INotifyPropertyChanged
public class ModbusRtuAsync:INotifyPropertyChanged
{
public Logger logger = NLog.LogManager.GetCurrentClassLogger();
......@@ -63,14 +63,14 @@ namespace GeneralGommunication
/// currTran 重发次数
/// </summary>
int retryCnt = 0;
List<byte> deviceConnected = new List<byte>();
List<int> deviceConnected = new List<int>();
public event DeviceConnectEventHander DeviceConnectEvent;
System.Timers.Timer timer3d5t;//通讯包的 3.5T 时间间隔。 实际只是 15ms定时而已
System.Timers.Timer timerTimeOut;//等待回复超时
public ModbusRTUAsync()
public ModbusRtuAsync()
{
Transactions = new List<Modbus_Transaction>();
......@@ -240,118 +240,9 @@ namespace GeneralGommunication
return sb.ToString();
}
///// <summary>
///// 包解析
///// </summary>
///// <param name="datas"></param>
//protected void ParsePack()
//{
// if (currTran == null)
// {
// //没有请求。。。
// currPack.Clear();
// return;
// }
// if (currPack.Count() < 3)
// {
// //数据太少
// return;
// }
// if (currPack[0] != currTran.deviceNo)
// {
// logger.Error($"ACK 接收的SLAVE地址{currPack[0]}与发送的{currTran.deviceNo}不一致");
// ErrCnt++;
// currPack.Clear();
// return;
// }
// if (currPack[1] != currTran.func)
// {
// logger.Error($"ACK 错误码:{currPack[1]} 异常码:{currPack[2]}");
// ErrCnt++;
// currPack.Clear();
// return;
// }
// if (currPack.Count() < currTran.expRecBytes)
// return;//数据还没收完
// UInt16 crc = currPack.CRC16(0, currTran.expRecBytes - 2);
// UInt16 rec_crc = currPack.ToUInt16_Little_Endian(currTran.expRecBytes - 2);
// if (crc != rec_crc)
// {
// logger.Error($"ACK 指令码:{currTran.func:X2} CRC 校验出错 接收:{rec_crc:X4} 计算:{crc:X4}");
// ErrCnt++;
// currPack.Clear();
// return;
// }
// //成功解析出一个包
// currTran.funcData.AddRange(currPack.Skip(2).Take(currTran.expRecBytes - 4));
// csm.IncPack(1);
// currPack.Clear();
// //收到数据,停止超时检测
// timerTimeOut.Stop();
// switch (currTran.func)
// {
// case 0x03:
// {
// List<UInt16> values = new List<UInt16>();
// int index = 1;
// while (index < currTran.funcData.Count())
// {
// values.Add(currTran.funcData.ToUInt16_Big_Endian(index));
// index += 2;
// }
// currTran.retData = currTran.parse16FuncPack(values);
// }
// break;
// }
// if (logger.IsDebugEnabled)
// {
// if (currTran.retData == null)
// logger.Debug($"ACK");
// else
// logger.Debug($"ACK {Newtonsoft.Json.JsonConvert.SerializeObject(currTran.retData)}");
// }
// //有很多指令是没有回复数据的, 回调只是通知 指令已经执行了而已
// //调用回调
// if (currTran.asyncDelegate != null)
// {
// if (Dispatcher != null)//线程同步执行
// {
// Dispatcher.BeginInvoke(currTran.asyncDelegate, currTran.asyncContext, currTran.retData);
// }
// else
// {
// currTran.asyncDelegate.Invoke(currTran.asyncContext, currTran.retData);
// }
// }
// //空出当前交易位置
// currTran = null;
// if (Transactions.Count() > 0)
// {
// //队列还有需要发送的指令,通知外部获取指令发送
// SendMsgEvent?.Invoke(this);
// }
//}
/// <summary>
/// 已经收完一份数据,不会再有更多,包解析
/// </summary>
/// <param name="datas"></param>
void ParsePack()
{
if (currTran == null)
......@@ -400,7 +291,7 @@ namespace GeneralGommunication
UInt16 crc = currPack.CRC16(0, currTran.expRecBytes - 2);
UInt16 rec_crc = currPack.ToUInt16_Little_Endian(currTran.expRecBytes - 2);
UInt16 rec_crc = currPack.ToUInt16_Big_Endian(currTran.expRecBytes - 2);
if (crc != rec_crc)
{
string errMsg = $"ACK 指令码:{currTran.func:X2} CRC 校验出错 接收:{rec_crc:X4} 计算:{crc:X4}";
......@@ -523,11 +414,11 @@ namespace GeneralGommunication
void ToSendBuf(Modbus_Transaction tran)
{
var data = tran.sendBuf;
data.Add(tran.deviceNo);
data.Add((byte)tran.deviceNo);
data.Add(tran.func);
data.AddRange(tran.funcData);
UInt16 crc = data.CRC16(0, data.Count());
data.AddRange(crc.GetBytes_Little_Endian());
data.AddRange(crc.GetBytes_Big_endian());
tran.funcData.Clear();
}
/// <summary>
......@@ -540,7 +431,7 @@ namespace GeneralGommunication
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
/// <returns></returns>
public Modbus_Transaction Do_06(byte deviceNo, int addr, UInt16 value,
public Modbus_Transaction Do_06(int deviceNo, int addr, UInt16 value,
string desription,
CallBackHandler asyncDelegate, object asyncContext)
{
......@@ -570,7 +461,7 @@ namespace GeneralGommunication
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
/// <returns></returns>
public Modbus_Transaction Do_10(byte deviceNo, int addr, IEnumerable<UInt16> datas,
public Modbus_Transaction Do_10(int deviceNo, int addr, IEnumerable<UInt16> datas,
string desription,
CallBackHandler asyncDelegate, object asyncContext)
{
......@@ -608,7 +499,7 @@ namespace GeneralGommunication
/// <summary>
/// 设备编号 0~255 0是广播
/// </summary>
public byte deviceNo;
public int deviceNo;
/// <summary>
/// modbus 功能号
......@@ -672,7 +563,7 @@ namespace GeneralGommunication
public delegate void DeviceConnectEventHander(object sender, DeviceConnectEventArgs e);
public class DeviceConnectEventArgs:EventArgs
{
public byte deviceNo;
public int deviceNo;
public bool isConnected;
public string errMsg;
}
......
This diff is collapsed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GeneralGommunication
{
public interface IModbusServer
{
void Init(ModbusRegReadWriteHandler regRead, ModbusRegReadWriteHandler regWrite,
Action<IEnumerable<byte>> sendMsg, out Action<IEnumerable<byte>> recMsg);
}
public delegate bool ModbusRegReadWriteHandler(int deviceNo, UInt16 regAddr, UInt16[] regValues);
}
......@@ -237,5 +237,218 @@ namespace GeneralGommunication
lrc = (byte)(~lrc + 1);
return lrc;
}
#region ASCII HEX 转换
public static byte? Ascii2Hex(this IEnumerable<byte> ascii, int index)
{
string msg = System.Text.Encoding.ASCII.GetString(new byte[] { ascii.ElementAt(index), ascii.ElementAt(index + 1) });
try
{
return (byte)int.Parse(msg, System.Globalization.NumberStyles.HexNumber);
}
catch
{
return null;
}
}
public static byte[] Ascii2Hex(this IEnumerable<byte> ascii, int index, int len)
{
if (len % 2 != 0)
return null;
List<byte> hex = new List<byte>();
for (int i = 0; i < len / 2; i++)
{
string msg = System.Text.Encoding.ASCII.GetString(new byte[] { ascii.ElementAt(index + i * 2), ascii.ElementAt(index + i * 2 + 1) });
byte d = (byte)int.Parse(msg, System.Globalization.NumberStyles.HexNumber);
hex.Add(d);
}
return hex.ToArray();
}
public static byte[] HexToAscii(this IEnumerable<byte> hex)
{
return HexToAscii(hex, 0, hex.Count());
}
public static byte[] HexToAscii(this IEnumerable<byte> hex, int index, int len)
{
string msg = "";
for (int i = 0; i < len; i++)
{
msg += hex.ElementAt(index + i).ToString("X2");
}
return System.Text.Encoding.ASCII.GetBytes(msg);
}
public static byte[] HexToAscii(this byte hex)
{
string msg = "";
for (int i = 0; i < 1; i++)
{
msg += hex.ToString("X2");
}
return System.Text.Encoding.ASCII.GetBytes(msg);
}
#endregion
#region 调试输出
/// <summary>
/// 调试打印出16进制 例如 3A 30 31 31 30 30 30
/// </summary>
/// <param name="pack"></param>
/// <returns></returns>
public static string Bytes2Hex(this IEnumerable<byte> pack)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pack.Count(); i++)
{
sb.Append($"{pack.ElementAt(i):X2} ");
}
return sb.ToString();
}
/// <summary>
/// 调试打印出ascii 例如
/// </summary>
/// <param name="pack"></param>
/// <returns></returns>
public static string Hex2Ascii(this IEnumerable<byte> pack)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pack.Count(); i++)
{
byte b = pack.ElementAt(i);
if (b >= 0x20 && b <= 0x7E)
{
sb.Append((char)b);
}
else {
sb.Append('▯');
}
}
return sb.ToString();
}
#endregion
#region u16 to u32 or u16 to float
/// <summary>
/// 大端模式 u16 to u32
/// </summary>
/// <param name="value"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
public static UInt32 U16ToU32_Big_Endian(this IEnumerable<UInt16> value, int startIndex)
{
return (UInt32)((value.ElementAt(startIndex) << 16) | value.ElementAt(startIndex + 1));
}
/// <summary>
/// 大端模式 u16 to float
/// </summary>
/// <param name="value"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
public static float U16ToF32_Big_Endian(this IEnumerable<UInt16> value, int startIndex)
{
byte[] bs = new byte[4];
bs[3] = (byte)(value.ElementAt(startIndex) >> 8);
bs[2] = (byte)(value.ElementAt(startIndex));
bs[1] = (byte)(value.ElementAt(startIndex + 1) >> 8);
bs[0] = (byte)(value.ElementAt(startIndex + 1));
float num = BitConverter.ToSingle(bs, 0);
return num;
}
/// <summary>
/// 大端模式 u32 to u16
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static UInt16[] U32ToU16_Big_Endian(this UInt32 value)
{
UInt16[] datas = new UInt16[2];
datas[0] = (UInt16)(value >> 16);
datas[1] = (UInt16)(value);
return datas;
}
/// <summary>
/// 大端模式 float to u16
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static UInt16[] F32ToU16_Big_Endian(this float value)
{
var bs = BitConverter.GetBytes(value);
UInt16[] datas = new UInt16[2];
datas[0] = (UInt16)(bs[3] << 8 | bs[2]);
datas[1] = (UInt16)(bs[1] << 8 | bs[0]);
return datas;
}
/// <summary>
/// 小端模式 u16 to u32
/// </summary>
/// <param name="value"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
public static UInt32 U16ToU32_Little_Endian(this IEnumerable<UInt16> value, int startIndex)
{
return (UInt32)((value.ElementAt(startIndex+1) << 16) | value.ElementAt(startIndex));
}
/// <summary>
/// 小端模式 u16 to float
/// </summary>
/// <param name="value"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
public static float U16ToF32_Little_Endian(this IEnumerable<UInt16> value, int startIndex)
{
var u32 = U16ToU32_Little_Endian(value, startIndex);
byte[] bs = BitConverter.GetBytes(u32);
float num = BitConverter.ToSingle(bs, 0);
return num;
}
/// <summary>
/// 小端模式 u32 to u16
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static UInt16[] U32ToU16_Little_Endian(this UInt32 value)
{
UInt16[] datas = new UInt16[2];
datas[0] = (UInt16)(value);
datas[1] = (UInt16)(value >> 16);
return datas;
}
/// <summary>
/// 小端模式 float to u16
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static UInt16[] F32ToU16_Little_Endian(this float value)
{
var bs = BitConverter.GetBytes(value);
var u32 = BitConverter.ToUInt32(bs, 0);
UInt16[] datas = U32ToU16_Little_Endian(u32);
return datas;
}
#endregion
}
}
......@@ -316,7 +316,7 @@
<Version>4.1.0</Version>
</PackageReference>
<PackageReference Include="Unity">
<Version>5.11.10</Version>
<Version>5.11.9</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
......
......@@ -3,6 +3,7 @@ using FlyADBase.Inc;
using FObjBase;
using GeneralGommunication;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
......@@ -12,8 +13,10 @@ using System.Linq;
namespace FlyADBase
{
public partial class FlyAd2021 : IFlyADClient
public partial class FlyAd2021B2 : IFlyADClient
{
protected Logger logger = NLog.LogManager.GetCurrentClassLogger();
#region MARKNO
const int MARKNO_SET_SAVE = 4;
#endregion
......@@ -274,10 +277,10 @@ namespace FlyADBase
SysTickContext sysTickContext = new SysTickContext();
CalSpeed calSpeed = new CalSpeed();
public FlyAd2021Core Core => core;
public FlyAd2021B2Core Core => core;
IGeneralComm comm;
FlyAd2021Core core;
FlyAd2021B2Core core;
/// <summary>
/// 不设置服务器
/// </summary>
......@@ -300,12 +303,12 @@ namespace FlyADBase
string defaultPath = "flyad.json";
string jsonDbPath;
static FlyAd2021()
static FlyAd2021B2()
{
propertyName_save = FlyAd2021JsonDb.GetMemberNames();
}
public FlyAd2021()
public FlyAd2021B2()
{
constructor();
advConstructor();
......@@ -318,7 +321,7 @@ namespace FlyADBase
core = new FlyAd2021Core();
core = new FlyAd2021B2Core();
core.Csm.StartMeasure();
//注册AD2021版的发送动作,把数据通过 comm模块发送出去
......@@ -327,6 +330,8 @@ namespace FlyADBase
byte[] msg = core.GetSendMsg();
if (msg == null)
return;
logger.Debug($"W {core.bytes2hex(msg)}");
comm?.Write(msg);
};
......@@ -668,28 +673,39 @@ namespace FlyADBase
//从设备读取参数
//获取当前全部状态
core.GetSysParam_Jog((asyncContext, retData) => JogVelocity = (UInt32)retData, null);
core.GetSysParam_Zero((asyncContext, retData) => PosOffset = (Int16)retData, null);
core.GetSysParam_MotorType((asyncContext, retData) => MotorType = (MOTORTYPE)retData, null);
core.GetSysParam_Ratio01((asyncContext, retData) => Ratio01 = (UInt16)retData, null);
core.GetSysParam_Ratio02((asyncContext, retData) => Ratio02 = (UInt16)retData, null);
core.GetRunParam_V((asyncContext, retData) => Velocity = (UInt32)retData, null);
core.GetRunParam_SV((asyncContext, retData) => SVelocity = (UInt32)retData, null);
core.GetRunParam_AccTime((asyncContext, retData) => ATime = (UInt32)retData, null);
core.GetRunParam_DecTime((asyncContext, retData) => DTime = (UInt32)retData, null);
core.GetRunParam_HSpd1((asyncContext, retData) => HVelocity1 = (UInt32)retData, null);
core.GetRunParam_HSpd2((asyncContext, retData) => HVelocity2 = (UInt32)retData, null);
//core.BuildMultiTrans(() =>
//{
core.GetSysParam_Jog((asyncContext, retData) => JogVelocity = (UInt32)retData, null);
core.GetSysParam_Zero((asyncContext, retData) => PosOffset = (Int16)retData, null);
core.GetSysParam_MotorType((asyncContext, retData) => MotorType = (MOTORTYPE)retData, null);
core.GetSysParam_Ratio01((asyncContext, retData) => Ratio01 = (UInt16)retData, null);
core.GetSysParam_Ratio02((asyncContext, retData) => Ratio02 = (UInt16)retData, null);
core.GetRunParam_V((asyncContext, retData) => Velocity = (UInt32)retData, null);
core.GetRunParam_SV((asyncContext, retData) => SVelocity = (UInt32)retData, null);
core.GetRunParam_AccTime((asyncContext, retData) => ATime = (UInt32)retData, null);
core.GetRunParam_DecTime((asyncContext, retData) => DTime = (UInt32)retData, null);
core.GetRunParam_HSpd1((asyncContext, retData) => HVelocity1 = (UInt32)retData, null);
core.GetRunParam_HSpd2((asyncContext, retData) => HVelocity2 = (UInt32)retData, null);
//});
}
else
{
//参数不保存在设备中, 保存在电脑。
//参数写入到设备。
NotifyPropertyChanged(nameof(MotorType));
NotifyPropertyChanged(nameof(Ratio01));
NotifyPropertyChanged(nameof(Ratio02));
NotifyPropertyChanged(nameof(PosOffset));
NotifyPropertyChanged(nameof(JogVelocity));
core.BuildMultiTrans(() =>
{
core.SetSysParam_MotorType(MotorType, null, null);
core.SetSysParam_Ratio01(Ratio01, null, null);
core.SetSysParam_Ratio02(Ratio02, null, null);
core.SetSysParam_Zero(PosOffset, null, null);
core.SetSysParam_Jog(JogVelocity, null, null);
});
//NotifyPropertyChanged(nameof(MotorType));
//NotifyPropertyChanged(nameof(Ratio01));
//NotifyPropertyChanged(nameof(Ratio02));
//NotifyPropertyChanged(nameof(PosOffset));
//NotifyPropertyChanged(nameof(JogVelocity));
}
GetAccess();
......@@ -818,7 +834,11 @@ namespace FlyADBase
else
comm = new GComm_TcpClient();
comm.DataReceived += (sendor, msg) => core.RecMsg(msg);
comm.DataReceived += (sendor, msg) =>
{
//core.logger.Debug($"R {core.bytes2hex(msg)}");
core.RecMsg(msg);
};
}
/// <summary>
/// 连接 addr
......@@ -1035,9 +1055,9 @@ namespace FlyADBase
{
static Mapper Mapper { get; } = new AutoMapper.Mapper(new MapperConfiguration(c =>
{
c.CreateMap<FlyAd2021, FlyAd2021JsonDb>().ReverseMap();
c.CreateMap<FlyAd2021B2, FlyAd2021JsonDb>().ReverseMap();
}));
public static void Save(string jsonDbPath, FlyAd2021 src)
public static void Save(string jsonDbPath, FlyAd2021B2 src)
{
if (string.IsNullOrEmpty(jsonDbPath))
......@@ -1052,7 +1072,7 @@ namespace FlyADBase
//异常,没有json 编码失败
}
}
public static bool Load(string jsonDbPath, FlyAd2021 src)
public static bool Load(string jsonDbPath, FlyAd2021B2 src)
{
if (string.IsNullOrEmpty(jsonDbPath))
return false;
......
......@@ -9,7 +9,7 @@ using System.Runtime.Remoting.Channels;
namespace FlyADBase
{
public partial class FlyAd2021 : IFlyADClientAdv
public partial class FlyAd2021B2 : IFlyADClientAdv
{
#region IFlyADClientAdv property
/// <summary>
......
......@@ -49,13 +49,13 @@
<Compile Include="EventArgs\PositionChangedEventArgs.cs" />
<Compile Include="EventArgs\TimeGridAdvEventArgs.cs" />
<Compile Include="EventArgs\TimeGridEventArgs.cs" />
<Compile Include="FlyAd2021Adv.cs" />
<Compile Include="FlyAd2021Core.cs" />
<Compile Include="FlyAd2021.cs" />
<Compile Include="FlyAd2021B2Adv.cs" />
<Compile Include="FlyAd2021B2Core.cs" />
<Compile Include="FlyAd2021B2.cs" />
<Compile Include="Inc\IFlyAD.cs" />
<Compile Include="Inc\IFlyADClient.cs" />
<Compile Include="Inc\IFlyADClientAdv.cs" />
<Compile Include="Inc\IFlyAd2021Core.cs" />
<Compile Include="Inc\IFlyAd2021B2Core.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TimeGridAdvHelper.cs" />
</ItemGroup>
......
......@@ -8,7 +8,7 @@ namespace FlyADBase.Inc
/// AD盒2021版.B2 , 核心模块
/// 实现AD盒2021版.B2 基本接口
/// </summary>
public interface IFlyAd2021Core : INotifyPropertyChanged
public interface IFlyAd2021B2Core : INotifyPropertyChanged
{
/// <summary>
......
......@@ -593,7 +593,7 @@ namespace FlyADBase
int endIdx = dataPool.Count() - 1 - lag;
int removeCnt = lag;
for (int i = endIdx; i >= 0; i--)
for (int i = 0; i <endIdx; i++)
{
int index = i;
int idxOfAd1 = index + ad1Lag;
......
......@@ -50,7 +50,7 @@
<Version>13.0.2</Version>
</PackageReference>
<PackageReference Include="Unity">
<Version>5.11.10</Version>
<Version>5.11.9</Version>
</PackageReference>
<PackageReference Include="Unity.Configuration">
<Version>5.11.2</Version>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment