Что отправлять через последовательные порты

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

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

Предположим, что ваши требования таковы:

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

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

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

4.) Вам нужна какая-то структура для отправки сложных форм данных на компьютер, возможно, массив показаний напряжения батареи.

Способы добиться этого

Кажется, есть несколько способов, которыми люди склонны делать это:

Простой строковый API:

Наиболее распространенный, связанный со сторонними датчиками, кажется, использует простой API на основе строк, так что команды для запуска и остановки потоков могут быть «SS, 1 \ r» и «SS, 0 \ r» соответственно. В этом случае вам придется читать из последовательного порта, пока вы не получите символ «\ r», а затем проанализировать полученные данные, чтобы увидеть, есть ли у них команда (слева от запятой) и параметры (справа от запятой). Это работает для сценариев с 1 по 3 выше, но не делает сценарий 4 очень простым.

API строк JSON:

Это работает так же, как и выше, но вместо того, чтобы передавать ваши параметры в виде простых значений, вы передаете объекты JSON, которые могут представлять сложные структуры данных. Следовательно, вы можете отправить массив напряжений батареи в виде массива JSON. Этот метод, по-видимому, охватывает все варианты использования 1-4 выше. Но JSON отправляет строки, и его сложнее анализировать с помощью встроенного c. Это сотворило бы чудеса для компьютерной части, которая могла бы использовать язык более высокого уровня, такой как Java, в котором есть библиотеки для чтения данных JSON.

API стиля пакетов:

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

[0xFF][0xFF][ID][CMD][D0][D1][D2][D3][D4][D5][D6][D7][0xEE][0xEE][0xEE]

С помощью этой структуры мы отправляем заголовок и нижний колонтитул (0xFF и 0xEE) для проверки полноты пакета, идентификатор для отправки последовательных пакетов (для передачи массива данных), массив данных, который мы можем использовать для упаковки длинных, плавающих, целых и т. д. , и командный байт (CMD), который может использоваться устройством для определения того, как анализировать полезную нагрузку данных (D0-D7).

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


person JBausmer    schedule 05.09.2013    source источник
comment
Что не так с подходом, который вы использовали, кроме того, что он является проприетарным? Что вы подразумеваете под предпочтительным? Существуют небольшие надежные парсеры для JSON, которые можно использовать на встроенном устройстве: zserge.bitbucket.org/jsmn. .html   -  person Robert Harvey    schedule 05.09.2013
comment
Большая часть JSON используется в сети, где текст сообщения JSON заворачивается в пакеты, проверяется контрольная сумма и проверяется, чтобы убедиться, что он попадает туда, куда вы его отправляете. Корректная передача необработанных последовательных байтов не гарантируется. (Обычно сбои представляют собой 1 или более битов в последовательности. Может быть, несколько целых байтов.) Вам нужно что-то сделать, чтобы проверить целостность сообщения и убедиться, что то, что вы отправляете, действительно туда попало. То, что вы используете, должно делать это.   -  person Lee Meador    schedule 05.09.2013
comment
Во-первых, он ограничивает использование до 256 типов команд. Чтобы обойти это, мы нарушили наше соглашение об отправке данных и команд отдельными пакетами. Теперь мы отправляем пакет, чьи данные задают идентификатор параметра, который мы хотим установить, и отдельный пакет, который отправляет значение для установки этого параметра. В некотором смысле он внедрил состояние в нашу систему доставки, прошивка должна помнить идентификатор в оперативной памяти, пока не получит данные для установки этого параметра. Мы используем 2 пакета вместо 1, что повышает вероятность отказа. Под предпочтительным я подразумеваю, что у кого-то есть лучший способ отправки и анализа структурированных данных.   -  person JBausmer    schedule 05.09.2013
comment
как насчет json-rpc, который имеет дело как с отправкой, так и с получением подтверждения? и это тоже распространенный метод.   -  person Lao Shaw    schedule 07.07.2017


Ответы (2)


Самая большая проблема здесь в том, что нет стандартов. Почти каждый реализует свой собственный протокол для ограничивающих устройств или когда речь идет о низкоуровневом транспорте, таком как UART/Serial Line. Но с растущей тенденцией IoT это, надеюсь, начинает меняться.

Пожалуйста, взгляните на SLIP и SLIPMUX для отправки протоколов, ориентированных на пакеты, по последовательной линии.

Независимо от того, отправляете ли вы JSON, XML или что-то еще, вам, скорее всего, понадобится какой-то стоп-флаг для завершения ваших сообщений. Часто \n используется для удобочитаемости в сочетании с закодированным ASCII содержимым, но это не лучший вариант для двоичного кодирования между машинами.

SlipMux обратно совместим с SLIP (для пакетов IPv4 и IPv6), но также поддерживает новые типы сообщений, такие как CoAP и диагностические (удобочитаемые) сообщения. Вы можете просто реализовать свои собственные типы пакетов, такие как сообщения "JSON" или "XML".

В качестве протокола могу порекомендовать CoAP в сочетании со SlipMux. CoAP очень похож на HTTP, но намного легче и, следовательно, с ним легко работать большинству разработчиков.

person Tarion    schedule 24.01.2017

Двоичный формат пакета привлекателен своей кажущейся простотой и эффективностью. Кроме того, некоторые каналы связи уже отправляют данные в виде пакетов фиксированного размера (USB, TCP/IP, файловые системы и т. д.), но, если бы мне пришлось делать это по-другому, я бы не пошел по этому пути снова из-за следующих недостатков:

  • не читаемый человеком (если вы не хотите запутать вещи и защитить свой протокол :-))
  • зависит от компьютерной архитектуры: подумайте о проблемах порядка следования байтов
  • зависимости инструментальной цепочки: например, как компилятор X упаковывает структуры данных по сравнению с компилятором Y?
  • зависимости канала: если канал изменится, что, если размер пакета протокола и новый размер пакета канала не совпадают?

JSON теперь был бы моим путем: передача данных ASCII менее эффективна, чем передача двоичных файлов, но ее удобство и переносимость компенсируют это, если только приложение не имеет серьезных ограничений пропускной способности. Я лично написал анализатор JSON для платы Arduino Uno, и он работает менее чем с 2 КБ ОЗУ данных, включая системный стек. Хорошо, он может задыхаться от глубоко вложенных передач JSON, но этого было достаточно, чтобы удалить ключевые элементы из пакета твитов в Твиттере, и он доказал, что может работать на крошечных системах.

Ив Макдональд

person user2918341    schedule 25.10.2013