private void TimerElaped_CheckPendingChannel(object sender, System.Timers.ElapsedEventArgs e) { bTimerInElapesing = true; List <WaitingForConfirm> cPendingChannel = WaitingForConfirmList.Instance().GetPendingChannelList(); string str_log1 = ""; for (int i = cPendingChannel.Count - 1; i >= 0; --i) { if (cPendingChannel[i].CheckTimeOut()) { // reset channel ResetChannel resetChannel = new ResetChannel(RestDataGridViewRows); dataGridView_channel.Invoke(resetChannel, cPendingChannel[i].Getchannel(), "超时:无回应!"); str_log1 += "通道【" + cPendingChannel[i].Getchannel().ToString() + "】:等待下位机回应超时!!!!\r\n"; // remove WaitingForConfirmList.Instance().RemovePendingChannel(i); } } // write log if ("" != str_log1) { str_log1 += "\r\n"; WriteTerminatorLog Log_delegate1 = new WriteTerminatorLog(WriteLog); terminator.Invoke(Log_delegate1, str_log1); } // time elpesed end bTimerInElapesing = false; }
private void SendSingleChannel_button_click(object ob, DataGridViewCellEventArgs e) { if ("operation" == dataGridView_channel.Columns[e.ColumnIndex].Name) { //dataGridView_channel.Rows[e.ColumnIndex]; //MessageBox.Show(Convert.ToString("voltage:" + dataGridView_channel.Rows[e.RowIndex].Cells[2].Value) + ". row index" + e.RowIndex.ToString()); if (null == cSerialPort || false == cSerialPort.IsOpen) { MessageBox.Show("请先打开串口!"); } else { List <WaitingForConfirm> cPendingChannel = WaitingForConfirmList.Instance().GetPendingChannelList(); // check channel state, if the channel is waiting for respone, not send data for (int i = 0; i < cPendingChannel.Count; ++i) { // row index + 1 is the channel number if ((byte)(e.RowIndex + 1) == cPendingChannel[i].Getchannel()) { // write log terminator.AppendText(DateTime.Now.ToLongTimeString() + ": 通道【" + cPendingChannel[i].Getchannel().ToString() + "】发送失败: 原因是正在等待下位机回应!\r\n\r\n"); return; } } string sender_data = dataGridView_channel.Rows[e.RowIndex].Cells[2].Value.ToString(); List <RowInfo> SendList = new List <RowInfo>(); RowInfo rowInfo = new RowInfo(); rowInfo.iRowIndex = e.RowIndex; rowInfo.strUserPutIn = sender_data; SendList.Add(rowInfo); if (!cSendChannel.InitialMultiRows(cSerialPort, SendList)) { MessageBox.Show("发送串口忙,请稍后重试!"); return; } Thread SendingThread = new Thread(cSendChannel.SendMultiRows); SendingThread.Start(); } } }
private void Serial_ReceiveData(object Sender, SerialDataReceivedEventArgs Event) { if (bPrepareCloseMainWindow) { return; } bIsInReceiving = true; int iDataByteToRead = cSerialPort.BytesToRead; byte[] readbuff = new byte[iDataByteToRead]; int iActReadBytes = cSerialPort.Read(readbuff, 0, iDataByteToRead); receivebuff.AddRange(readbuff); //int iOneFrameByte = 8; byte STOP_BYTE = 0x16; int STOP_BYTE_index = ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES - 1; // 已经考虑了一个前导符 int iCS_Byte_Index = STOP_BYTE_index - 1; while (receivebuff.Count >= ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES) // (FE) FE 68H CHANNEL CONTROL DATA*4 CS STOP { // Check data effect int iStartIndex = 0; // find the start byte with 0xFE 0x68H bool bFindStart = false; for (int i = 0; i + 1 < receivebuff.Count; ++i) { // find start index if (0xFE == receivebuff[i] && 0x68 == receivebuff[i + 1]) { iStartIndex = i; // FE 68 的位置 bFindStart = true; break; } } if (bFindStart) { receivebuff.RemoveRange(0, iStartIndex); // 0: FE, 1:68H // check date count after remove useless byte if (ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES > receivebuff.Count) // +1 是只起始符前面的一个FE,代表68H 是紧跟这前导符的 { // the data not receive enought, waiting for next receive break; } // calculate crs byte byCS = 0; for (int i = 1; i < iCS_Byte_Index; ++i) { byCS += receivebuff[i]; } // check CRS and stop byte if ((byCS != receivebuff[iCS_Byte_Index]) || (STOP_BYTE != receivebuff[STOP_BYTE_index])) { // CRS is failed or not find stop byte // remove start position, drop this frame data // write log byte[] byte_log2 = new byte[ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES]; receivebuff.CopyTo(0, byte_log2, 0, ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES); string str_log2 = "和校验失败【应为0x" + byCS.ToString("X2") + "】,或停止位【应为0x" + STOP_BYTE.ToString("X2") + "】错误,丢弃! 接收数据:\r\n" + ChangeArrayToHexString(byte_log2) + "\r\n\r\n"; WriteTerminatorLog Log_delegate2 = new WriteTerminatorLog(WriteLog); terminator.Invoke(Log_delegate2, str_log2); receivebuff.RemoveRange(0, 2); continue; } // get control byte byte control = receivebuff[3]; // data from MEU to PC(bit7 = 1) and the data is ACK if ((0 == (control & 0x80)) || (0x2 != (control & 0x60) >> 5)) { // the control byte check fail // remove start position, drop this frame data // write log byte[] byte_log1 = new byte[ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES]; receivebuff.CopyTo(0, byte_log1, 0, ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES); string str_log1 = "控制位【0x" + control.ToString("X2") + "】校验失败,丢弃! 接收数据:\r\n" + ChangeArrayToHexString(byte_log1) + "\r\n\r\n"; WriteTerminatorLog Log_delegate1 = new WriteTerminatorLog(WriteLog); terminator.Invoke(Log_delegate1, str_log1); receivebuff.RemoveRange(0, 2); continue; } // here, the effect data get: FE 68H channel control byte_data*4 cs stop byte channel = receivebuff[2]; byte[] voltage = new byte[4]; receivebuff.CopyTo(4, voltage, 0, 4); // write log double fVoltage = (double)voltage[0]; // calculate decimal fVoltage += (double)(((int)voltage[1] << 16) | ((int)voltage[2] << 8) | ((int)voltage[3])) / 0xFFFFFF; byte[] byte_log = new byte[ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES]; receivebuff.CopyTo(0, byte_log, 0, ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES); string str_log = "通道【" + channel.ToString() + "】接受数据-> 电压【" + fVoltage.ToString("F2") + "】" + ChangeArrayToHexString(byte_log) + "\r\n"; bool bFindPendingChannel = false; List <WaitingForConfirm> cPendingChannel = WaitingForConfirmList.Instance().GetPendingChannelList(); for (int i = cPendingChannel.Count - 1; i >= 0; --i) { if (cPendingChannel[i].CheckRecieveChannel_ACK(channel, voltage)) { // set row to ResetChannel resetChannel = new ResetChannel(RestDataGridViewRows); dataGridView_channel.Invoke(resetChannel, channel, "设置完成"); str_log += "通道【" + channel.ToString() + "】设置完成!!\r\n\r\n"; bFindPendingChannel = true; // remove pengding channel WaitingForConfirmList.Instance().RemovePendingChannel(i); } } if (!bFindPendingChannel) { str_log += "通道【" + channel.ToString() + "】-> 数据无效,可能原因为:数据返回超时!\r\n\r\n"; } WriteTerminatorLog Log_delegate = new WriteTerminatorLog(WriteLog); terminator.Invoke(Log_delegate, str_log); // remove one frame from revieve buff and the pre byte(FE) receivebuff.RemoveRange(0, ONE_FRAME_BYTES_WITH_ONE_PRE_BYTES); } else { receivebuff.RemoveRange(0, receivebuff.Count - 1); // leave last byte data } } bIsInReceiving = false; }