Улучшение соединения SerialPort - PullRequest
0 голосов
/ 19 августа 2010

Довольно простой вопрос на этот раз.У меня есть приложение, которое связывается с другой копией приложения на других машинах.Одно приложение отправляет довольно постоянный поток данных, другое получает его.

Код для отправки данных выглядит следующим образом (где serialPort является экземпляром класса System.IO.Ports.SerialPorts в C # .Net 2.0):

private void bgDataWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e){
    try{
        string tempStr = Convert.ToString(String.Format("{0:0.000000}", data));
        serialPort.Write(tempStr); // Write "data" out to 6 decimal places  
    }
    catch (TimeoutException){ }
    catch (InvalidOperationException err){ // Port is obstructed or closed
        this.Invoke((MethodInvoker)delegate{
            MessageBox.Show(this, "Couldn't send wireless data:\n\n" + 
                            err.ToString(), "NanoMETER - Wireless Error (Data)", 
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
            Global.remoteEna = false;
            serialPort.Close();
            usingBT = false;  
        }); 
    }
}

Вызывается по таймеру.Код получения еще более прост:

private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {
    string buffer = serialPort.ReadExisting();
    HandleInput(buffer);
}

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

1 Ответ

1 голос
/ 27 августа 2010

Стажеры нередко назначаются для преобразования старого кода на более новую платформу.

Есть несколько улучшений, которые вы можете сделать.

1) Следующая стратегия хороша, когда байты, отправляемые через порт, должны интерпретироваться в блоках, таких как команды.У вас есть какой-то протокол?То, что определяет формат сообщения, которое вы отправляете.Например, конкретный разделитель для указания начала и длины предстоящей команды.Это позволяет быстро определить, была ли команда отправлена ​​только наполовину или отсутствовали байты.Еще лучше добавить CRC в конце.

2) Вместо чтения по таймеру основывайте себя на событиях, помеченных вашим объектом последовательного порта.Вот пример того, что я использую:

    //OnReceive event will only fire when at least 9 bytes are in the buffer.
    serialPort.ReceivedBytesThreshold = 9; 
    //register the event handlers
    serialPort.DataReceived += new SerialDataReceivedEventHandler(OnReceive);
    serialPort.PinChanged += new SerialPinChangedEventHandler(OnPinChanged);

В приведенном выше коде я установил порог 9, вы должны изменить его на тот, который соответствует вашему контексту.Кроме того, событие Pinaged - это что-то хорошее для мониторинга, оно позволит вам быстро определить, был ли кабель отсоединен.Есть еще кое-что об этом, касающееся CTSChanged, но вы можете посмотреть его, если вам интересно.

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

...