Разделить сообщение в последовательной связи - PullRequest
2 голосов
/ 27 января 2012

Я новичок в последовательной связи.Я прочитал довольно много учебных пособий, и большая часть того, что я пытаюсь сделать, работает, однако у меня есть вопрос, касающийся последовательной связи с C #.У меня есть микроконтроллер, который постоянно отправляет данные через последовательную линию.Данные представлены в следующем формате: bxxxxixx.xx, xx.xx *, где x представляют разные числа, знаки + или -.В определенное время хочу прочитать эту информацию из моей программы C # на моем компьютере.Проблема, с которой я сталкиваюсь, заключается в том, что мои сообщения кажутся разбитыми на случайные позиции, хотя я использую ReadTo ("*");Я предполагал, что это будет читать все до символа *.Как я могу убедиться, что полученное сообщение завершено?

Спасибо за вашу помощь.

    public string receiveCommandHC()
    {

        string messageHC = "";
        if (serialHC.IsOpen)
        {
            serialHC.DiscardInBuffer();
            messageHC = serialHC.ReadTo("*");

        }
        return messageHC;
    }

Ответы [ 3 ]

3 голосов
/ 27 января 2012

Я не уверен, почему вы это делаете, но вы отбрасываете все данные в буфере последовательных портов непосредственно перед чтением, поэтому, если компьютер уже получил «bxxx» в этот момент, вы выбрасываете егои вы будете читать только «xixx.xx, xx.xx».

1 голос
/ 27 января 2012

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

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

Вам понадобится буфер чтения и записи. Они должны быть достаточно большими, чтобы хранить данные за несколько циклов.

Добавить данные, прочитанные со входа, в конец буфера чтения. Пусть чтение буфера циклически включается для получения полных сообщений с самого начала буфера.

В зависимости от используемого протокола обычно начинается начало данных и, возможно, индикатор окончания данных и где-то размер сообщения (это может быть фиксированным, опять же, в зависимости от вашего протокола). Я собираю из вашего протокола, что начальный символ сообщения 'b', а конечный символ сообщения '*'. Удалите все данные, предшествующие начальному символу вашего сообщения ('b'), так как это из неполного сообщения.

Когда полное сообщение будет найдено, уберите его из передней части буфера и вызовите событие, чтобы указать его прибытие.

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

Я надеюсь, что это поможет вам понять, как справиться с последовательной связью.

Как отметил Марк, вы в настоящее время очищаете свой буфер таким образом, что это вызовет проблемы.

редактировать

Как я уже сказал в своем комментарии, я не распознаю serialHC, но если вы работаете с необработанными данными, посмотрите на использование класса SerialPort. Больше информации о том, как его использовать и пример (который примерно использует процесс, который я описал выше) можно найти здесь .

1 голос
/ 27 января 2012

Я собираюсь предположить, что на самом деле вы получаете заканчивается команд, то есть вместо b01234.56.78.9 (без окончательного *), вы получаете (скажем, ) .56.78.9. Это потому, что вы отбросили входной буфер . Не делай этого. Вы не можете знать состояние в этой точке (непосредственно перед чтением), поэтому отбрасывание буфера просто неправильно. Удалить строку serialHC.DiscardInBuffer();.

...