Firmata library – библиотека, реализующая протокол Firmata
Библиотека Firmata реализует протокол Firmata, что позволяет простым образом общаться с программами на компьютере.
Данная библиотека входит в состав Arduino IDE.
Удобна тем, что при необходимости не нужно изобретать велосипед и придумывать свой протокол, как, например, в этой программе управления, а уже использовать этот готовый протокол. К тому же он реализован и для Processing-а.
Рассмотрим функции библиотеки:
void begin();
void begin(long);
Описание:
Запуск/инициализация библиотеки
Параметры:
long – отличная от установленной по-умолчанию(57600) скорость обмена
void printVersion(void);
Описание:
Отправить компьютеру версию протокола
void blinkVersion(void);
Описание:
Промигать версию протокола на 13 пине.
void printFirmwareVersion(void);
Описание:
отправить название прошивки и ее версию на компьютер.
void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
Описание:
установить название и версию прошивки, используя название скетча без расширения (.pde)
Отправка сообщений
void sendAnalog(byte pin, int value);
Описание:
отправить аналоговое сообщение
void sendDigitalPort(byte portNumber, int portData);
Описание:
Отправить значение порта одним 8-битным сообщением
void sendSysex(byte command, byte bytec, byte* bytev);
Описание:
послать сообщение в виде массива байт
void sendString(const char* string);
Описание:
Отправить сообщение в виде стоки
void sendString(byte command, const char* string);
Описание:
Отправить сообщение в виде стоки командного типа
Получение сообщений
int available(void);
Описание:
Проверяет наличие сообщений в буфере
void processInput(void);
Описание:
Прочесть сообщение из буфера, отправить данные зарегистрированным функциям-обработчикам
void attach(byte command, callbackFunction newFunction);
void attach(byte command, systemResetCallbackFunction newFunction);
void attach(byte command, stringCallbackFunction newFunction);
void attach(byte command, sysexCallbackFunction newFunction);
Описание:
Задать функцию-обработчик для определённого типа сообщений
void detach(byte command);
Описание:
Отменить функцию-обработчик для определённого типа сообщений
Функции-обработчики
Фунцкия-обработчик должна быть вида:
generic:
void (*callbackFunction)(byte, int);
system_reset:
void (*systemResetCallbackFunction)(void);
string:
void (*stringCallbackFunction)(char*);
sysex:
void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
Типы сообщений
Ниже представлены типы сообщений, к которым можно подключить вашу функцию-обработчик:
#define DIGITAL_MESSAGE 0x90 // данные цифрового порта (8-бит) #define ANALOG_MESSAGE 0xE0 // аналоговое значение пина (PWM) #define REPORT_ANALOG 0xC0 // включить/отключить отчет об аналоговом пине #define REPORT_DIGITAL 0xD0 // включить/отключить отчет о цифровом пине // #define SET_PIN_MODE 0xF4 // установить режим пина: INPUT/OUTPUT/PWM/etc #define FIRMATA_STRING 0x71 // строка: stringCallbackFunction #define SYSTEM_RESET 0xFF // сообщение для перезагрузки прошивки: systemResetCallbackFunction
Пример:
Получение и отправка аналогового сообщения
#include <Firmata.h> byte analogPin; void analogWriteCallback(byte pin, int value) { pinMode(pin,OUTPUT); analogWrite(pin, value); } void setup() { Firmata.setFirmwareVersion(0, 1); Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); Firmata.begin(); } void loop() { while(Firmata.available()) { Firmata.processInput(); } for(analogPin = 0; analogPin < TOTAL_ANALOG_PINS; analogPin++) { Firmata.sendAnalog(analogPin, analogRead(analogPin)); } }
Другой пример – управление двумя сервами:
#include <Firmata.h> #include <Servo.h> Servo servo9; Servo servo10; void analogWriteCallback(byte pin, int value) { if(pin == 9) servo9.write(value); if(pin == 10) servo10.write(value); } void setup() { Firmata.setFirmwareVersion(0, 2); Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); servo9.attach(9); servo10.attach(10); Firmata.begin(9600); } void loop() { while(Firmata.available()) Firmata.processInput(); }
Теперь нужно разобраться – какой формат сообщений нужно предавать с управляющей программы компьютера (хоста).
В этом поможет описание протокола на официальном сайте
http://firmata.org/wiki/Protocol
а так же пример программы, управляющей состоянием портов Arduino:
http://firmata.org/wiki/Proposals
Исходный код которой можно скачать здесь:
http://www.pjrc.com/teensy/firmata_test/firmata_test.tar.gz
и разобраться, как посылать/принимать данные по данному протоколу.
Код для установки значения на выходе цифрового порта:
uint8_t buf[3]; buf[0] = 0x90 | pin; buf[1] = val & 0x7F; buf[2] = (val >> 7) & 0x7F; port.Write(buf, 3);
Код для установки аналогового значения:
uint8_t buf[3]; buf[0] = 0xE0 | pin; buf[1] = val & 0x7F; buf[2] = (val >> 7) & 0x7F; port.Write(buf, 3);
Код для установки состояния порта:
uint8_t buf[4]; buf[0] = 0xF4; buf[1] = pin; buf[2] = mode; port.Write(buf, 3);
, где
port – экземпляр класса Serial для работы с COM-портом
pin – номер пина ардуины
val – значение для установки
mode – состояние порта – одно из:
#define MODE_INPUT 0x00 #define MODE_OUTPUT 0x01 #define MODE_ANALOG 0x02 #define MODE_PWM 0x03 #define MODE_SERVO 0x04 #define MODE_SHIFT 0x05 #define MODE_I2C 0x06
Cсылки:
http://arduino.cc/en/Reference/Firmata
http://firmata.sourceforge.net/wiki/Protocol
http://www.acraigie.com/programming/firmatavb/default.html
По теме
Практическое программирование Arduino- программирование работы с COM-портом
Arduino и Matlab
Arduino и LabVIEW
11 комментариев на «“Программирование Arduino — библиотека Firmata”»
Интересное, конечно, решение, но только зачем-то подразумевает написание обработчиков. Можно было бы отдавать полный контроль управляющему приложению.
И самого главного нет — передачи данных. Есть «строка», но эту строку надо ещё парсить, а это тоже целый процесс. Нет обратной связи — дошло ли, в целости ли…
В общем сомнительная библиотека. Надо изобретать что-то своё!
Что нет проверки целостности данных — это минус.Processing , да и для взаимодействия с URBI я планирую использовать именно его.
Разве нет передачи данных?
Cвоё, разумеется, изобрести можно, но рекомендую внимательнее присмотреться к этому протоколу.
Например, этот же протокол для работы с Arduino использует
А разве есть передача данных? Я присмотрелся как мог, и пришёл к выводу, что даже для процессинга реализация посредственная.
Собственно для связи с процессингом я и начал писать свою библиотеку.
На мой взгляд гораздо интереснее взаимодействие на следующем уровне:
В программе для Ардуино подключаются функции в качестве событий, которым передаются данные, тут схоже как сделано в Firmata, но во-первых очень редко надо передавать String, тем более, что его не просто парсить, во-вторых длинны byte явно недостаточно для передачи большинства значений. Поэтому интереснее если будет передаваться массив int, при чём к нему ещё будет прилагаться параметр команды — для определения обработчика:
А из Процессинга:
0 — как команда, для определения разных функций на разные команды (чтобы не развлекаться switch-case)).
Библиотека должна сама проверять целостность, и отправлять-принимать авто-отчёт об успешности передачи и т.п.
Ну и ещё интересный и важный момент — автоматический поиск и определение порта на котором висит устройство.
В общем много есть ценных нововведений, которые в Firmata вряд ли реализуют в ближайшее время.
это немного не то, но взглянуть стоит —RPC(Remote Procedure Call) для Arduino
Да, схожая тема, но пока мы тут говорили — я написал львиную долю того, чего хотел получить от Firmata.
Через некоторое время, думаю, смогу представить здесь. Вдруг кому-то будет интересно.
Отлично! С нетерпением буду ждать 🙂
А я не пойму… Serial.print уже не катит?
и на компе аналогично. Хоть процессинг, хоть на сях, хоть на (О трепещите ацкие кодеры) VB.NET
покопался в коде этой фирматы, нашел опрос шины i2c/ А есть ли там 1wire?
а как сервами крутить, что нужно в COM слать? разъясните пожалуйста…
аналоговое значение.Управляемая веб-камера или же web-cam-бот
см. пример в
объясните подробней, что нужно на ком отправлять, допустим из arduino ide.
P.S. очень нужно, перерыл все, но так и не понял(