Протокол общения с 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 датчики висят??
  • Вопрос задан
  • 1812 просмотров
Пригласить эксперта
Ответы на вопрос 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 ничего не произойдет.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы