Последовательный порт ReadLine против ReadExisting или как правильно читать данные с последовательного порта - PullRequest
13 голосов
/ 12 марта 2009

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

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

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

C #, 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, поскольку мне сказали, что это ненадежно.

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

Ответы [ 4 ]

11 голосов
/ 12 марта 2009

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

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

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

5 голосов
/ 12 марта 2009

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

1 голос
/ 28 июня 2016

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

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

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

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

0 голосов
/ 17 июля 2015
if (serialPort1->IsOpen){
    if (serialPort1->BytesToRead>0){
        this->textBox1->Text += serialPort1->ReadExisting();
    }
}
...