firmata4j - это клиентская библиотека протокола Firmata написанная на Java. Она позволяет управлять Arduino (или другим устройством), которое поддерживает взаимодействие по протоколу Firmata, из программы на языке Java.
- Взаимодействие с устройством и с его портами в объектно-ориентированном стиле
- Коммуникация через последовательный порт, сеть или авторский транспортный слой
- Позволяет абстрагироваться от деталей протокола
- Предоставляет графический компонент для визуализации и изменения режима и состояния портов устройства
- Позволяет возаимодействовать с устройствами по протоколу I2C
Добавьте зависимость в pom.xml
проекта:
<dependency>
<groupId>com.github.kurbatov</groupId>
<artifactId>firmata4j</artifactId>
<version>2.3.8</version>
</dependency>
Если вы хотите подключаться к устройству по последовательному порту (что весьма
вероятно), добавьте одну из следующих библиотек в файл pom.xml
:
<!-- только одну из библиотек -->
<dependency>
<groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId>
<version>2.6.2</version>
</dependency>
<!-- или -->
<dependency>
<groupId>io.github.java-native</groupId>
<artifactId>jssc</artifactId>
<version>2.9.4</version>
</dependency>
jscc - более старая библиотека, которая работала без нареканий до последнего времени. Сейчас обнаружились проблемы в работе на GraalVM и с последними обновлениями Windows 10. firmata4j использовала jssc по-умолчанию во всех версиях до 2.3.9.
jSerialComm показала себя как рабочий вариант на GraalVM и с последними обновлениями Windows 10.
Основной сценарий использования:
// создать экземпляр устройства Firmata
IODevice device = new FirmataDevice("/dev/ttyUSB0"); // используя имя порта
// IODevice device = new FirmataDevice(new NetworkTransport("192.168.1.18:4334")); // используя сетевой адрес
// подписаться на события при помощи device.addEventListener(...);
// и/или device.getPin(n).addEventListener(...);
device.start(); // начать обмен сообщениями с устройствами
device.ensureInitializationIsDone(); // дождаться окончания инициализации
// здесь можно послать команды устройству
device.stop(); // остановить обмен сообщениями с устройством
Отправка команд устройству может привести к возникновению событий на устройстве. Зарегестрированные обработчики событий получают оповещения о событиях асинхронно. Обработчики могут быть добавлены и удалены в любое время.
Обработчик может быть зарегистрирован для получения событий устройства или его портов.
device.addEventListener(new IODeviceEventListener() {
@Override
public void onStart(IOEvent event) {
// с этого момента можно быть уверенным, что устройство инициализировано
// можно спрятать индикатор загрузки и начать делать интересные вещи
System.out.println("Устройство готово");
}
@Override
public void onStop(IOEvent event) {
// с этого момента можно быть уверенным, что устройство было остановлено
System.out.println("Устройство остановлено");
}
@Override
public void onPinChange(IOEvent event) {
// здесь мы реагируем на изменение состояния порта
Pin pin = event.getPin();
System.out.println(
String.format(
"Порт %d перешёл в состояние %d",
pin.getIndex(),
pin.getValue())
);
}
@Override
public void onMessageReceive(IOEvent event, String message) {
// здесь мы реагируем на получение текстовых сообщений от устройства
System.out.println(message);
}
});
Чтобы получить более детальный контроль, можно подписаться на обработку событий одного конкретного порта.
Pin pin = device.getPin(2);
pin.addEventListener(new PinEventListener() {
@Override
public void onModeChange(IOEvent event) {
System.out.println("Изменился режим порта");
}
@Override
public void onValueChange(IOEvent event) {
System.out.println("Изменилось значение порта");
}
});
Режим и значение порта можно изменить:
pin.setMode(Pin.Mode.OUTPUT); // наши обработчики получат оповещение об этом изменении
pin.setValue(1); // ... а после и об этом изменении
firmata4j поддерживает взаимодействие с I2C устройствами. Получить ссылку на I2C устройство можно следующим способом:
IODevice device = new FirmataDevice(port);
...
byte i2cAddress = 0x3C;
I2CDevice i2cDevice = device.getI2CDevice(i2cAddress);
Во многих случаях удобнее написать обёртку для класса I2CDevice
под конкретное устройство, чтобы облегчить и сократить написание кода. Пример
такого подхода продемонстрирован в классах
SSD1306
и
I2CExample
.
firmata4j позволяет отослать произвольное бинарное сообщение устройству. Например, установка интервала измерений значения аналоговых портов (sampling intervall) с использованием низкоуровневого сообщения:
device.sendMessage(FirmataMessageFactory.setSamplingInterval(12));
Также поддерживаются обработчики низкоуровневых событий. Они могут быть полезны для отладки или обработки сообщений от устройства с модифицированной имплементацией Firmata.
device.addProtocolMessageHandler(FirmataEventType.SYSEX_CUSTOM_MESSAGE, new Consumer<Event>() {
@Override
public void accept(Event evt) {
byte[] message = (byte[]) evt.getBodyItem(FirmataEventType.SYSEX_CUSTOM_MESSAGE);
byte messageType = message[0];
// и так далее
}
});
Обработчики низкоуровневых событий помогают имплементировать контроль подключения к устройству:
IODevice device = new FirmataDevice(port);
//...
FirmataWatchdog watchdog = new FirmataWatchdog(3000, new Runnable() {
@Override
public void run() {
// действия, если в течение 3000 мс не произошло ни одного низкоуровневого события
}
});
device.addProtocolMessageHandler(FirmataEventType.ANY, watchdog);
//...
device.start();
FirmatWatchdog
активируется первым с момента регистрации сообщением. Поэтому
экземпляр FirmatWatchdog
должен быть зарегистрирован до начала взаимодействия
с устройством.
Визуальное представление состояний портов устройства можно получить при помощи
компонента JPinboard
.
JPinboard pinboard = new JPinboard(device);
JFrame frame = new JFrame("Pinboard Example");
frame.add(pinboard);
frame.pack();
frame.setVisible(true);
JPinboard
позволяет установить режим порта из контекстного меню. Состояние
порта вывода может быть изменено двойным щелчком на его изображении.
Пример использования JPinboard
может быть найден в классе
org.firmata4j.Example
.
firmata4j придерживается версий протокола Firmata. Первая доступная версия firmata4j - 2.3.1.
firmata4j-2.3.x будет работать с Fimata v. 2.3.x. На самом деле она заработает и с Firmata v. 2.x.x, но не обязательно будет поддерживать все функции, заявленые протоколом. Первые номера в версиях должны обязательно совпадать, потому что они означают значительные (несовместимые) изменения в протоколе.
Arduino IDE содержит реализацию протокола Firmata. Чтобы загрузить её на Arduino, нужно сделать следущее:
- Подключить Arduino к компьютеру
- Запустить Arduino IDE
- Выбрать
File -> Examples -> Firmata -> StandardFirmata
в меню IDE - Выбрать устройство в
Tools -> Board
- Выбрать порт в
Tools -> Port
(уже выбрано, если вы ранее загружали что-либо на Arduino) - Нажать кнопку
Upload
Обратите внимание, что firmata4j фокусируется на том, чтобы работать с
прошивкой StandardFirmata
. Несмотря на то, что существуют другие прошивки с
поддержкой Firmata, некоторые из них поддерживают только избранные функции
протокола. Чтобы firmata4j смогла пройти инициализацию, прошивка должна
отвечать на следующие запросы:
REPORT_FIRMWARE
CAPABILITY_QUERY
PIN_STATE_QUERY
ANALOG_MAPPING_QUERY
- Easy Peripherals for the Internet of Things
- Modelovanie a Riadenie Hybridných Systémov s Využitím Petriho Sietí Vyšších Úrovní
- Programmazione di Sistemi Embedded con Linguaggi ad Agenti: un Caso di Studio basato su Jason e Arduino
- Использование firmata4j в Clojure
Помощь в развитии библиотеки всегда приветствуется. Если вы нашли ошибку или хотите предложить идею новой функции, пожалуйста, создайте запрос.
Если вы хотите улучшить библиотеку, пожалуйста, сделайте следующее:
- Сделайте
fork
этого репозитория - Склонируйте свой
fork
на локальный компьютер (git clone https://github.com/<your_username>/firmata4j.git
) - Создайте feature branch (
git checkout -b my-new-feature
) - Внесите необходимые изменения в код
- Примените ваши изменения(
git commit -am 'Adds some feature'
) - Отправьте изменения на сервер (
git push origin my-new-feature
) - Создайте Pull Request
firmata4j распространяется по лицензии MIT. Текст лицензии находится в файле LICENSE.