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

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

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

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

C#, вздрагивание 5.0, клиент HP тонкий, компактные рамки 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()

одно замечание о моем приложении заключается в том, что я запускаю поток (weighSample), когда курсор переходит на текстовое поле. Причина этого заключается в том, что вес также может быть набран вручную (часть req). Поэтому я заранее не знаю, будет ли пользователь нажимать печать на балансе или вводить вес. В любом случае после получения данных я выхожу из рабочего потока. Кроме того, обратите внимание, что я не использую datareceived события последовательного порта, так как мне сказали это ненадежно.

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

4 ответов


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


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

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

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


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

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

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

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


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