Протокол общения с Arduino?

Добрый день!

Делаю свой сервер для управления ардуной через ком порт.
На этапе проектирования возник вопрос о протоколе общения с адруиной. Сервер должен принимать и отправлять команды на ардуину, но вот как?
В простой реализации я бы сделал примерно так команду:
"MODE:SET; P_N:1; P_IN:0; P_LOW: 0." - отправка на устройство команды на установку пина 1 в положение IN, LOW.
"MODE:GET; P_N:1." - отправка на устройство команды получения данных или состояния пина 1.

Всё это довольно просто с когда только непосредственно с пином имеем дело, а что если на пине 1 висит DHT11 и нужно получить температуру и влажность?
"MODE:GET; P_N:1,1"? - получить данные с пина 1, условно первые данные (температура).
А если на ноге висит сдвиговый регистр?
"MODE:SET; P_N:1,0,1,0,0,0,1,1,1; P_IN:0; P_LOW: 0." - пин 1 в положение IN, LOW и включить соответствующие выводы на регистре сдвига.
А если на ноге 1Wire датчики висят??
  • Вопрос задан
  • 1841 просмотр
Пригласить эксперта
Ответы на вопрос 6
Весь протокол в обмене словами, по сути.
Т.е. по определенному набору входных слов можно сделать функции, которые отработают и отправят в ответ строку - результат.

Можно сделать примерно такое (сильно не пинать за говнокод, это пример!):
отправляем строку. арудина её читает, если находит подстроку, то выполняет определенное действие, иногда пишет в терминал какие-то слова, что действие выполнено.
if (strstr(term_in, "SWPOWER"   ) != 0) code = 1;/*strstr - найти подстроку в строке, пришедшей с ПК (алгоритм чтения слова опустим)*/
if (strstr(term_in, "CALL_1"    ) != 0) code = 2;
if (strstr(term_in, "SMS_SEND"  ) != 0) code = 3;
if (strstr(term_in, "CTRL+Z"    ) != 0) code = 4;
//в зависимости от найденной подстроки был получен один из кодов и по нему работает case
      switch (code)
      {
        case 1:
          Serial.println("@power on/off signal");
          digitalWrite(9, HIGH);
          delay(1000);
          digitalWrite(9, LOW);
          break;
        case 2:
          Serial.println("term@: call number +790679__823");//отправляем сообщение, что начата попытка дозвона
          gprsSerial.println("ATD+790679__823;");//в шилд
          break;
        case 3:
          function1();
   default:
          /*Код, который выполнится, если ниодно из константых значению не соответствует значение в переменной variable*/
          Serial.print("text ");
          break;
Ответ написан
a_volkov1987
@a_volkov1987
Инженер-схемотехник
Для начала определите какое оборудование будет подключено к ардуине и в каком виде оно будет принимать и отдавать данные для общения с сервером.
Потом определитесь как именно будет происходить общение с серверомю Может вам нужны данные от оборудования только "по запросу" или же ардуина должна с определенным интервалом отдавать данные сама.
Ну и исходя из этого разработайте протокол.
Определите заголовок пакета для передачи и приема, если придется принимать и передавать пакеты разной длины, в заголовке выделите секцию под описание длины пакета. И не передавайте данные в стоковом виде, если можно обойтись без этого. То есть секция пакета, которая описывает получателя данных, не должна быть со строковыми данными. Используйте код. 01 - модем, A2 - датчик температуры .... F0 - датчик влажности и т.д.
В принципе пакет от сервера может иметь следующий вид:
AA 00 - (2 байта) признак начала пакета
XX XX - (2 байта) длина пакета в байтах (без заголовка)
XX -(1 байт) получатель данных
XX...XX (n байт) аргумент для передачи получателю

Опционально в конце пакета можно передать контрольную сумму, вычисленную как некую функцию от заголовка и тела пакета.

Что и как передается в аргументе - ваше дело. Для датчика DHT вы вообще можете ничего не указывать, а для модема первый байт пакета может содержать AT-команду в виде условного кода, 10 байт после нее - номер абонента без 8 и (возможно) еще n байт с текстом, если это передача смс.
ДЛя управления какой-нибудь индикацией вы можете передавать 1 байт, в котором будет зашифрован тип индикации (00 - индикация выключена, 01 - постоянная индикация, 02 - мигающая индикация)

От ардуино вы можете получать данные таким же пакетом.
Ответ написан
Комментировать
MaxDukov
@MaxDukov
впишусь в проект как SRE/DevOps.
сделайте отдельные команды для работы напрямую с пинами, отдельные - для работы с датчиками, отдельный - для регистров. Иначе получается, что ВСЯ логика реализуется на компьютере, ардуина лишь реализует передачу/прием данных.
Ответ написан
anthtml
@anthtml
Системный администратор программист радиолюбитель
UART для микроконтроллера (ардуины) просто интерфейс обмена текстовыми или битовыми сообщениями, с пинами и другими устройствами он никак не связан, а имеет выход только в программную часть МК. Так что как вы реализуете его работу в прошивке (скетче), так он и будет работать. Берите приходящие из serial команды, расшифровывайте их и раздавайте задания функциям работы с пинами или устройствами. От них собирайте данные, формируйте из данных текстовые ответы и отправляйте в serial. Стандартов практически нет - тут все как душа разработчика/заказчика пожелает.
Ответ написан
Neuroware
@Neuroware
Программист в свободное от работы время
Мне кажется вы пытаетесь написать еще одну Firmata, посмотрите в сторону данной библиотеки, возможно там уже есть все что вам нужно
Ответ написан
Комментировать
@Melz
Ну обычно для этого берут RS-232 и компанию через MAX232 или его альтернативу.
https://www.arduino.cc/en/Tutorial/ArduinoSoftwareRS232

Ну а ардуина как определяет что висит на ее ноге? У нее же нет дара предсказывания, если вы просто повесите на ногу датчик 1Wire ничего не произойдет.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы