话不多说,直接上代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms.VisualStyles;namespace DeviceControl { /// <summary> /// 锐捷 RJ68XX /// </summary> public class RjTester { public RjTester() { } // 波特率:4800、 9600、 19200、 38400 起始位:1 数据位:8 停止位:1 奇偶校验位:无校验 public SerialCom serialCom = new SerialCom(); private static readonly object dataRJLock = new object(); #region 命令格式 /// <summary> /// 从机地址 /// </summary> private byte slaveAddr = 0x02; public byte SlaveAddr { get => slaveAddr; set { slaveAddr = value; InitCmd(); } } private readonly byte[] EndMark = new byte[] { 0x7D };//下传命令数据格式-帧尾 /// <summary> /// 启动当前组测试 /// </summary> private RjCmd cmdStart; /// <summary> /// 启动当前组测试OK /// </summary> private RjCmd cmdStartOK;//接收到的OK命令 /// <summary> /// 停止(相当于停止键) /// </summary> private RjCmd cmdStop; /// <summary> /// 停止OK /// </summary> private RjCmd cmdStopOK; /// <summary> /// 读取测试数据及结果 执行状态:测试﹑测试结束、报警 /// </summary> private RjCmd cmdReadData; // <summary> /// 设置测试数据OK 执行状态:测试﹑测试结束、报警 /// </summary> private RjCmd cmdSetOK; private void InitCmd() { cmdStart = new RjCmd(slaveAddr, 0x0F, 0xFF); cmdStartOK = new RjCmd(slaveAddr, 0x0F, 0xFF, new byte[] { 0x00 }); cmdStop = new RjCmd(slaveAddr, 0x0F, 0x00); cmdStopOK = new RjCmd(slaveAddr, 0x0F, 0x00, new byte[] { 0x00 }); cmdReadData = new RjCmd(slaveAddr, 0xF0, 0x01); cmdSetOK = new RjCmd(slaveAddr, 0x5A, 0x01, new byte[] { 0x00 }); } /// <summary> /// 启动某组测试 /// </summary> private RjCmd cmdStartGroup; /// <summary> /// 启动当前组测试OK 从机帧 正确应答帧 /// </summary> private RjCmd cmdStartGroupOK;//接收到的OK命令 #endregion #region 读写操作 /// <summary> /// 测试:启动当前组测试、指定组测试 /// </summary> /// <param name="readValues"></param> /// <param name="readDelay"></param> /// <param name="GroupNo">指定组 第01~30组</param> /// <returns></returns> public ComResult ReadData(out RjReadValues readValues, int readDelay, int GroupNo = -1) { lock (dataRJLock)//ReadData { if (GroupNo > -1) { byte groupNo = Convert.ToByte(GroupNo - 1); cmdStartGroup = new RjCmd(slaveAddr, 0x0F, 0xEE, new byte[] { groupNo }); serialCom.SendData(cmdStartGroup.CmdBytes, out _, EndMark, 1000); } else { serialCom.SendData(cmdStart.CmdBytes, out _, EndMark, 1000); } AppDoEventDelay(readDelay); ComResult result = serialCom.SendData(cmdReadData.CmdBytes, out byte[] recvBytes, EndMark, 1000); readValues = new RjReadValues(); if (result == ComResult.OK && recvBytes != null) { if (recvBytes.Length == 0x80) { //组号 readValues = new RjReadValues(); readValues.GroupNo = recvBytes[6]; #region 读取1-8项数据 for (int i = 0; i < 8; i++) { RjReadDataItem tmpItem = readValues.RjReadDataItems[i]; byte[] tmpBytes = new byte[14]; Array.Copy(recvBytes, 7 * (i + 1), tmpBytes, 0, 14); tmpItem.No = tmpBytes[0];//序号 tmpItem.Item = (EmItem)tmpBytes[1];//项目 if (tmpItem.Item == EmItem.绝缘 | tmpItem.Item == EmItem.耐压 | tmpItem.Item == EmItem.直耐) { double multiple = 1; switch (tmpItem.Item) { case EmItem.绝缘: multiple = 10;// 电阻/10 break; case EmItem.耐压: multiple = 100;//电流/100 break; case EmItem.直耐: multiple = 1000;//电流/1000 break; } tmpItem.V = DataConvert.BytesToInt16R(tmpBytes, 2);//电压 tmpItem.IR = DataConvert.BytesToInt32R(tmpBytes, 4) / multiple; tmpItem.Time = DataConvert.BytesToInt16R(tmpBytes, 10) / 10D;//时间 tmpItem.Result = tmpBytes[13];//结果 readValues.RjReadDataItems[i] = tmpItem; } } #endregion //项目测试结果字节 1 字节 0~4 位分别对应接地,绝缘,耐压,直耐项的测试结果,1 合格,0 不合格 readValues.ProjectTest_Result = recvBytes[119]; //组测试结论 0x01 组合格 0x02 不合格 readValues.GroupTest_Result = recvBytes[121]; if (readValues.VaulesIsAllZero()) return ComResult.ZeroValue; } else { Log.WriteAsync($"耐压测试仪:读取数据失败,原因:数据长度不符", EmLogType.AppLog); return ComResult.FormatError; } } else { Log.WriteAsync($"耐压测试仪:读取数据失败,原因:{result}", EmLogType.AppLog); } CommonFunc.AppDoEventDelay(30);//发送停止命令前等待,不等待有可能发送的命令不生效。 serialCom.SendData(cmdStop.CmdBytes); return result; } } /// <summary> ///设置测试条件 /// </summary> public FBResult WriteSet(in RjSetValues setVaules) { FBResult fbResult = new FBResult(false, ""); var cmdPam = setVaules.ToBytes(); RjCmd cmdSet = new RjCmd(slaveAddr, 0x5A, 0x01, cmdPam); lock (dataRJLock)//WriteSet { ComResult comResult = serialCom.SendData(cmdSet.CmdBytes, out byte[] recvBytes, EndMark, 500); Log.Write(DataConvert.HexBytesToString(cmdSet.CmdBytes), EmLogType.AppLog); if (comResult == ComResult.OK) { if (CommonFunc.BytesIsEquals(cmdSetOK.CmdBytes, recvBytes)) { fbResult.Result = true; } else { fbResult.Result = false; fbResult.Reason = "设置锐捷测试仪参数失败"; } } else { fbResult.Result = false; fbResult.Reason = comResult.ToString(); } return fbResult; } } /// <summary> /// 发送停止指令 /// </summary> /// <returns></returns> public bool SendStop() { lock (dataRJLock)//SendStop { bool result = false; ComResult comResult = serialCom.SendData(cmdStop.CmdBytes, out byte[] recvBytes, EndMark, 500); if (comResult == ComResult.OK) { if (recvBytes.Length==9 & recvBytes[5]==0x00) { result = true; } else { result = false; } } else { result = false; } return result; } } #endregion /// <summary> /// 发送心跳 /// </summary> /// <returns>接收到OK返回TRUE,否则返回False</returns> public bool SendHeart() { bool result = false; if ((DateTime.Now - serialCom.LastRecvTime).TotalSeconds < 10)//RJ 10秒内有收到数据,直接返回true { result = true; return result; } result = SendStop(); return result; } } #region Model /// <summary> /// 命令 /// </summary> internal struct RjCmd { /// <summary> /// /// </summary> /// <param name="slaveAddr">从机地址</param> /// <param name="cmdType">命令类型</param> /// <param name="cmd">命令字</param> /// <param name="param">参数</param> internal RjCmd(byte slaveAddr, byte cmdType, byte cmd, byte[] param = null) { length = new byte[2]; checksum = 0x00; this.slaveAddr = slaveAddr; this.cmdType = cmdType; this.cmd = cmd; this.param = param; CmdBytes = null; GetCmdBytes(); } /// <summary> /// 帧头 /// </summary> private const byte head = 0x7B; /// <summary> /// 帧尾 /// </summary> private const byte end = 0x7D; /// <summary> /// 从机地址 /// </summary> private byte slaveAddr; /// <summary> /// 总字节 /// </summary> private byte[] length; /// <summary> /// 校验和 /// </summary> private byte checksum; /// <summary> /// 命令类型 /// </summary> private byte cmdType; /// <summary> /// 命令字 /// </summary> private byte cmd; /// <summary> /// 参数 /// </summary> private byte[] param; /// <summary> /// 命令 byte[] /// </summary> internal byte[] CmdBytes; internal void GetCmdBytes() { IEnumerable<byte> bytes; byte[] tmp = { head }; bytes = tmp.Concat(length); bytes = bytes.Append(slaveAddr); bytes = bytes.Append(cmdType); bytes = bytes.Append(cmd); if (param?.Length > 0) bytes = bytes.Concat(param); bytes = bytes.Append(checksum); bytes = bytes.Append(end); CmdBytes = bytes.ToArray(); //长度 length = BitConverter.GetBytes((short)CmdBytes.Length); CmdBytes[1] = length[1]; CmdBytes[2] = length[0]; //是对所发送数据校验的结果。校验采用水平校验,即有效字节数 + 从机地址 + 命令 + 参数 的和,长度为双字节,取低位字节为校验和 int sum_all = 0; for (int i = 1; i <= CmdBytes.Length - 3; i++) { sum_all += CmdBytes[i]; } checksum = (byte)(sum_all & 0xFF); CmdBytes[CmdBytes.Length - 2] = checksum; } } public enum EmItem { Null = 0, 绝缘 = 2, 耐压 = 3, 直耐 = 7, } public struct RjSetDataItem { /// <summary> /// 序号: 1-8 /// </summary> public int No; /// <summary> /// 项目:0空 2绝缘 3耐压 7直耐 /// </summary> public EmItem Item; /// <summary> /// 绝缘测试 设置: 电压值 25V~3000V /// 耐压 测试条件: 电压值 范围:50~5000VAC;最小步幅:1V。 /// 直耐 测试条件: 电压值 50~6000VDC;最小步幅:1V。 /// </summary> public int V; /// <summary> /// 绝缘 上限: 电阻值 *10 范围: 0~99.9 MΩ,100~50000MΩ,0 MΩ 表示取消上限设置最小步幅:0.1 MΩ,1 MΩ /// 耐压 上限: 电流值 *100 范围:0.00~40.00mA最小步幅:0.01mA /// 直耐 上限: 电流值*1000 范围:0.000~9.999mA 最小步幅:0.001mA /// </summary> public double IR_Up; ///<summary> ///绝缘 下限: 电阻值 *10 范围:0.3~99.9 MΩ,100~50000MΩ 最小步幅:0.1 MΩ,1 MΩ /// 耐压 下限: 电流值 *100 范围:0.00~40.00mA最小步幅:0.01mA /// 直耐 下限: 电流值*1000 范围:0.000~9.999mA 最小步幅:0.001mA /// </summary> public double IR_Low; /// <summary> /// 绝缘 测试时间 *10 范围:1.0~999.9s 最小步幅:0.1s /// 耐压 测试时间 *10 范围:1.0~999.9s最小步幅:0.1s /// 直耐 测试时间 *10 /// </summary> public double Time; public byte[] ToBytes() { byte[] resByte = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; resByte[0] = Convert.ToByte(No);//序号 resByte[1] = (byte)Item ;//项目 if (Item == EmItem.绝缘 | Item == EmItem.耐压 | Item == EmItem.直耐) { double multiple = 1; switch (Item) { case EmItem.绝缘: multiple = 10;//电阻x10 break; case EmItem.耐压: multiple = 100;//电流x100 break; case EmItem.直耐: multiple = 1000;//电流x1000 break; } byte[] bVoltage = DataConvert.Int16ToBytesR((short)V);//电压 byte[] bValue_Low = DataConvert.Int32ToBytesR((int)(IR_Low * multiple)); byte[] bValue_Up = DataConvert.Int32ToBytesR((int)(IR_Up * multiple)); byte[] bTime = DataConvert.Int16ToBytesR((short)(Time * 10));//时间; resByte[2] = bVoltage[0]; resByte[3] = bVoltage[1]; resByte[4] = bValue_Low[0]; resByte[5] = bValue_Low[1]; resByte[6] = bValue_Low[2]; resByte[7] = bValue_Low[3]; resByte[8] = bValue_Up[0]; resByte[9] = bValue_Up[1]; resByte[10] = bValue_Up[2]; resByte[11] = bValue_Up[3]; resByte[12] = bTime[0]; resByte[13] = bTime[1]; //备用 //resByte[14] = 0x00; } return resByte; } } /// <summary> /// 设置命令值结构 /// </summary> public class RjSetValues { /// <summary> /// 组号 0-29 /// </summary> public byte GroupNo; public RjSetDataItem[] SetDataItems = new RjSetDataItem[8];//第 1 - 8 项设置数据 public byte Err;//遇失败步 1 字节 00 继续 01 停止 public byte ACoffset;//交耐补偿 1 字节 00 关 01 开 public byte DCoffset;//直耐补偿 1 字节 00 关 01 开 public double Time1;//绝缘延判 2 字节 *10s public double Time2;//交耐缓升 2 字节 *10s public double Time3;//交耐缓降 2 字节 *10s public double Time4;//直耐延判 2 字节 *10s public double Time5;//直耐缓升 2 字节 *10s public double Time6;//直耐缓降 2 字节 *10s public double Reserve;//备用 /// <summary> /// 仪器设置频率:0 1 /// </summary> public byte Hz; /// <summary> /// 仪器设置频率:50 60 /// </summary> public int HzNum { get { return (Hz == 0 ? 50 : 60); } set { if (value == 50) Hz = 0; else if (value == 60) Hz = 1; } } public byte[] ToBytes() { byte[] bytes = new byte[1 + (15 * 8) + 18]; bytes[0] = GroupNo; //组号 for (int i = 0; i < 8; i++)//1-8项数据 { byte[] itemdata = SetDataItems[i].ToBytes(); Array.Copy(itemdata, 0, bytes, 1 + (15 * i), itemdata.Length); } int num = 1 + (15 * 8); bytes[num + 0] = Err;//遇失败步00 继续 01 停止 bytes[num + 1] = Hz; bytes[num + 2] = ACoffset; bytes[num + 3] = DCoffset; var tmpBytes1 = DataConvert.Int16ToBytesR((short)(Time1 * 10)); bytes[num + 4] = tmpBytes1[0]; bytes[num + 5] = tmpBytes1[1]; var tmpBytes2 = DataConvert.Int16ToBytesR((short)(Time2 * 10)); bytes[num + 6] = tmpBytes2[0]; bytes[num + 7] = tmpBytes2[1]; var tmpBytes3 = DataConvert.Int16ToBytesR((short)(Time3 * 10)); bytes[num + 8] = tmpBytes3[0]; bytes[num + 9] = tmpBytes3[1]; var tmpBytes4 = DataConvert.Int16ToBytesR((short)(Time4 * 10)); bytes[num + 10] = tmpBytes4[0]; bytes[num + 11] = tmpBytes4[1]; var tmpBytes5 = DataConvert.Int16ToBytesR((short)(Time5 * 10)); bytes[num + 12] = tmpBytes5[0]; bytes[num + 13] = tmpBytes5[1]; var tmpBytes6 = DataConvert.Int16ToBytesR((short)(Time6 * 10)); bytes[num + 14] = tmpBytes6[0]; bytes[num + 15] = tmpBytes6[1]; bytes[num + 16] = 0x00; bytes[num + 17] = 0x00; return bytes; } } public struct RjReadDataItem { /// <summary> /// 序号: 1-8 /// </summary> public int No; /// <summary> /// 项目:0空 2绝缘 3耐压 7直耐 /// </summary> public EmItem Item; /// <summary> /// 绝缘测试 设置: 电压值 25V~3000V /// 耐压 测试条件: 电压值 范围:50~5000VAC;最小步幅:1V。 /// 直耐 测试条件: 电压值 50~6000VDC;最小步幅:1V。 /// </summary> public int V; /// <summary> /// 绝缘 测试结果: 电阻值 *10 /// 耐压 测试结果: 电流值 *100 /// 直耐 上限: 电流值*1000 /// </summary> public double IR; /// <summary> /// 测试时间 *10 /// </summary> public double Time; /// <summary> /// 测试结果 0未判 1OK 2NG 3PT 4NG 5NG /// </summary> public int Result; } /// <summary> /// 绝缘测试数据 /// </summary> public class RjReadValues { /// <summary> /// 组号 0-29 /// </summary> public byte GroupNo; public RjReadDataItem[] RjReadDataItems = new RjReadDataItem[8];//第 1 - 8 项设置数据 /// <summary> /// 项目测试结果:0~4 位分别对应接地,绝缘,耐压,直耐项的测试结果,1 合格,0 不合格 /// </summary> public int ProjectTest_Result; /// <summary> /// 测试状态:0x01 测试中 0x02 测试结束 0x03 测试中止 /// </summary> public double Test_State; /// <summary> /// 组测试状态:0x01 组合格 0x02 不合格 /// </summary> public int GroupTest_Result; /// <summary> /// 错误代码 /// </summary> public int ErrorCode; public string ErrorCodeStr { get { switch (ErrorCode) { case 1: return "校验和错误"; case 2: return "命令类型错误"; case 3: return "命令字错误"; case 4: return "状态不符"; case 5: return "参数无效或个数不符"; default: return "ERROR"; } } } public bool VaulesIsAllZero() { bool bAllZero = true; for (int i = 0; bAllZero & i < 8; i++) { bAllZero &= (RjReadDataItems[i].V.Equals(0) & RjReadDataItems[i].IR.Equals(0) & RjReadDataItems[i].Time.Equals(0) && RjReadDataItems[i].Result.Equals(0)); } return bAllZero; } } #endregion }
下面是补充代码:
1 public struct FBResult 2 { 3 public FBResult(bool result = true, string reason = "") 4 { 5 Result = result; 6 Reason = reason; 7 Code = "S"; 8 } 9 public bool Result; 10 public string Code;//原因代码 S成功 11 public string Reason; 12 }FBResult
1 /// <summary> 2 /// 串口通讯类,适用于发送一个命令然后等待并接收返回数据。 3 /// </summary> 4 public class SerialCom 5 { 6 7 public SerialPort serialPort = new SerialPort(); 8 9 10 #region 串口打开标志 11 private bool connected = false; 12 public bool Connected 13 { 14 get 15 { 16 return serialPort.IsOpen & connected; 17 } 18 set { connected = value; } 19 } 20 #endregion 21 private int timeOut = 2000; 22 public int TimeOut 23 { 24 set { timeOut = value; } 25 get { return timeOut; } 26 } 27 /// <summary> 28 /// 最后一次接收数据的时间 29 /// </summary> 30 public DateTime LastRecvTime = DateTime.MinValue; 31 /// <summary> 32 /// 33 /// </summary> 34 private const int ComBufferSize = 256; 35 /// <summary> 36 /// 串口通讯缓存 37 /// </summary> 38 private byte[] ComBuffer = new byte[ComBufferSize]; 39 40 private const int DataBufferSize = 2048; 41 /// <summary> 42 /// 接收到的字节数 43 /// </summary> 44 private int DataBufferReadCount = 0; 45 /// <summary> 46 /// 接收到的数据缓存 47 /// </summary> 48 public byte[] DataBuffer = new byte[DataBufferSize]; 49 50 //private static readonly object dataLock = new object(); 51 private readonly object dataComLock = new object(); 52 53 public bool Open(SerialParam serialParam) 54 { 55 serialPort.PortName = serialParam.PortName; 56 serialPort.BaudRate = serialParam.BaudRate; 57 serialPort.DataBits = serialParam.DataBits; 58 serialPort.StopBits = serialParam.StopBits; 59 serialPort.Parity = serialParam.Parity; 60 serialPort.ReadTimeout = timeOut; 61 serialPort.WriteTimeout = timeOut; 62 serialPort.DataReceived -= ReceiveData; 63 serialPort.DataReceived += ReceiveData; 64 65 try 66 { 67 serialPort.Close(); 68 serialPort.Open(); 69 connected = true; 70 } 71 catch (Exception ex) 72 { 73 Log.Write($"串口{serialPort.PortName}打开失败,原因:{ex.Message}", EmLogType.ErrorLog); 74 return false; 75 } 76 return true; 77 } 78 public void Close() 79 { 80 if (serialPort.IsOpen) 81 { 82 serialPort.Close(); 83 connected = false; 84 } 85 } 86 87 /// <summary> 88 /// 串口接收数据 89 /// </summary> 90 /// <param name="sender"></param> 91 /// <param name="e"></param> 92 private void ReceiveData(object sender, SerialDataReceivedEventArgs e) 93 { 94 LastRecvTime = DateTime.Now; 95 96 Array.Clear(ComBuffer, 0, ComBufferSize); 97 if (DataBufferReadCount > DataBufferSize - ComBufferSize)//缓存超过最大值,清理缓存 98 { 99 ClearDataBuffer(); 100 } 101 try 102 { 103 //当次接收的数据放入DataBuffer缓存中 104 //if (serialPort.BytesToRead > 0) 105 //{ 106 int readLength = serialPort.Read(ComBuffer, 0, ComBufferSize); 107 Array.Copy(ComBuffer, 0, DataBuffer, DataBufferReadCount, readLength); 108 DataBufferReadCount += readLength; 109 //} 110 } 111 catch (Exception ex) 112 { 113 Log.Write($"串口{serialPort.PortName}接收数据报错,原因:{ex.Message}", EmLogType.ErrorLog); 114 } 115 116 } 117 /// <summary> 118 /// 清除串口接收到的数据缓存 119 /// </summary> 120 private void ClearDataBuffer() 121 { 122 Array.Clear(DataBuffer, 0, DataBufferSize); 123 DataBufferReadCount = 0; 124 125 } 126 /// <summary> 127 /// 发送数据 128 /// </summary> 129 /// <param name="sendBytes"></param> 130 /// <returns></returns> 131 public ComResult SendData(byte[] sendBytes) 132 { 133 if (!Connected) 134 return ComResult.DisConnected; 135 lock (dataComLock) 136 { 137 ClearDataBuffer(); 138 try 139 { 140 serialPort.Write(sendBytes, 0, sendBytes.Length); 141 } 142 catch 143 { 144 return ComResult.DisConnected; 145 } 146 } 147 return ComResult.OK; 148 } 149 150 /// <summary> 151 /// 发送数据并接收返回的数据(指定长度) 152 /// </summary> 153 /// <param name="sendBytes"></param> 154 /// <param name="recvBytes">返回数据</param> 155 /// <param name="recvBytesLength">返回数据长度</param> 156 /// <param name="waitTime">等待时间</param> 157 /// <returns></returns> 158 public ComResult SendData(byte[] sendBytes, out byte[] recvBytes, int recvBytesLength = 0, int waitTime = 3000) 159 { 160 recvBytes = new byte[recvBytesLength]; 161 if (!Connected) 162 return ComResult.DisConnected; 163 lock (dataComLock) 164 { 165 try 166 { 167 ClearDataBuffer(); 168 serialPort.Write(sendBytes, 0, sendBytes.Length); 169 DateTime dtStart = DateTime.Now; 170 while (DataBufferReadCount < recvBytesLength) 171 { 172 if ((DateTime.Now - dtStart).TotalMilliseconds > waitTime) 173 { 174 return ComResult.OverTime; 175 } 176 CommonFunc.AppDoEventDelay(5); 177 } 178 Array.Copy(DataBuffer, 0, recvBytes, 0, recvBytesLength); 179 } 180 catch 181 { 182 return ComResult.DisConnected; 183 } 184 } 185 return ComResult.OK; 186 } 187 /// <summary> 188 /// 发送数据并接收返回的数据(指定结束符) 189 /// </summary> 190 /// <param name="sendBytes"></param> 191 /// <param name="recvBytes">返回数据</param> 192 /// <param name="endBytes">结束字节</param> 193 /// <param name="waitTime">等待时间</param> 194 /// <returns></returns> 195 public ComResult SendData(byte[] sendBytes, out byte[] recvBytes, byte[] endBytes, int waitTime = 3000) 196 { 197 recvBytes = null; 198 if (!Connected) 199 { 200 return ComResult.DisConnected; 201 } 202 lock (dataComLock) 203 { 204 ComResult comResult = ComResult.OK; 205 try 206 { 207 ClearDataBuffer(); 208 serialPort.Write(sendBytes, 0, sendBytes.Length); 209 byte[] tmpBytes = new byte[endBytes.Length]; 210 DateTime dtStart = DateTime.Now; 211 while (true) 212 { 213 if (DataBufferReadCount >= endBytes.Length) 214 Array.Copy(DataBuffer, DataBufferReadCount - endBytes.Length, tmpBytes, 0, endBytes.Length); 215 if (CommonFunc.BytesIsEquals(endBytes, tmpBytes)) 216 break; 217 if ((DateTime.Now - dtStart).TotalMilliseconds > waitTime) 218 { 219 comResult = ComResult.OverTime; 220 break; 221 } 222 CommonFunc.AppDoEventDelay(5); 223 } 224 recvBytes = new byte[DataBufferReadCount]; 225 Array.Copy(DataBuffer, 0, recvBytes, 0, recvBytes.Length); 226 } 227 catch 228 { 229 comResult = ComResult.UnkownError; 230 } 231 return comResult; 232 } 233 } 234 235 /// <summary> 236 /// 发送数据并接收返回的数据(指定结束符) 杨子绝缘测试仪测试结果上传ON 237 /// </summary> 238 /// <param name="sendBytes"></param> 239 /// <param name="recvBytes">返回数据</param> 240 /// <param name="endBytes">结束字节</param> 241 /// <param name="waitTime">等待时间</param> 242 /// <returns></returns> 243 public ComResult SendData1(byte[] sendBytes, out byte[] recvBytes, byte[] endBytes, int waitTime = 3000) 244 { 245 recvBytes = null; 246 if (!Connected) 247 { 248 return ComResult.DisConnected; 249 } 250 lock (dataComLock) 251 { 252 ComResult comResult = ComResult.OK; 253 try 254 { 255 ClearDataBuffer(); 256 serialPort.Write(sendBytes, 0, sendBytes.Length); 257 byte[] tmpBytes = new byte[endBytes.Length]; 258 DateTime dtStart = DateTime.Now; 259 while (true) 260 { 261 //if (DataBufferReadCount >= endBytes.Length) 262 if (DataBufferReadCount >20) 263 Array.Copy(DataBuffer, DataBufferReadCount - endBytes.Length, tmpBytes, 0, endBytes.Length); 264 if (CommonFunc.BytesIsEquals(endBytes, tmpBytes)) 265 break; 266 if ((DateTime.Now - dtStart).TotalMilliseconds > waitTime) 267 { 268 comResult = ComResult.OverTime; 269 break; 270 } 271 CommonFunc.AppDoEventDelay(5); 272 } 273 274 recvBytes = new byte[DataBufferReadCount]; 275 Array.Copy(DataBuffer, 0, recvBytes, 0, recvBytes.Length); 276 } 277 catch 278 { 279 comResult = ComResult.UnkownError; 280 } 281 return comResult; 282 } 283 284 } 285 286 287 288 /// <summary> 289 /// 发送数据并接收返回的数据(指定长度) 290 /// </summary> 291 /// <param name="sendStr"></param> 292 /// <param name="recvStr">返回数据</param> 293 /// <param name="recvStrLength">返回数据长度</param> 294 /// <param name="waitTime">等待时间</param> 295 /// <returns></returns> 296 public ComResult SendData(string sendStr, out string recvStr, int recvStrLength = 0, int waitTime = 3000) 297 { 298 recvStr = null; 299 var sendBytes = Encoding.ASCII.GetBytes(sendStr); 300 var recvBytesLength = recvStrLength;//1个ASCII字符等于1字节 301 ComResult comResult = SendData(sendBytes, out byte[] recvBytes, recvBytesLength, waitTime); 302 if (comResult == ComResult.OK) 303 { 304 recvStr = Encoding.ASCII.GetString(recvBytes); 305 } 306 return comResult; 307 } 308 /// <summary> 309 /// 发送数据并接收返回的数据(指定结束符) 310 /// </summary> 311 /// <param name="sendStr"></param> 312 /// <param name="recvStr">返回数据</param> 313 /// <param name="endMark">结束符</param> 314 /// <param name="waitTime">等待时间</param> 315 /// <returns></returns> 316 public ComResult SendData(string sendStr, out string recvStr, string endMark, int waitTime = 3000) 317 { 318 recvStr = null; 319 var sendBytes = Encoding.ASCII.GetBytes(sendStr); 320 var endBytes = Encoding.ASCII.GetBytes(endMark); 321 ComResult comResult = SendData(sendBytes, out byte[] recvBytes, endBytes, waitTime); 322 if (comResult == ComResult.OK) 323 { 324 recvStr = Encoding.ASCII.GetString(recvBytes); 325 } 326 return comResult; 327 } 328 /// <summary> 329 /// 发送数据 330 /// </summary> 331 /// <param name="sendStr"></param> 332 /// <returns></returns> 333 public ComResult SendData(string sendStr) 334 { 335 var sendBytes = Encoding.ASCII.GetBytes(sendStr); 336 return SendData(sendBytes); 337 338 } 339 }SerialCom
1 public enum ComResult 2 { 3 OK = 1, 4 DisConnected = 2, 5 FormatError = 3, 6 ZeroValue = 4, 7 UnkownError = 5, 8 OverTime = 6 9 }ComResult
1 /// <summary> 2 /// 等待延时 3 /// </summary> 4 /// <param name="timeout">等待时间</param> 5 /// <returns></returns> 6 public static void AppDoEventDelay(int timeout) 7 { 8 DateTime start = DateTime.Now; 9 do 10 { 11 Application.DoEvents(); 12 } while ((DateTime.Now - start).TotalMilliseconds < timeout); 13 }AppDoEventDelay
数据转换使用的DataConvert:
1 public static class DataConvert 2 { 3 4 #region default 5 6 public static string ArrayToString<T>(T[] array) 7 { 8 StringBuilder builder = new StringBuilder(); 9 builder.Append("["); 10 for (int i = 0; i < array.Length; i++) 11 { 12 builder.Append($"{array[i]},"); 13 } 14 if (builder[builder.Length - 1] == ',') 15 builder.Remove(builder.Length - 1, 1);//去掉最后的, 16 builder.Append("]"); 17 return builder.ToString(); 18 } 19 public static string ListToString<T>(List<T> list) 20 { 21 StringBuilder builder = new StringBuilder(); 22 builder.Append("["); 23 for (int i = 0; i < list.Count; i++) 24 { 25 builder.Append($"{list[i]},"); 26 } 27 if (builder[builder.Length - 1] == ',') 28 builder.Remove(builder.Length - 1, 1);//去掉最后的, 29 builder.Append("]"); 30 return builder.ToString(); 31 } 32 /// <summary> 33 /// bytes转换成ascii字符串 34 /// [0x0C,0X64]转换成0C64 35 /// </summary> 36 /// <param name="bytes"></param> 37 /// <returns></returns> 38 public static string HexBytesToString(byte[] bytes) 39 { 40 //byte[] bytes = new byte[] { 0x0C, 0x0b, 0x64, }; 41 string hexString = string.Empty; 42 if (bytes != null) 43 { 44 StringBuilder builder = new StringBuilder(); 45 for (int i = 0; i < bytes.Length; i++) 46 { 47 builder.Append(bytes[i].ToString("X2")); 48 } 49 hexString = builder.ToString(); 50 } 51 return hexString; 52 } 53 /// <summary> 54 /// ascii字符串转换成bytes 55 /// 0C64转换成[0x0C,0X64] 56 /// </summary> 57 /// <param name="hexString"></param> 58 /// <returns></returns> 59 public static byte[] StringToHexBytes(string hexString) 60 { 61 byte[] temp = new byte[1]; 62 byte[] bytes = null; 63 hexString = hexString.Replace(" ", ""); 64 //string pattern = @"\s"; 65 //string replacement = ""; 66 //System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex(pattern); 67 //string send_data = rgx.Replace(hexString, replacement); 68 if (!string.IsNullOrEmpty(hexString) && hexString.Length % 2 == 0) 69 { 70 int num = hexString.Length / 2; 71 bytes = new byte[num]; 72 for (int i = 0; i < num; i++) 73 { 74 temp[0] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); 75 bytes[i] = temp[0]; 76 } 77 } 78 return bytes; 79 } 80 81 /// <summary> 82 /// 普通字符串转换成符合CSV规范的字符串 83 /// </summary> 84 /// <param name="str"></param> 85 /// <returns></returns> 86 public static string CsvHandlerStr(string str) 87 { 88 if (str != null) 89 { 90 char[] arrChar = { '"', ',', '\r', '\n' }; 91 if (str.IndexOfAny(arrChar) > -1) 92 { 93 string tmpStr = str.Replace("\"", "\"\""); 94 return "\"" + tmpStr + "\""; 95 } 96 else 97 return str; 98 } 99 else 100 { 101 return "null"; 102 } 103 104 } 105 #endregion 106 107 #region byte[]转数字 108 109 /// <summary> 110 /// byte数组中取int数值,本方法适用于(低位在前,高位在后)的顺序 111 /// </summary> 112 /// <param name="src">byte数组 </param> 113 /// <param name="offset"> 从数组的第offset位开始 </param> 114 /// <returns>int数值</returns> 115 public static int BytesToInt32(byte[] src, int offset) 116 { 117 int value; 118 value = (int)((src[offset] & 0xFF) 119 | ((src[offset + 1] & 0xFF) << 8) 120 | ((src[offset + 2] & 0xFF) << 16) 121 | ((src[offset + 3] & 0xFF) << 24)); 122 return value; 123 } 124 125 /// <summary> 126 /// byte数组中取int数值,本方法适用于(低位在后,高位在前)的顺序 127 /// </summary> 128 /// <param name="src"></param> 129 /// <param name="offset"></param> 130 /// <returns></returns> 131 public static int BytesToInt32R(byte[] src, int offset) 132 { 133 int value; 134 value = (int)(((src[offset] & 0xFF) << 24) 135 | ((src[offset + 1] & 0xFF) << 16) 136 | ((src[offset + 2] & 0xFF) << 8) 137 | (src[offset + 3] & 0xFF)); 138 return value; 139 } 140 /// <summary> 141 /// byte数组中取short数值,本方法适用于(低位在前,高位在后)的顺序 142 /// </summary> 143 /// <param name="src"></param> 144 /// <param name="offset"></param> 145 /// <returns></returns> 146 public static short BytesToInt16(byte[] src, int offset) 147 { 148 short value; 149 value = (short)((src[offset] & 0xFF) 150 | ((src[offset + 1] & 0xFF) << 8)); 151 return value; 152 } 153 /// <summary> 154 /// byte数组中取short数值,本方法适用于(低位在后,高位在前)的顺序 155 /// </summary> 156 /// <param name="src"></param> 157 /// <param name="offset"></param> 158 /// <returns></returns> 159 public static short BytesToInt16R(byte[] src, int offset) 160 { 161 short value; 162 value = (short)(((src[offset] & 0xFF) << 8) 163 | (src[offset + 1] & 0xFF)); 164 return value; 165 } 166 167 #endregion 168 #region 数字转byte[] 169 170 /// <summary> 171 /// Int16转换成byte[] (低位在前,高位在后)的顺序 172 /// </summary> 173 /// <param name="num"></param> 174 /// <returns></returns> 175 public static byte[] Int16ToBytes(short num) 176 { 177 byte[] bytes = new byte[2]; 178 bytes[0] = (byte)(num & 0xFF); 179 bytes[1] = (byte)((num >> 8) & 0xFF); 180 return bytes; 181 } 182 183 /// <summary> 184 /// Int16转换成byte[] (低位在后,高位在前)的顺序 185 /// </summary> 186 /// <param name="num"></param> 187 /// <returns></returns> 188 public static byte[] Int16ToBytesR(short num) 189 { 190 byte[] bytes = new byte[2]; 191 bytes[0] = (byte)((num >> 8) & 0xFF); 192 bytes[1] = (byte)(num & 0xFF); 193 return bytes; 194 } 195 /// <summary> 196 /// Int32转换成byte[] (低位在前,高位在后)的顺序 197 /// </summary> 198 /// <param name="num"></param> 199 /// <returns></returns> 200 public static byte[] Int32ToBytes(int num) 201 { 202 byte[] bytes = new byte[4]; 203 bytes[0] = (byte)(num & 0xFF); 204 bytes[1] = (byte)((num >> 8) & 0xFF); 205 bytes[2] = (byte)((num >> 16) & 0xFF); 206 bytes[3] = (byte)((num >> 24) & 0xFF); 207 return bytes; 208 } 209 /// <summary> 210 /// Int32转换成byte[] (低位在后,高位在前)的顺序 211 /// </summary> 212 /// <param name="num"></param> 213 /// <returns></returns> 214 public static byte[] Int32ToBytesR(int num) 215 { 216 byte[] bytes = new byte[4]; 217 bytes[0] = (byte)((num >> 24) & 0xFF); 218 bytes[1] = (byte)((num >> 16) & 0xFF); 219 bytes[2] = (byte)((num >> 8) & 0xFF); 220 bytes[3] = (byte)(num & 0xFF); 221 return bytes; 222 } 223 224 225 #endregion 226 227 #region TryParse 228 229 public static bool ByteTryParse(string str, ref byte value) 230 { 231 if (byte.TryParse(str, out byte temp)) 232 { 233 value = temp; 234 return true; 235 } 236 else 237 return false; 238 } 239 public static bool ShortTryParse(string str, ref short value) 240 { 241 if (short.TryParse(str, out short temp)) 242 { 243 value = temp; 244 return true; 245 } 246 else 247 return false; 248 } 249 public static bool UshortTryParse(string str, ref ushort value) 250 { 251 if (ushort.TryParse(str, out ushort temp)) 252 { 253 value = temp; 254 return true; 255 } 256 else 257 return false; 258 } 259 260 public static bool IntTryParse(string str, ref int value) 261 { 262 if (int.TryParse(str, out int temp)) 263 { 264 value = temp; 265 return true; 266 } 267 else 268 return false; 269 } 270 271 public static bool FloatTryParse(string str, ref float value) 272 { 273 if (float.TryParse(str, out float temp)) 274 { 275 value = temp; 276 return true; 277 } 278 else 279 return false; 280 } 281 public static bool DoubleTryParse(string str, ref double value) 282 { 283 if (double.TryParse(str, out double temp)) 284 { 285 value = temp; 286 return true; 287 } 288 else 289 return false; 290 } 291 292 public static bool BoolTryParse(string str, ref bool value) 293 { 294 if (bool.TryParse(str, out bool temp)) 295 { 296 value = temp; 297 return true; 298 } 299 else 300 return false; 301 } 302 303 304 public static bool DateTimeTryParse(string str, ref DateTime value) 305 { 306 if (DateTime.TryParse(str, out DateTime temp)) 307 { 308 value = temp; 309 return true; 310 } 311 else 312 return false; 313 } 314 315 316 317 318 319 320 public static bool EnumTryParse<T>(string str, ref T value) where T : struct 321 { 322 if (Enum.TryParse<T>(str, out T temp)) 323 { 324 value = temp; 325 return true; 326 } 327 else 328 return false; 329 } 330 331 332 333 public static double ChangeDataToD(string strData) 334 { 335 decimal dData = 0.0M; 336 try 337 { 338 if (strData.Contains("E") || strData.Contains("e")) 339 { 340 //strData = strData.Substring(0, strData.Length - 1).Trim(); 341 dData = Convert.ToDecimal(Decimal.Parse(strData.ToString(), System.Globalization.NumberStyles.Float)); 342 } 343 else 344 { 345 dData = decimal.Parse(strData); 346 } 347 } 348 catch (Exception) 349 { 350 dData = 0; 351 352 } 353 return double.Parse(dData.ToString()); 354 } 355 356 #endregion 357 }DataConvert
关于log日志记录的代码就不贴了,可以根据项目实际情况使用log日志记录的功能。
如有疑问欢迎留言讨论
标签:石文进,return,锐捷,C#,bytes,int,new,byte,public From: https://www.cnblogs.com/chuangqing666/p/18657262