Arduino:Библиотеки/CmdMessenger

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.



Библиотека CmdMessenger[1]

Библиотека CmdMessenger – это библиотека для пересылки сообщений. Она может использоваться для платформ Arduino и .NET/Mono. В качестве транспортного уровня в ней используется последовательный порт. Чтобы использовать эту библиотеку, в скетче нужно указать, какие именно команды вы собираетесь использовать. Передаваемые команды указываются обычным списком, а принимаемые – тоже списком, но через подключение к экземпляру класса CmdMessenger.

Сообщение имеет следующий формат:

Cmd Id, param 1, [...] , param N;

Библиотека позволяет делать следующее:

  • Отправлять и получать команды.
  • Вызывать функции, привязанные к присылаемым командам.
  • Отправлять и получать вместе с командами различные аргументы. Аргументов может быть несколько или же не быть ни одного.
  • Отправлять и получать данные всех основных типов, включая byte, long, int, float и double.
  • Отправлять и получать обычный текст (который может прочитать человек) или бинарный код (так будет более эффективно).

С версией 3 библиотека получила полную реализацию в C# – теперь ее можно запустить и в Mono, и в Visual Studio.

Это позволяет двустороннюю коммуникацию между контроллером Arduino и PC.

Библиотеку CmdMessenger можно загрузить через менеджер библиотек в IDE Arduino или PlatformIO, а также в виде отдельного пакета (более подробно об этом читайте тут). Подробное описание и пример использования можно найти здесь. Также к библиотеке CmdMessenger есть Python-интерфейс, и найти его можно по этой ссылке.

Инициализация библиотеки

Инициализация библиотеки осуществляется вместе с указанием последовательного порта:

CmdMessenger cmdMessenger = CmdMessenger(Serial)

Здесь же при желании можно изменить разделитель полей, разделитель команд и экранированный символ:

CmdMessenger cmdMessenger = CmdMessenger(Serial, const char field_separator, const charcommand_separator, const char escape_character)

Чтобы улучшить читаемость, можно сделать так, чтобы в конце каждого символа добавлялся символ новой строки:

void printLfCr (bool addNewLine=true)

Входящие последовательные данные должны обрабатываться в блоке loop() при помощи вызова следующей функции:

void feedinSerialData ();

Отправка команды

Если команда отсылается без аргументов, то формат следующий:

sendCmd(int cmdID)

Если команда отсылается с аргументом, то формат следующий (здесь T – это тип данных для аргумента, который мы хотим отправить):

sendCmd(int cmdId, T arg)

Если мы хотим отправить команду и подождать ответа, то пишем следующее:

sendCmd(int cmdId, T arg, bool reqAc, int ackCmdId, int timeout)

Здесь параметры обозначают следующее:

  • reqAc – определяет, хотим ли мы ответа или нет (хотим, поэтому нужно выставить на true)
  • ackCmdId – команда, которую нужно подождать
  • timeout – период ожидания в миллисекундах

Тип возвращаемого значения – boolean. Если ответ будет получен в течение периода ожидания, функция вернет true, иначе – false. Также имейте в виду, что все команды, за исключением ожидаемой ackCmdId, будут проигнорированы.

Отправка команды с несколькими аргументами

Чтобы отправить несколько аргументов, функция отправки делится на несколько подфункций:

sendCmdStart(int cmdId);
sendCmdArg(T arg)
sendCmdEnd();

Также вместо последней (закрывающей) подфункции можно использовать следующий вариант:

sendCmdEnd(bool reqAc, int ackCmdId, int timeout);

Между sendCmdStart() и sendCmdEnd() можно отсылать сколько угодно аргументов, и это делается с помощью функции sendCmdArg(). Аргументы могут быть представлены разными типами данных.

Отправка форматированных, экранированных и бинарных аргументов

Данные типа float передаются в виде цифр формата ASCII и по умолчанию с двумя знаками после запятой. Если вы хотите больше знаков после запятой, то можете сделать следующее:

sendCmdArg(float arg, int n)

Из-за ограничений Arduino числовой диапазон для данных типа float и double, передаваемых с помощью этой функции, составляет лишь от «-2147483648» до «2147483648». Однако функция ниже может отправлять float-данные в диапазоне от «-3.4028235E+38» до «3.4028235E+38» (в экспоненциальной форме).

cmdMessenger.printSci(arg, n)

Если мы хотим отформатировать аргумент функцией типа printf, то можем воспользоваться этим:

cmdMessenger.sendCmdfArg(char *fmt, ...);

Имейте в виду, что платформа Arduino в данный момент не поддерживает отформатированные переменные с плавающей точкой.

Если мы хотим отправить строку, содержащую символ «,» или «;», то перед отправкой его можно экранировать – чтобы с их отправкой не возникало никаких проблем. После считывания эту строку нужно разэкранировать.

sendCmdEscArg(char *arg);

Для отправки бинарных аргументов используется следующая функция:

sendCmdBinArg(T arg)

Здесь T – это тип отправляемого аргумента. Для бинарных данных лучше использовать явное приведение типов. В отличие от обычного текста, в данном случае типы параметров должны точно соответствовать друг другу и со стороны получателя, и со стороны отправляющего. По этой причине при отправке целых чисел используйте int16_t и int32_t, поскольку все платформы воспринимают их одинаково.

Подключение функций внешнего вызова

Подключение функции внешнего вызова к ID сообщения:

attach(byte msgId, messengerCallbackFunction CallBackFunction);

Подключение функции внешнего вызова без привязки к ID сообщения:

attach(messengerCallbackFunction CallBackFunction);

Считывание аргументов у присланных команд

В функции внешнего вызова можно считывать аргументы, присланные вместе с ID команды. Чтобы проверить, есть ли какие-нибудь аргументы, доступные для считывания, используйте следующую функцию:

bool available ();

Если есть, то прочесть аргументы можно при помощи одной из следующих функций:

bool readBoolArg();
int16_t readInt16Arg();
int32_t readInt32Arg();
char readCharArg();
float readFloatArg();
float readDoubleArg();
char* readStringArg();

Имейте в виду, что поведение функции readStringArg() немного отличается от остальных – в том, что присланная строка доступна только до тех пор, пока не считана новая команда. Чтобы у нас был постоянный строковый аргумент, мы можем сделать копию, воспользовавшись для этого следующей функцией:

copyStringArg(char *string, uint8_t size);

Чтобы сравнить строку с текущим аргументом, используйте следующую функцию:

uint8_t compareStringArg(char *string);

Чтобы прочитать бинарный аргумент, используйте следующую функцию:

T readBinArg()

Эта функция также применима к неэкранированным строкам.

Системные требования

IDE Arduino версии 1.0.5 и новее (скачать можно тут). Старые версии могут работать, но не тестировались.

С чего начать

Чтобы научиться работать с библиотекой, попробуйте примеры – от простого к сложному. PC-код для этих примеров есть как для C#, так и для VisualBasic.

  • Receive – Настройка PC-переключателя для светодиода, встроенного в Arduino.
  • SendandReceive – Расширенная версия Receive. Теперь Arduino отсылает обратно статус.
  • SendandReceiveArguments – Расширенная версия SendandReceive. Теперь Arduino получает и отправляет множество float-значений.
  • SendandReceiveBinaryArguments – Расширенная версия SendandReceiveArguments. Теперь Arduino принимает и отсылает множество двоичных значений, тем самым демонстрируя более эффективный способ коммуникации
  • DataLogging – Расширенная версия SendandReceiveBinaryArguments. Теперь при перемещении ползунка PC будет отправлять команды на Arduino.
  • ArduinoController – Расширенная версия Receive. Теперь Arduino отправляет обратно статус.
  • SimpleWatchdog – Демонстрирует настройку автоматического подключения между PC и Arduino.
  • TemperatureControl – Расширенная версия ArduinoController. Демонстрирует, как создать адаптивный интерфейс (в данном случае для отображения температурных данных).
  • ConsoleShell – Демонстрирует, как использовать ConsoleShell в качестве оболочки и коммуницировать с нею при помощи консоли. Этот пример отличается от других тем, что для него нет PC-кода.

Исправление проблем

  • Если PC и Arduino не подключаются друг к другу, то дело, возможно, в том, что со стороны PC выбран неправильный порт, или в том, что на Arduino и PC выставлена неправильная скорость передачи данных. Проверить это можно, вписывая команды в монитор порта IDE Arduino.
  • Если порт и скорость указаны правильно, но функции обратного вызова не вызываются, попробуйте посмотреть в логи отправляемых и получаемых данных. В качестве примера загляните в пример SendandReceiveArguments.

Примечания

Пример использования Max5/MaxMSP шел в комплекте с библиотекой до версии 2 (впрочем, его по-прежнему можно найти по этой ссылке). Этот пример был удален, поскольку у нас нет возможности проверить его с Max/MaxMSP.

Альтернативный вариант для C#

Альтернативную версию библиотеки CmdMessenger для C# можно найти в Code Project.

Эта версия не поддерживает Mono и отправку сообщений в двоичном виде, но зато поддерживает современные функции C#5 и является, по сути, упрощенной версией библиотеки. По ссылке в предыдущем абзаце также можно найти хороший пример применения этой версии.

См.также

Внешние ссылки