Сборка последовательного сообщения в C # - PullRequest
0 голосов
/ 28 января 2012

Я новичок в мире C # и последовательной связи. Прочитав несколько уроков, я сумел наладить общение. Я задал другой похожий вопрос здесь , но я не думаю, что задал правильный вопрос. Я следовал совету, приведенному в последнем вопросе, и немного изменил свой код, чтобы теперь отправлять с моего микроконтроллера последовательное сообщение, которое выглядит следующим образом:

SxxxxxxxxxxxxxxxxxxxxxxxxE

Символы X означают различные цифры, знаки плюс и минус и запятые. Строка, которую я отправляю, всегда будет одинаковой длины и всегда будет начинаться с буквы S и заканчиваться буквой E (если это плохо, я могу изменить ее). Проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытаюсь прочитать последовательную строку, я получаю только части сообщения за раз, так что-то вроде этого:

Sxxxxxxx
xxxxx
xxxxESxxx

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

Любая помощь будет принята с благодарностью!

Это код, с которым я играюсь:

    SerialPort serialHC = new SerialPort(); // serial connection dealing with Hand Controller

     public string receiveCommandHC()
    {

        string messageHC = "";
        if (serialHC.IsOpen)
        {
            //serialHC.DiscardInBuffer();
            //messageHC = serialHC.ReadLine();
            messageHC = serialHC.ReadTo("*");
            //tempMsgHC = serialHC.ReadTo("*");
            //i = tempMsgHC.IndexOf("S");
            //tempMsgHC.Remove(0,i);
            //messageHC = tempMsgHC;

            //serialHC.Read(bufferHC = new byte[serialHC.BytesToRead], 0, serialHC.BytesToRead);
        }
        return messageHC;

Раньше конец сообщения был "*"

Только что попробовал следовать примеру здесь вот что я получаю из этого. Serial Message Received

Это то, что я отправляю (используя Putty для проверки) enter image description here

1 Ответ

2 голосов
/ 28 января 2012

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

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

Инициализация:

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

  2. Выделите буфер фиксированного размера для чтения данных в.

  3. Войдите в состояние «Ожидание сообщения».

Ожидание сообщения:

  1. Читайте каждый символ, пока не найдете букву "S" или не будет достигнут конец сообщения.
  2. Если обнаружена буква «S», перейдите в состояние «Чтение в сообщении».
  3. Если «S» не найден, дождитесь следующего сообщения.

Чтение в сообщении:

  1. Копировать каждый символ в данных в буфер сообщений, пока не будет найдена буква "E" или не будет достигнут конец сообщения.
  2. Если обнаружена буква «E», составьте расписание содержимого буфера сообщений, который необходимо обработать, очистите его и войдите в состояние «Ожидание сообщения».
  3. Если буква "Е" не найдена, дождитесь следующего сообщения.

Вот некоторый код, который отражает суть алгоритма:

enum ReadState { Waiting, Reading, Finished }
static string ReadMessage(SerialPort port)
{
    var messageBuffer = new StringBuilder("S");
    var state = ReadState.Waiting;
    while (state != ReadState.Finished)
    {
        switch (state)
        {
        case ReadState.Waiting:
            if (port.ReadChar() == 'S')
            {
                state = ReadState.Reading;
            }
            break;
        case ReadState.Reading:
            messageBuffer.Append(port.ReadTo("E"));
            state = ReadState.Finished;
            break;
        }
    }
    return messageBuffer.ToString();
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...