Существует множество способов написания последовательного протокола в зависимости от того, какие функции вы хотите использовать, и сколько проверки ошибок вам нужно.
Вот некоторые из общих вещей, которые вы видите в протоколах точка-точка:
Конец сообщения
Простейшие протоколы ASCII просто имеют конец символьной последовательности сообщения, часто \r
или так, \n
как это печатается при нажатии клавиши ввода. Двоичные протоколы могут использовать 0x03
или какой-либо другой общий байт.
Начало сообщения
Проблема только с окончанием сообщения состоит в том, что вы не знаете, какие еще байты уже были получены при отправке сообщения. Эти байты будут затем добавлены к сообщению и будут неправильно интерпретированы. Например, если Arduino только что проснулся, в последовательном буфере может быть мусор. Чтобы обойти это, у вас есть начало последовательности сообщений. В вашем примере ^
в бинарных протоколах часто0x02
Проверка ошибок
Если сообщение может быть повреждено, нам нужна проверка ошибок. Это может быть контрольная сумма или ошибка CRC или что-то еще.
Побег персонажей
Возможно, контрольная сумма добавляет контрольный символ, такой как байт «начало сообщения» или «конец сообщения», или сообщение содержит значение, равное контрольному символу. Решение состоит в том, чтобы ввести escape-символ. Экранирующий символ помещается перед модифицированным управляющим символом, поэтому фактический управляющий символ отсутствует. Например, если начальный символ 0x02, используя escape-символ 0x10, мы можем отправить значение 0x02 в сообщении в виде пары байтов 0x10 0x12 (управляющий символ байта XOR)
Номер пакета
Если сообщение повреждено, мы можем запросить повторную отправку с помощью сообщения nack или повторить попытку, но если было отправлено несколько сообщений, то только последнее сообщение может быть повторно отправлено. Вместо этого пакету может быть присвоен номер, который переворачивается после определенного количества сообщений. Например, если это число равно 16, передающее устройство может сохранить последние 16 отправленных сообщений, и, если они были повреждены, принимающее устройство может запросить повторную отправку с использованием номера пакета.
длина
Часто в двоичных протоколах вы видите байт длины, который сообщает принимающему устройству, сколько символов содержится в сообщении. Это добавляет еще один уровень проверки ошибок, как если бы правильное количество байтов не было получено, то произошла ошибка.
Специфичный для Arduino
При разработке протокола для Arduino первое соображение заключается в том, насколько надежен канал связи. Если вы отправляете данные по большинству беспроводных сред, XBee, WiFi и т. Д., В них уже встроены средства проверки ошибок и повторных попыток, и поэтому нет смысла вставлять их в ваш протокол. Если вы отправляете через RS422 на пару километров, это будет необходимо. Вещи, которые я бы включил, это начало и конец сообщения, как у вас. Моя типичная реализация выглядит примерно так:
>messageType,data1,data2,…,dataN\n
Разделение частей данных запятой позволяет легко выполнять синтаксический анализ, и сообщение отправляется с использованием ASCII. Протоколы ASCII хороши тем, что вы можете вводить сообщения в последовательный монитор.
Если вам нужен двоичный протокол, возможно, для сокращения размеров сообщений, вам придется реализовать экранирование, если байт данных может совпадать с байтом управления. Двоичные управляющие символы лучше подходят для систем, где требуется полный спектр проверки ошибок и повторных попыток. При желании полезная нагрузка может быть ASCII.