Последовательный порт ReadLine vs ReadExisting или как правильно считывать данные из последовательного порта

Я читаю данные из последовательного порта. Данные выводятся из шкалы. Теперь я использую Readline() и получаю данные даже после удаления DiscardInBuffer(). Каков правильный способ чтения данных из последовательного порта? В Интернете так мало примеров, что я чувствую, что это какой-то святой Грааль, который никто не понял.

Любая помощь, пожалуйста?

Кажется, что последовательный порт - это капризный ребенок.

С#, WinCE 5.0, тонкий клиент HP, Compact framework 2.0

 private void WeighSample()
    {
        this._processingDone = false;
        this._workerThread = new Thread(CaptureWeight);
        this._workerThread.IsBackground = true;
        this._workerThread.Start();
    } //end of WeighSample()


    private void CaptureWeight()
    {
         globalCounter++;
         string value = "";


          while (!this._processingDone)
          {
              try
              {

                 value = this._sp.ReadLine();

                  if (value != "")
                  {
                      if (value == "ES")
                      {
                          _sp.DiscardInBuffer();
                          value = "";
                      }
                      else
                      {
                          this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
                      }
                  }
              }
              catch (TimeoutException)
              {
                  //catch it but do nothing
              }
              catch
              {
                  //reset the port here?
                  MessageBox.Show("some other than timeout exception thrown while reading serial port");
              }
          }


    } //end of CaptureWeight()

Одно замечание о моем приложении заключается в том, что я запускаю поток (weightSample), когда курсор перескакивает на текстовое поле. Причина этого в том, что вес также можно ввести вручную (часть запроса). Поэтому я не знаю заранее, будет ли пользователь нажимать PRINT на весы или набирать вес. В любом случае после получения данных я выхожу из рабочего потока. Также обратите внимание, что я не использую событие последовательного порта DataReceived, так как мне сказали, что он не надежный.

Любые комментарии/идеи приветствуются. Это мой первый опыт работы с последовательными портами.

Ответ 1

Мне никогда не удавалось работать с ReadLine. Просто выполняйте чтение в локальном буфере всякий раз, когда доступны данные, а затем используйте отдельный поток для сканирования данных и поиска разрывов строк.

Ответ 2

Зависит от того, какой символ (-ы) конца строки (EOL) предназначен для ваших входных данных. Если ваши данные ориентированы по прямой, то ReadLine является допустимой функцией для использования, но вы можете захотеть взглянуть на свойство NewLine и убедиться, что она правильно установлена ​​для ваших входных данных.

Например, если ваша шкала выводит строку для EOL, установите port.NewLine = "\n";

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.newline.aspx

Ответ 3

Я хотел бы прокомментировать Элиаса Сантоса, но у меня нет достаточной репутации. Есть несколько ошибок в использовании метода ReadExisting:

https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readexisting(v=vs.110).aspx

Обратите внимание, что этот метод может оставлять задние байты в внутренний буфер, что делает значение BytesToRead больше нуля.

Я столкнулся с некоторыми проблемами с ReadExisting до этого, и это из-за нежелательных байтов. Использование Readline устраняет эти проблемы.

Ответ 4

if (serialPort1->IsOpen){
    if (serialPort1->BytesToRead>0){
        this->textBox1->Text += serialPort1->ReadExisting();
    }
}