/// <summary> /// Прочитать пакет данных /// </summary> /// <returns>Полученные данные</returns> public byte[] Read(int Timeout) { int cntr = 0; while (PackFIFO.Count == 0) { System.Threading.Thread.Sleep(1); if (Timeout > 0) { if (cntr >= Timeout) { throw new BinExchange_TimeoutException("Timeout error"); } cntr++; } } BinExchangePackage ret = PackFIFO.Dequeue(); if (ret.Status == BinExchangePackage.StatusCodes.OK) { return(ret.Data); } else { throw new BinExchange_Exception("CRC error"); } }
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { byte[] data = new byte[_serialPort.BytesToRead]; _serialPort.Read(data, 0, data.Length); for (int i = 0; i < data.Length; i++) { BinExchangePackage d = protocol.Parse(data[i]); if (d != null) { PackFIFO.Enqueue(d); DataReceived?.Invoke(); } } }
public BinExchangePackage Parse(byte ch) { BinExchangeChar dta = GetByte(ch); switch (state) { case States.MAIN: //ищем начало пакета if (dta.Start) //если нашли начало пакета { pack = new BinExchangePackage(); DataCounter = 0; state = States.GET_HEADER; } break; /////////////////////////// case States.GET_HEADER: //Читаем заголовок if (dta.CharDetect) //если прочли символ { if (DataCounter == 0) //если читаем 1-й байт { pack.Len = dta.Ch; DataCounter++; } else { pack.Len |= (UInt16)(dta.Ch << 8); DataCounter = 0; if (pack.Len > max_len) //пакет слишком большой { DropsIncr(); pack.Status = BinExchangePackage.StatusCodes.PACK_TOO_LONG; state = States.MAIN; return(pack); } else if (pack.Len > 0) //если пакет не пустой { pack.Data = new byte[pack.Len]; state = States.GET_DATA; } else { state = States.GET_CRC; } } } else if (dta.Start) //если обнаружили начало пакета, хотя тут должен быть заголовок { DropsIncr(); //начинаем сначала pack = new BinExchangePackage(); DataCounter = 0; state = States.GET_HEADER; } break; /////////////////////////// case States.GET_DATA: //Читаем данные if (dta.CharDetect) //если прочли символ { pack.Data[DataCounter] = dta.Ch; DataCounter++; if (DataCounter >= pack.Len) //если прочли все { DataCounter = 0; state = States.GET_CRC; } } else if (dta.Start) //если обнаружили начало пакета, хотя тут должны быть данные { DropsIncr(); //начинаем сначала pack = new BinExchangePackage(); DataCounter = 0; state = States.GET_HEADER; } break; /////////////////////////// case States.GET_CRC: //принимаем CRC if (dta.CharDetect) //если прочли символ { if (DataCounter == 0) //если читаем 1-й байт { pack.crc16 = dta.Ch; DataCounter++; } else { pack.crc16 |= (UInt16)(dta.Ch << 8); DataCounter = 0; ///// ToDo: добавить ошибку CRC //Проверяем CRC if (Crc16(pack.Data, pack.Len) == pack.crc16) { state = States.MAIN; pack.Status = BinExchangePackage.StatusCodes.OK; return(pack); } else { DropsIncr(); pack.Status = BinExchangePackage.StatusCodes.CRC_ERROR; state = States.MAIN; return(pack); } } } else if (dta.Start) //если обнаружили начало пакета, хотя тут должен быть заголовок { DropsIncr(); //начинаем сначала pack = new BinExchangePackage(); DataCounter = 0; state = States.GET_HEADER; } break; } return(null); }