2014-11-03 2 views
1

Я беру данные из последовательного инструмента для построения графика на диаграмме. Поток данных составляет 230 кбит/с, а последовательный конвейер заполнен менее чем на 50%, данные поступают примерно на 100 кбит/с и фактически не меняются на самом деле, а скорость и количество.Ошибки данных с моим методом последовательного приема

Использование только программы последовательного терминала, такой как Teraterm, на том же компьютере; Я могу захватить данные и доказать, что как источник данных, так и метод приема теста хороши, и я не вижу ошибок для захваченных данных.

Приложение Windows Forms, которое я разрабатываю, теряет данные. Я уменьшил его от приема, захвата (параллельно), разбора и построения, только для получения и захвата. И обнаружили, что я все еще вижу потерянные данные в захвате.

Я не давно опытный человек Windows, поэтому, возможно, не знаю, как лучше выполнять одни и те же функции. Вот действия, которые я предпринимаю для выполнения принимаемых действий:

Я использую класс System.IO.Ports.SerialPort. я изменить событие .DataReceived через: Я затем вызвать метод Open()

+= new SerialDataReceivedEventHandler(comPort_DataReceive); 

.

Примечание: Возможно, что-то неправильно здесь, я никогда не очищаю событие .DataReceived с-= в любой точке, вместо этого каждый раз, когда я открываю, событие добавляется еще раз. Тем не менее, эти проблемы возникают, даже когда я только разговаривал с портом один раз.

Вот мой код для функции приема данных. RxString - это строка.

private void comPort_DataReceive(object sender, SerialDataReceivedEventArgs e) 
    { 
     RxString = comPort.ReadExisting(); 
     this.Invoke(new EventHandler(ParseData)); 
    } 

    private void ParseData(object sender, EventArgs e) 
    { 
     // Save to capture file, if capture is enabled 
     if ((WriteToFileEnabled == true) && (WriteToFileName != null)) 
     { 
      writeFileHandle.Write(RxString); 
     } 
     return; 
     // Previously would parse and plot data 
    } 

Итак, как люди могут получить получение в этой ситуации, чтобы получить эти данные, не потеряв его?

Следуйте следующим вопросам: насколько большой буфер для последовательного приема, или мне нужно беспокоиться об этом, если у меня есть разумно реагирующее приложение? Управление потоком не имеет значения, удаленное устройство собирается отправлять данные независимо от того, что было бы, поэтому мой компьютер мог бы взять эти данные и обработать их или проигнорировать. Но как я могу узнать, потерял ли я данные или испытал ошибки фреймов и прочее? (Я прошу, чтобы последний из них не искал многое из структуры класса SerialPort, извините.)

+0

Как вы уверены, что данные теряются? Есть ли какой-либо шаблон в потере данных? –

+0

230 Кбит/с довольно быстро подходит для последовательного порта ... если вы находитесь в электрически шумной среде или используете изогнутые кабели, вы можете легко повредить данные. Если передающее устройство позволяет, попробуйте уменьшить до 9600 пунктов и убедитесь, что все работает, прежде чем наращивать скорость. Исправлены ошибки четности. Если вы не используете четность в своем протоколе, и вы не используете квитирование, тогда действительно невозможно гарантировать, что вы получаете все данные или что вы получаете их правильно. –

+0

Этот вызов Invoke() * очень * затруднительный, для ответа на него требуется некоторое время. В частности, если вы «разбираете и замышляете», это обязательно будет проблемой жесткого пожарного шланга. Также очень подходит для блокировки вашей программы, когда вы вызываете Close(). Обнаружение ошибок переполнения путем реализации события SerialPort.ErrorReceived. Собирайте данные, прежде чем вы вызовете BeginInvoke(), убедитесь, что поток пользовательского интерфейса может не отставать. –

ответ

3

Предположим, что ваше устройство отправляет сообщения длиной 85 байт. Обработчик события DataReceive может или не запускать один раз, чтобы получить эти 85 байтов. Так как он может срабатывать более одного раза, ваш код должен учитывать это. Обработчик события DataReceive должен прочитать доступные байты и добавить их в буфер, который обрабатывается позже.

Также может выполняться только одно из событий, поднятых классом SerialPort. В примере предположим, что обработчик должен запускать три раза, чтобы получить 85 байтов. При обработке первой части два других не могут выполнить. Если при обработке первой части необходимы одно из других событий, PinChanged или ErrorReceived, они также не могут быть выполнены.

Мои первые два опыта с классом SerialPort состояли из 9600 бит/с терминала и 1 Мбит/с Bluetooth-устройства. То, что работало для более медленного, не работало быстрее, но когда я понял, как быстрее работать, медленнее может использовать ту же методологию.

Моя методология:

  1. Перед открытием последовательного порта я начинаю два других фоновых потоков, которые работают в цикле делать. Первый (Receive) считывает все доступные байты из последовательного порта, добавляет их в буфер и сигнализирует второй поток при каждом чтении. Второй (протокол) определяет, поступило ли полное сообщение, выполняет ли какой-либо байт для преобразования строк, обновляет пользовательский интерфейс и т. Д. В зависимости от приложения я могу запустить третий поток, который обрабатывает ошибки и изменения контактов. Все эти потоки дросселируются с помощью Threading AutoResetEvent.

  2. В моем обработчике событий DataReceive есть одна строка в нем, Set на AutoResetEvent, который регулирует прием.

Пример VB этого можно найти здесь SerialPort Methodology. С момента принятия этой методологии у меня не было проблем, которые, похоже, угрожают другим пользователям SerialPort и успешно использовали его со скоростью до 2 Мбит/с.

+0

Спасибо, я рассмотрю пример и ожидаю, что это может быть точно так, как мне поможет. Учитывая другие действия сегодня, я предполагаю, что это займет день или около того, прежде чем я смогу рассмотреть это и сделать некоторые эксперименты, но я опубликую последующую информацию, если это закончится решением или приведет к дальнейшим вопросам. – rtm

+0

Стратегия использования потоков для разделения приема приема от синтаксического анализа получения, а также от представления данных - правильное направление решения. – rtm

Смежные вопросы