SerialPort(COM) Разрыв пакета при приеме - C#

Узнай цену своей работы

Формулировка задачи:

Вся соль в приеме данных... Настроил виртуальный порты - гоняю данные все работает идеально, пробую связать 2 машины - приходит не всЕ сообщение, а скачала кусок, потом второй кусок(пакет 15 байт). В принципе не проблема склеить пакет, но как-то не комильфо. Или так и должно быть? Могу приклеить код если нужно.
Вообщем решил вроде проблему. Оказалось что нужно просто поставить задержку. Ну и конечно обнулять буфер после приема.
//где-то в конструкторе 
 _serialPort.DataReceived += _serialPort_DataReceived;
 
 void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(15);
            ReadFromComPort();
            _serialPort.DiscardInBuffer();
        }
 public bool ReadFromComPort()
        {
            int CountReadBuf = _serialPort.BytesToRead;
            if (CountReadBuf != 0)
            {
                //MessageBox.Show("Count=" + CountReadBuf.ToString());
                byte[] ReadBuffer = new byte[CountReadBuf];
                try
                {
                    _serialPort.Read(ReadBuffer,0,CountReadBuf);
                    MessageIn.Add(new MessagePer("COM",ReadBuffer,"INPUT"));// моя обработка
                    //MessageBox.Show(String.Join(" ",MessageIn[MessageIn.Count-1].Data));
                    return true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error Read to serial port :: "
                      + ex.Message, "Error!");
                    return false;
                }
                
            }
            return false;
        }

Решение задачи: «SerialPort(COM) Разрыв пакета при приеме»

textual
Листинг программы
       public event EventHandler end_data;
       public event EventHandler get_ans_dl_point;
 
        // Для обработки данных и подключения к СОМ порту
        public void scan_ports()
        {
            while(true)
            {
                System.Threading.Thread.Sleep(65);
 
                if(!on)
                {
                    on = Scan_com_ports();
                    all_reset();
                }
                else
                {
                    id_lave = true;     // установим id_lave в true если Read_data_com не выставит в false 
                                        //то читаем дальше если нет то пытаемся сново пронюхать порты
                    
                    Read_data_com();
 
                    if (!id_lave)
                    { 
                        on = id_lave;
                        main_serial.Close();
                    }
                }
            }
        }
 
        // Обнуляем все переменные
        public void all_reset()
        {
            real_cren = 0;
            real_tangaj = 0;
            axel_x = 0;
            axel_y = 0;
            axel_z = 0;
            giro_x = 0;
            giro_y = 0;
            giro_z = 0;
            real_curs = 0;
            real_vertical_speed = 0;
            real_h = 0;
 
            rssi = -1;
            latitude = -1;
            longitude = -1;
 
            curs_gps = 0;
            h_gps = 0;
            speed_gps = 0;
            satilite_gps = -1;
 
            I_last = 0; ;
            I = 0; ;
            U = -1; ;
            U_ant = -1;
            stat_system = false;
            stat_motors = false;
            stat_load = false;
            stat_around = false;
            stat_start = false;
            stat_end = false;
            stat_stop = false;
            stat_gps = false;
            stat_home = false;
        }
 
        // Читаем наиболее актуальные данные из буфера СОМ порта
        public void Read_data_com()
        {
            try
            {
                byte[] tmp_buffer = new byte[4096];
                int size = main_serial.Read(tmp_buffer, 0, 4096);
 
 
                // Вначале оттделим команды и сохраним их в списке команд CommandList,
                // в данном списке команда с одним кодом будет в единственном экземляре
                // таким образом команда с конкретным кодом будет являться последней пришедшей с устройства, т.е. актуальной
                for (int i = 0; i < size; ++i)
                {
                    // Пытаемся поймать ответы на наши действия
                    if (i < tmp_buffer.Length - 16)
                    {
                        if (tmp_buffer[i] == 0xff && tmp_buffer[i + 1] == 0xff && tmp_buffer[i + 2] == 0x63 && tmp_buffer[i + 4] != 0)
                        {
                            back_mesage[0] = tmp_buffer[i + 4];
                            back_mesage[1] = tmp_buffer[i + 5];
                            back_mesage[2] = tmp_buffer[i + 6];
                            back_mesage[3] = tmp_buffer[i + 7];
                            back_mesage[4] = tmp_buffer[i + 8];
                            back_mesage[5] = tmp_buffer[i + 9];
                            back_mesage[6] = tmp_buffer[i + 10];
                            back_mesage[7] = tmp_buffer[i + 11];
                            back_mesage[8] = tmp_buffer[i + 12];
                            back_mesage[9] = tmp_buffer[i + 13];                            
                        }
 
                        if (tmp_buffer[i] == 0xff && tmp_buffer[i + 1] == 0xff && tmp_buffer[i + 2] == 0x64 && tmp_buffer[i + 4] != 0)
                        {
                            back_mesage[10] = tmp_buffer[i + 4];
                            back_mesage[11] = tmp_buffer[i + 5];
                            back_mesage[12] = tmp_buffer[i + 6];
                            back_mesage[13] = tmp_buffer[i + 7];
                            back_mesage[14] = tmp_buffer[i + 8];
                            back_mesage[15] = tmp_buffer[i + 9];
 
                            // Событие отклик на наши действия
                            if (get_ans_dl_point != null) get_ans_dl_point(this, EventArgs.Empty);
                        }                      
                    }
 
                    // Получен маркер нового пакета данных в то время как предыдущий пакет не был дополучен 
                    // (обеспечивается условием DataBufferSize > 1)
                    if (tmp_buffer[i] == 0xff && DataBufferSize > 1 && DataBuffer[DataBufferSize - 1] == 0xff)
                    {
 
                        // Обнулим буффер данных от устройства
                        DataBuffer[0] = 0xff;
                        DataBufferSize = 1;
                    }
 
                    DataBuffer[DataBufferSize] = tmp_buffer[i];
                    ++DataBufferSize;
 
 
                    // Пакеты данных всегда по MAX_DATA_SIZE байт
                    if (DataBufferSize >= MAX_DATA_SIZE)
                    {
                        AddCommand(DataBuffer, DataBufferSize);
 
                        // После разбора данных обнулим буффер
                        DataBufferSize = 0;
                    }
                }
 
                // После получения всех команд обработаем  все данные пришедшие в _актуальных_ командах
                System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<byte, byte[]>> enumerator = CommandList.GetEnumerator();
 
                while (enumerator.MoveNext())
                {
                    System.Collections.Generic.KeyValuePair<byte, byte[]> item = enumerator.Current;
                    ParseData(item.Value, item.Value.Length);
                }
                CommandList.Clear();
 
                // Событие окончания
                if (end_data != null) end_data(this, EventArgs.Empty);
            }
 
            catch (System.InvalidOperationException)
            {
                id_lave = false;
            }
 
            catch (System.Exception)
            {
            }
        }
 
        // Поиск нужного порта
        public bool Scan_com_ports()
        {
            // Очищаем массив для хранаения имён СОМ портов и записываем в него имена имеющихся СОМ в системе,
            // необходимо если число ком портов измененилось
            Array.Clear(com_array, 0, com_array.Length);
            com_array = System.IO.Ports.SerialPort.GetPortNames();
 
            if (com_array.Length <= 0)
                return false;
 
            for (int i = 0; i < com_array.Length; ++i)
            {
                try
                {
                    main_serial.Close();
                    if (!main_serial.IsOpen)
                    {
                        main_serial.PortName = com_array[i];
                        main_serial.BaudRate = 57600;
                        main_serial.ReadTimeout = 2000;
                        main_serial.WriteBufferSize = 2048;
                        main_serial.RtsEnable = true;
                        main_serial.DataBits = 8;
                        main_serial.Open();
 
                        System.Threading.Thread.Sleep(310); // время для заполнения буфера СОМ порта
                        main_serial.Read(tmp_buffer, 0, 400);
                        System.Threading.Thread.Sleep(310); // время для заполнения буфера СОМ порта
 
                        // условие того что порт нужный
                        for (int j = 0; j < size - 16; ++j)
                        {
                            if (tmp_buffer[j] == 0xff && tmp_buffer[j + 1] == 0xff && tmp_buffer[j + 2] == 0x75)
                                return true;
                        }
                    }
                }
                catch (System.Exception )
                {
                   
                }
            }
            
            return false;
        }
 
 // Комнды обрабатываются
        private bool AddCommand(byte[] data_buffer, int data_size)
        {
            if (data_size < MAX_DATA_SIZE || data_buffer[0] != 0xFF || data_buffer[1] != 0xFF)
                return false;
            CommandList[data_buffer[2]] = new byte[data_size];
            Array.Copy(data_buffer, CommandList[data_buffer[2]], data_size);
            return true;
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4 из 5
Похожие ответы