Статьи

PHP, Arduino, и … Minecraft? Подключение Arduino к PHP!

IoTWeek_Gray

Это неделя Интернета вещей в SitePoint! Всю неделю мы публикуем статьи, ориентированные на пересечение интернета и физического мира, поэтому следите за последними обновлениями в теге IoT .

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

Затем мы подключили эту виртуальную тревогу к слушающему PHP-скрипту, чтобы мы могли знать, когда дверь открыта в контексте PHP-скрипта.

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

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

Вы можете найти код для этого руководства по адресу https://github.com/sitepoint-editors/tutorial-php-arduino-and-minecraft/tree/connect-arduino

Ускоренный курс по программированию в Arduino

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

Общим для них является то, что они имеют порты / контакты для подключения к различным компонентам (например, кнопки, датчики и светодиоды) и понимают общие языки программирования. Языки программирования — C и C ++, что является самым сложным для изучения Arduino.

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

Вам понадобится Arduino (или альтернативы, которые будут обсуждаться позже) и сигнальный зуммер или светодиод .

Зуммер и / или светодиод имеют два контакта: один для заземления (иногда обозначается как «gnd» или «-»), а другой — для подключения к порту / выводу Arduino:

Иллюстрация схемы

Я смоделировал это в Fritzing . Это фантастика, и вы должны попробовать!

Далее нам нужно скачать официальную IDE. Зайдите на https://www.arduino.cc/en/Main/Software и загрузите версию, подходящую для вашей операционной системы. Загрузите его, и вы должны увидеть что-то вроде этого:

Снимок экрана Arduino IDE

Основными языками программирования Arduino являются C и C ++. Функции выглядят аналогично функциям PHP 7, где тип возвращаемого значения заменяет ключевое слово function . Итак, мы видим пару методов, которые должны возвращать void (то есть они ничего не должны возвращать).

Функция setup вызывается при запуске Arduino. Как следует из названия, мы можем использовать его для начальной настройки платы. Вы видите эти цифры рядом с каждым контактом / портом на Arduino? Они могут быть использованы для ввода или вывода (цифровой и аналоговый). На самом деле, это хорошая идея, чтобы определить функцию каждого контакта перед его использованием.

Многие платы Arduino поставляются с контактом 13, уже подключенным к светодиоду на плате. Мы можем включить это, используя следующий код:

 void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); } 

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

 ls /dev | grep usbmodem 

Эта команда перечисляет все в /dev (в OSX и большинстве систем Linux мы можем найти имена устройств USB-устройств, подключенных к нашей системе). Затем он берет этот список и передает его через команду Grep, чтобы отфильтровать все элементы, содержащие слово usbmodem .

Принять к сведению предметы возвращены. Если вы не видите ничего, возможно, что-то не так с вашим Arduino или он просто не подключен должным образом. Дайте нам знать, в комментариях, если вы не можете пройти этот шаг …

Вернитесь в Arduino IDE и выберите соответствующий порт Arduino в меню «Инструменты» → «Порт». Хорошо знать фактическое имя устройства, даже если бы вы могли угадать его без команд терминала, так как позднее нам понадобится точное имя.

После того, как вы установили правильный порт и выбрали подходящий тип Arduino (из меню «Инструменты» → «Доска»), вы сможете загрузить пример на доску.

Анимированное изображение используемой IDE

IDE Arduino берет код C или C ++ и компилирует его для байт-кода, понятного плате. Этот процесс написания, компиляции и загрузки кода в Arduino может быть очень медленным для нас, PHP. Мы будем использовать более простой подход в ближайшее время.

Вы можете найти множество примеров программ Arduino через меню «Файл» → «Примеры». Я нашел их бесценными, когда разбирался с синтаксисом C и возможностями платы!

На самом деле, более простой способ проверить, работает ли Arduino и правильно ли он подключен, — загрузить пример «Blink»:

Если вы правильно подключили зуммер или светодиод, вы можете даже изменить скрипт, чтобы установить соответствующий порт на HIGH / Low . Но это медленный и разочаровывающий процесс, когда приходится изучать C и постоянно перезагружать код в Arduino.

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

Знакомый PHP

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

Перейдите к примеру «Примеры» → «Фирма» → «СтандартФирмата» и загрузите его на свой Arduino. Теперь он может общаться через стандартный последовательный интерфейс.

Если вы еще не загрузили код из последнего поста , сейчас самое время сделать это. Мы собираемся построить поверх этого …

Нам нужно добавить новую библиотеку к тем, которые у нас уже есть:

 composer require carica/firmata 

Эта библиотека выступает в роли клиента для стандартного кода Firmata, который мы только что загрузили в Arduino. В index.php мы можем добавить следующий код для подключения к Arduino:

 use Carica\Io; use Carica\Firmata; $board = new Firmata\Board( Io\Stream\Serial\Factory::create( "/dev/cu.usbmodem14141", 57600 ) ); 

Вам обязательно нужно закрыть Arduino IDE, прежде чем пытаться запустить этот код. Он открывает соединения с Arduino, которые блокируют последующие соединения из нашего PHP-скрипта. Если вы не можете подключиться к Arduino в любой момент, просто отключите и снова подключите Arduino к тому же порту USB. Это сломает любые открытые соединения, которые могут блокировать вещи.

Вам нужно заменить cu.usbmodem14141 именем устройства, которое вы получили из команды терминала (или нашли в меню «Инструменты» IDE «Порт»).

Давайте добавим прослушиватель событий, когда скрипт PHP наконец-то подключится к Arduino:

 $board ->activate() ->done( function() use ($board, $loop, $watcher) { $pin = $board->pins[9]; $pin->mode = Firmata\Pin::MODE_PWM; print "connected to Arduino"; } ); $loop->run(); 

Мы можем прикрепить обратный вызов для запуска после того, как PHP-скрипт наконец подключится к плате. Мы должны установить режим вывода / порта Arduino, как мы это делали в C-коде Arduino IDE. На этот раз мы устанавливаем вывод 9 в режим ШИМ (широтно-импульсная модуляция) .

Большинство выводов Arduino можно установить на HIGH или LOW . Устройства, для которых установлено значение HIGH , включатся (загорится светодиод), а значение LOW выключится. ШИМ является инкрементным режимом, где значения от 0 до 255 обеспечивают гранулярный заряд для подключенных устройств. Технически PWM больше похож на быстрое переключение между HIGH и LOW для x / 255 времени, в противном случае он будет установлен на HIGH , но наблюдаемые эффекты одинаковы.

Заметьте, что мы $watcher $loop $watcher и $loop ? $loop является экземпляром цикла обработки событий, который не так часто встречается в приложениях PHP. Если вы не знаете, что такое циклы событий или как они работают, ознакомьтесь с введением, которое мы давали некоторое время назад

Мы можем использовать концепцию, аналогичную JavaScript-функции setInterval , прикрепив обратный вызов к циклу событий, который у нас здесь:

 print "connecting."; $board ->activate() ->done( function() use ($board, $loop, $watcher) { print "connected."; $pin = $board->pins[9]; $pin->mode = Firmata\Pin::MODE_PWM; $loop->setInterval( function() use ($pin, $watcher) { // this is called about every second }, 1000 ); } ); 

Таким образом, вместо использования бесконечного цикла для проверки изменений в файлах журнала, мы можем использовать таймер цикла событий. В сочетании с остальной частью сценария мы можем установить для пина 9 значение от 0 до 255 :

 $loop->setInterval( function() use ($pin, $watcher) { print "check."; $watcher->findChanges(); $changes = $watcher->getUpdatedResources(); if (count($changes) > 0) { $first = $changes[0]; $lines = file($first); for ($i = count($lines) - 1; $i > -1; $i--) { if (stristr($lines[$i], "CHAT")) { if (stristr($lines[$i], "closed")) { print "open."; $pin->analog = 0; // 0/255 } if (stristr($lines[$i], "open")) { print "closed."; $pin->analog = 0.5; // 127/255 } break; } } } }, 1000 ); 

Мы используем примерно тот же код, который мы сделали в прошлый раз. На этот раз вместо того, чтобы писать open или closed для терминала, мы устанавливаем analog значение для контакта 9. analog относится к настройке ШИМ, которую мы сделали ранее. Если бы мы хотели использовать более простые значения HIGH или LOW , мы могли бы установить режим вывода на цифровой:

 $pin->mode = Pin::MODE_OUTPUT; 

… И установите digital значение контакта:

 if (stristr($lines[$i], "closed")) { $pin->digital = 0; } if (stristr($lines[$i], "open")) { $pin->digital = 1; } 

Принеси гориллу

Работая с этим, я обнаружил, что ссылка Arduino / Firmata / OSX иногда была нестабильной. Библиотека Carica Firmata использует несколько различных методов (в зависимости от наличия расширений), и по умолчанию используются собственные потоки сокетов. К сожалению, версия Arduino I автоматически сбрасывается после новых подключений, и Firmata требует небольшой задержки перед установкой связи с Arduino.

Реализация собственного потока сокетов (в Carica Firmata) слишком быстро связывается с платой, что прерывает цикл загрузки. Беда наступает.

Мне удалось избежать этого, установив расширение Gorilla, которое поддерживается Carica Firmata. Вы можете найти инструкции о том, как это сделать, на Github . Создайте и включите расширение Gorilla, и вы не должны испытывать те же проблемы со стабильностью, что и я …

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

Мы успешно реализовали половину схемы внутри Minecraft, а другую половину на Arduino. Кроме того, мы обнаружили один способ соединить их обоих через PHP. Подумайте о возможностях!