Exemple #1
0
        /// <summary>
        /// Прочитать пакет данных
        /// </summary>
        /// <returns>Полученные данные</returns>
        public byte[] Read(int Timeout)
        {
            int cntr = 0;

            while (PackFIFO.Count == 0)
            {
                if (Timeout > 0)
                {
                    Task.Delay(10).GetAwaiter().GetResult();
                    if (cntr >= Timeout)
                    {
                        throw new BinExchange_TimeoutException("Timeout error");
                    }
                    cntr += 10;
                }
            }


            BinExchangePackage ret = PackFIFO.Dequeue();

            if (ret.Status == BinExchangePackage.StatusCodes.OK)
            {
                return(ret.Data);
            }
            else
            {
                throw new BinExchange_Exception("CRC error");
            }
        }
Exemple #2
0
        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();
                }
            }
        }
Exemple #3
0
        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);
        }