Java arduino processing

Связываемся с Processing

При работе с платой Arduino мы иногда выводим результат на Serial Monitor. Но это не единственная возможность для получения данных на экране. Например, вы можете воспользоваться программой Processing.

Когда вы установите эту программу, то удивитесь — насколько она похожа на Arduino IDE. Не удивляйтесь, обе программы сделаны на одном движке.

Приложение Processing имеет очень много возможностей, в том числе и библиотеку Serial, поэтому мы можем связать передачу данных между платой и Processing.

Запустим Arduino IDE и выберем простейший пример вывода данных на Serial Port:

Запустим пример и убедимся, что код работает.

Получение строковых данных из микроконтроллера

Теперь мы хотим получить этот же текст в Processing. Запускаем новый проект и напишем код.

Первый шаг — импортировать библиотеку. Идем в Sketch | Import Library | Serial. В скетче появится строка:

Далее объявляем переменные, создаём обязательные функции. Обратите внимание, что в отличии от скетчей Arduino, в скетчах Processing используется функция draw() вместо loop().

Чтобы обеспечить прием данных с последовательного порта, нам нужен объект класса Serial. Так как с Arduino мы отправляем данные типа String, нам надо получить строку и в Processing.

В методе setup() нужно получить доступный последовательный порт. Как правило, это первый доступный порт из списка. После этого мы можем настроить объект Serial, указав порт и скорость передачи данных (желательно, чтобы скорости совпадали).

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

Processing позволяет работать не только с консолью, но и создавать стандартные окна. Перепишем код.

Запустим пример ещё раз и увидим окно с надписью, которое перерисовывается в одном месте.

Таким образом мы научились получать данные от Arduino. Это позволит нам рисовать красивые графики или создавать программы контроля за показаниями датчиков.

Получение числовых данных из микроконтроллера

Получение строк во многих случаях избыточно. Нам вполне хватит пары чисел 0 и 1, чтобы узнать, что кнопка нажата или нет. Возьмём пример 01.Basics: DigitalReadSerial (Чтение цифрового вывода) и немного модифицируем его.

Мы посылаем состояние кнопки. Осталось написать код для Processing. Создадим окно с квадратом. В обычном состоянии квадрат будет серым, при нажатии кнопки он станет зелёным.

Отправка данных

Мы можем не только получать данные с платы, но и отправлять данные на плату, заставляя выполнять команды с компьютера.

Допустим, мы будем посылать символ «1» из Processing. Когда плата обнаружит присланный символ, включим светодиод на порту 13 (встроенный).

Скетч будет похож на предыдущий. Для примера создадим небольшое окно. При щелчке в области окна будем отсылать «1» и дублировать в консоли для проверки. Если щелчков не будет, то посылается команда «0».

Теперь напишем скетч для Arduino.

Запускаем оба скетча. Щёлкаем внутри окна и замечаем, что светодиод загорается. Можно даже не щёлкать, а удерживать кнопку мыши нажатой — светодиод будет гореть постоянно.

Обмен данными

Теперь попытаемся объединить оба подхода и обмениваться сообщениями между платой и приложением в двух направлениях.

Для максимальной эффективности добавим булеву переменную. В результате у нас отпадает необходимость постоянно отсылать 1 или 0 от Processing и последовательный порт разгружается и не передает лишнюю информацию.

Когда плата обнаружит присланную единицу, то меняем булевое значение на противоположное относительно текущего состояния (LOW на HIGH и наоборот). В else используем строку «Hello Kity», которую будем отправлять только в случае, когда не обнаружим ‘1’.

Функция establishContact() отсылает строку, которую мы ожидаем получить в Processing. Если ответ приходит, значит Processing может получить данные.

Переходим к скетчу Processing. Мы будем использовать метод serialEvent(), который будет вызываться каждый раз, когда обнаруживается определенный символ в буфере.

Добавим новую булеву переменную firstContact, которая позволяет определить, есть ли соединение с Arduino.

В методе setup() добавляем строку serial.bufferUntil(‘\n’);. Это позволяет хранить поступающие данные в буфере, пока мы не обнаружим определённый символ. В этом случае возвращаем (\n), так как мы отправляем Serial.println() от Arduino. ‘\n’ в конце значит, что мы активируем новую строку, то есть это будут последние данные, которые мы увидим.

Так как мы постоянно отсылаем данные, метод serialEvent() выполняет задачи цикла draw(), то можно его оставить пустым.

Теперь рассмотрим основной метод serialEvent(). Каждый раз, когда мы выходим на новую строку (\n), вызывается этот метод. И каждый раз проводится следующая последовательность действий:

  • Считываются поступающие данные;
  • Проверяется, содержат ли они какие-то значения (то есть, не передался ли нам пустой массив данных или «нуль»);
  • Удаляем пробелы;
  • Если мы первый раз получили необходимые данные, изменяем значение булевой переменной firstContact и сообщаем Arduino, что мы готовы принимать новые данные;
  • Если это не первый приём необходимого типа данных, отображаем их в консоли и отсылаем микроконтроллеру данные о клике, который совершался;
  • Собщаем Arduino, что мы готовы принимать новый пакет данных.

При подключении и запуске в консоли должна появится фраза ‘Hello Kitty’. Когда вы будете щёлкать мышкой в окне Processing, светодиод на пине 13 будет включаться и выключаться.

Кроме Processing, вы можете использовать программы PuTTy или написать свою программу на C# использованием готовых классов для работы с портами.

04.Communication: Dimmer

Пример демонстрирует, как можно посылать данные из компьютера на плату для управления яркостью светодиода. Данные поступают в виде отдельных байтов от 0 до 255. Данные могут поступать от любой программы на компьютере, которая имеет доступ к последовательному порту, в том числе от Processing.

Для примера понадобится стандартная схема с резистором и светодиодом на выводе 9.

Скетч для Arduino.

Код для Processing

Запускаем Processing и водим мышкой над созданным окном в любую сторону. При движении влево яркость светодиода будет уменьшаться, при движении вправо — увеличиваться.

04.Communication: PhysicalPixel (Зажигаем светодиод мышкой)

Немного изменим задачу. Будем проводить мышкой над квадратом и посылать символ «H» (High), чтобы зажечь светодиод на плате. Когда мышь покинет область квадрата, то пошлём символ «L» (Low), чтобы погасить светодиод.

Код для Arduino.

Код для Processing.

04.Communication: Graph (Рисуем график)

Если в предыдущем примере мы посылали данные с компьютера на плату, то теперь выполним обратную задачу — будем получать данные с потенциометра и выводить их в виде графика.

Подсоедините потенциометр стандартным способом. И код для Arduino.

Код для Processing.

Крутим ручку потенциометра и смотрим за изменениями показаний. Можно заметить, что иногда бывают всплески.

Управляем цифровыми пинами (черновик)

Как-то набросал небольшой черновик для управления цифровыми пинами через Processing. На экране выводятся 13 квадратов для каждого пина в обратном порядке. Можно включать и выключать питание на выводе щелчком. Соответственно, на плате нужно к выводам присоединить светодиоды. В коде задействованы только два светодиода. Проект не стал дорабатываться, но оставил на память для будущих других проектов.

Листинг для Processing

Код для Arduino

Используем кнопки из ControlP5

Спустя некоторое время после создания черновика, наткнулся на библиотеку ControlP5, которая позволяет быстро создать окно с кнопками. Набросал следующий скетч. Пример рассчитан на использование порта COM3.

Соединяем три светодиода с выводами 10, 11, 12. Заливаем скетч на плату, затем запускаем скетч от Processing и нажимаем на кнопки. Первые три кнопки включают отдельные светодиоды, а четвёртая выключает их все сразу.

Источник

Зачем нужно соединять Java-программу на компьютере и Arduino?


Картинка rawpixel

Любой энтузиаст, строящий свои проекты на базе Arduino, рано или поздно сталкивается с необходимостью тем или иным способом обеспечить взаимосвязь этой платы со своим компьютером.

Такой симбиоз даёт возможность как управлять платой с компьютера, так и наоборот — компьютером с платы. Об этом мы и поговорим в этой статье.

Постановка задачи и общие сведения о библиотеке

В рамках этой задачи я не имею в виду стандартное общение самой платы со средой разработки, я имею в виду, что условно необходимо реализовать «прямое» общение платы и компьютера. Конечно, это подразумевает собой наличие на компьютере некой утилиты, которая и будет осуществлять подобное общение.

Подобная программа может быть написана на любом известном вам языке программирования, но так уж исторически сложилось, что я более-менее понимаю java, поэтому разговор далее будет идти только об этом языке и библиотеках под него.

Некоторое время назад для решения подобного вопроса — использовалась библиотека RxTx, однако в её работе отмечаются некоторые проблемы, ввиду необходимости установки DLL под Windows, а также проблемы со стабильностью (судя по ряду мнений активных пользователей этой библиотеки. Возможно, у вас был другой опыт).

Сегодня есть гораздо более простая и удобная в использовании библиотека, которая позволяет организовать общение через COM-порты: jSerialComm.

Она удобна тем, что обеспечивает доступ комфортным, независимым от платформы способом, без использования каких-либо дополнительных инструментов и библиотек.

Подробное описание API этой библиотеки находится по этому адресу:

Так как сама библиотека не содержит достаточно большого количества примеров использования (только самые основные), то наверняка вам пригодится и вот эта подборка, в которой собрано 20 достаточно полезных коротких примеров использования возможностей библиотеки.

Но до начала всех манипуляций, нам необходимо вывести в консоль, и узнать, какие COM-порты у нас вообще доступны:

Библиотека может работать в ряде режимов, которые отличаются степенью блокировки (т.е., ожидания поступления данных).

Например, режимом по умолчанию является неблокирующий: методы, читающие данные, возвратят любые данные, которые доступны. Без какого-либо ожидания:

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

Как раз для работы в таком режиме и предназначен полностью блокирующий способ. Например, в коде ниже, метод readBytes() ждёт запрошенные 1024 байта в течение 1 секунды:

Если нужно, чтобы он бесконечно ждал поступления этих данных, то тогда внесите вот такое изменение в строке, где содержится setComPortTimeouts:

Более подробно обо всех доступных режимах вы можете прочитать здесь.

Также существует полностью асинхронный режим работы, в котором возможно прослушивание ряда событий и реагирование на них. В этом режиме тайм-ауты (всевозможные блокировки) игнорируются:

Например, в коде выше, при наличии любых данных, доступных для чтения — будет запущен обратный вызов.

Также (при желании) вы можете использовать стандартные Java интерфейсы Inputstream, Outputstream, например, так:

Подключаем Arduino к компьютеру

Случай, когда компьютер шлёт данные на Arduino

Теперь вернёмся к нашей задаче общения компьютера с Arduino. Понятно, что задача может быть двоякой: скажем так, «нисходящей» и «восходящей».

То есть, когда инициатором является компьютер или Arduino.

Хороший пример первого варианта можно посмотреть здесь. В нём содержится код как со стороны компьютера, так и со стороны Arduino. Рассмотрим компьютерную сторону:

Мы видим, что код является полностью блокирующим (т.к. мы заранее знаем объём передаваемых данных, когда в цикле с компьютера пересылаем одну цифру на Arduino). Кроме того, следующая строка даёт нам хороший пример того, как нужно конфигурировать порт для общения с Arduino:

Также можно легко заметить (так как инициатором является компьютер), что в этом случае мы используем исходящий с компьютера поток (OutputStream):

Перейдём к стороне Arduino. Здесь всё достаточно стандартно, и для чтения используется простая конструкция:

Случай, когда Arduino шлёт данные на компьютер

А теперь попробуем рассмотреть обратный вариант, когда необходимо общаться, так сказать, в «восходящем» режиме — то есть Arduino шлёт сообщения компьютеру.

Для этого нам надо внести изменения в Java код, а также изменить скетч прошивки Arduino.

Начнём с кода Java. Во-первых, так как в этом случае нужно принимать поток данных, нам необходимо изменить getOutputStream на getInputStream:

Также нам необходимо изменить режим записи — на режим чтения, переключив его на полублокирующий вариант. Как можно увидеть в строке ниже, полублокирующий режим у нас включён таким образом, что мы ждём, пока хотя бы 1 байт данных не будет успешно прочитан (это нули, следующие за выражением TIMEOUT_READ_SEMI_BLOCKING):

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

Как можно заметить из кода, мы сделали так, что поступающие данные из COM-порта читаются в бесконечном цикле.

Скетч Arduino, в свою очередь, достаточно прост и выглядит следующим образом:

Как можно заметить, с периодичностью в одну секунду мы просто пишем байты в COM-порт.

Для чего это всё можно применить?

А теперь попробуем прикинуть, для чего, собственно, вся эта последовательность телодвижений может пригодиться?

Понятно, что способ общения Arduino с компьютером является весьма полезным для целой массы применений, среди которых могут быть и разнообразные погодные станции, и управление системами робототехники и т. д.

Лично мой кейс использования выглядит приблизительно так (для чего, собственно, я это всё и затеял. Уже жду детали из Китая):

Дело в том, что я уже достаточно давно (лет 10) для просмотра телевизора и фильмов, использую видеопроектор. Телевизионный сигнал идёт с подключаемой приставки, а фильмы я смотрю с компьютера. Чтобы мне не нужно было постоянно перетыкать HDMI-кабель в гнездо видеопроектора — я купил специальный разветвитель, который после нажатия кнопки переключает один источник сигнала на другой (это всё можно было и не писать, но так ситуация будет более понятна).

Периодически, когда я смотрю телевизор, я натыкаюсь на ряд фильмов, которые идут по телевизору в SD-качестве. Несмотря на то, что я эти фильмы уже видел 100500 раз — мне всё равно хочется пересматривать их ещё.

В этот момент я вспоминаю, что доступ к этим фильмам есть у меня на компьютере и в отличном качестве. После чего — я иду к компьютеру, включаю фильм, возвращаюсь обратно, переключаю источник сигнала и смотрю фильм уже в хорошем качестве.

То есть, если бы у меня был некий способ, не вставая с дивана включать фильм на компьютере — я вполне мог бы начать смотреть его с минимальными усилиями и без лишних походов.

Тут многие, наверное, скажут: «да купи ты себе беспроводную мышь и не парься!»

На это у меня есть что ответить: раньше так и было, однако однажды у меня родилась мысль, как можно упростить это ещё сильнее!

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

Суть этого способа в двух словах заключается в следующем:

  1. мы подключаем приёмник инфракрасного излучения к Arduino,
  2. загружаем в Arduino специальный скетч, после чего нажимаем на любую нужную кнопку пульта дистанционного управления (например, на ту кнопку, которая у нас обычно ни в чём не задействована). При нажатии на эту кнопку пульт излучает определённый код, который передаётся на Arduino, и отображается в мониторе порта. Записываем этот код (например, на бумажку),
  3. далее мы загружаем в Arduino другой скетч, который является уже исполнителем определённых действий, при получении этого кода на инфракрасный приёмник.

Таким образом, совместив между собой эти два способа (то есть приём и обработку кодов нажатий определённых кнопок на пульте), на подключённой к компьютеру Arduino — с Java программой компьютере, мы можем управлять с инфракрасного пульта процессами, протекающими на компьютере!

Например, в моём случае, я хочу запускать воспроизведение фильмов на компьютере.

Тут следует сделать одну оговорку: дело в том, что пульт управления от видеопроектора у меня неродной (родной вышел из строя) и поэтому я использую программируемый универсальный пульт, в котором у меня используется, дай бог, если 35% от имеющихся на нём кнопок.

Получается, я вполне могу назначить на оставшиеся кнопки весьма широкий набор функций: добавить громкость, убавить громкость, включить воспроизведение, поставить на паузу, перемотка, переключить на другой видеофайл и т.д. и т.п.

Весь проект со стороны компьютера я вижу следующим образом: в компьютер (всегда в один и тот же USB-разъём) будет воткнута самая маленькая Arduino, которая у меня имеется, — Arduino Nano, с подключённым к ней инфракрасным приёмником. Всё это будет выполнено достаточно компактно — в форм-факторе флешки, а корпус будет изготовлен 3D печатью.

Сама java-программа будет добавлена в автозагрузку компьютера.

Скетч для Arduino будет максимально простым. Приблизительно похожим на тот, что вы уже видели выше.

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

Если подумать, применений этому способу может быть очень много. С ходу мне в голову приходит изготовление некоего «презентера», который позволяет запускать файлы на компьютере и выводить их на большой экран во время выступлений на сцене перед большой аудиторией. Это всего лишь одна из идей. А так, думаю, этот способ может быть многим полезен.

Удачи всем в сборке!

НЛО прилетело и оставило здесь промокод для читателей нашего блога:

— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS .

Источник

Adblock
detector