Создание робота, управляемого по телефону, с использованием Node.js, RN-XV WiFly, Arduino и Twilio

Автор: | 20.07.2026

*Присоединяйтесь к обсуждению на Hacker News!*

*Этот пост использует модуль Twilio для Node.js и REST API сообщений Twilio*

Twilio, Arduino, Node.js и модуль RN-XV WiFly. Прежде всего, я хотел бы показать вам, как выглядит готовый робот в действии:

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

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

Схема подключения довольно проста и требует минимальной пайки.

**Шаг 1:** Подключите беспроводной SD-шилд к вашему Arduino.

**Шаг 2:** Подключите светодиод к цифровому выводу 13 и GND. Обратите внимание, что более короткий вывод светодиода — это GND.

**Шаг 3а:** Подключите линии +5V и GND от двух сервоприводов к макетной плате. Я использовал перемычки M/M, так как мои сервоприводы изначально имели 3-контактные разъемы типа «мама».

**Шаг 3б:** Проведите перемычки M/M от макетной платы к слотам питания 5V и GND на Arduino.

**Шаг 3в:** Подключите сигнальный провод левого сервопривода к цифровому выводу 10 на Arduino, а сигнальный провод правого сервопривода — к цифровому выводу 9.

**Шаг 4а:** Подключите питание +5V и GND сонара к макетной плате. Для этого я припаял разъемы к модулю сонара, чтобы его было легче подключать. Затем я использовал перемычки M/F для подключения к макетной плате.

**Шаг 4б:** Подключите выход PWM сонара к цифровому входу 5 на Arduino.

**Шаг 5:** Подключите модуль RN-XV WiFly к беспроводному SD-шилду. Обратите внимание, что я рекомендую делать это после загрузки программы на Arduino, так как у меня возникало много проблем с загрузкой, когда модуль RN-XV был подключен.

**Шаг 6:** Здесь вы прикрутите все детали к шасси. Я не включил пошаговые инструкции для этой части, так как это будет зависеть от того, как вы хотите установить шасси, но в моей модели есть два колеса, каждое из которых подключено к одному из двигателей, и одно свободно вращающееся колесо спереди. Arduino и макетная плата находятся в держателе SparkFun Arduino+Breadboard и приклеены к верхней части робота. У меня также есть 9V батарея, приклеенная к нижней части робота для питания Arduino.

Программная часть для Arduino относительно проста. Начнем с базового метода setup(), добавив в него только функции настройки WiFly. Обратите внимание, что мы используем эту библиотеку WiFly от jcrouchley. Вам нужно будет скачать её и поместить в каталог библиотек вашей Arduino IDE. После этого вы можете создать новый скетч и начать его с следующего кода:

Этот код в основном самодокументируемый, однако одна область, которая вызвала у меня затруднения в начале, заключается в том, что вам нужно открыть последовательный порт для использования модуля WiFly. Это связано с подключением беспроводного SD-шилда — он использует порты RX/TX Arduino, которые обычно используются для нативных последовательных соединений, для связи с RN-XV (который настраивается командами, отправляемыми через последовательный порт). Из-за этого мы должны явно указать библиотеке WiFly использовать нативный объект Serial на скорости 9600 бод.

Единственная возможная проблема заключается в том, что вы не можете использовать монитор последовательного порта или команды Serial.print, так как WiFly занял обычный порт. С этим скетчем вы сможете установить соединение WiFi и открыть TCP-сокет к произвольному серверу Node.js (который мы еще не создали). Далее мы можем добавить код в нашу функцию loop(), чтобы Arduino включал светодиод при подключении к серверу Node.js и принимал TCP-ответ от сервера.

Затем мы можем добавить этот код в нашу функцию setup() для настройки вывода светодиода:

Теперь, когда мы можем установить TCP-соединение и включать/выключать свет для индикации открытого TCP-сокета, мы можем перейти к самой интересной части этого робота — движению! Первым шагом будет добавление следующих определений в начало вашего скетча:

Расположение выводов довольно простое, однако вы также заметите переменные rightStopPos и leftStopPos. Они указывают остановленные позиции сервоприводов с непрерывным вращением.

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

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

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

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

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

Вам нужно будет добавить следующие определения для настройки входа MaxSonar:

Теперь, когда модуль сонара правильно настроен, мы можем добавить способ для его связи с нашим сервером. Для этого мы просто будем отвечать расстоянием, обнаруженным в дюймах, всякий раз, когда Arduino получает ‘5’ на TCP-входе. Это добавляется в функцию loop():

На этом всё для части кода Arduino, я рекомендую вам дважды проверить свой скетч по завершенному примеру здесь.

Теперь, когда наш скетч для Arduino готов, мы можем приступить к написанию серверной части нашего маленького TwilioBot. Я решил написать серверную часть на Node.js просто из-за простоты поддержания TCP-сокета с Arduino и одновременного общения с Twilio в реальном времени.

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

npm install twilio-api@0.3.0

npm install express@»>=3.0″

Теперь, когда наши пакеты npm установлены, мы можем начать настройку нашего приложения. Первым делом войдите в свой аккаунт и перейдите в Панель управления. Если вы новичок на платформе, я рекомендую посмотреть наш первый туториал Quickstart для информации о том, как настроить аккаунт и приобрести номер телефона.

Как только у вас будет аккаунт и номер телефона, вам нужно будет создать новое TwiML-приложение на вкладке Apps в вашей Панели управления. Затем вы можете указать URL вашего сервера (с портом 8002) в полях SMS и Voice Request URL, а также в полях Status Callback URL. Это должно выглядеть примерно так:

Затем вы можете вернуться на вкладку Numbers и настроить ваш номер телефона для использования вашего недавно созданного приложения:

Теперь, когда ваш номер телефона настроен правильно, вы можете начать писать немного JavaScript. В server.js добавьте следующий код:

Это просто настраивает новый сервер express на порту 8002 для связи с Twilio и TCP-сервер на порту 1337 для связи с вашим Arduino. Обратите внимание, что вам нужно будет либо изменить вызов twilioAPI.Client с вашим Account Sid и Auth Token, либо отредактировать переменные окружения и установить ваш account_sid и auth_token (используя команду export в Linux).

В этом примере мы используем пакет Node-Twilio-API как middleware для express — он автоматически генерирует все ваши маршруты и ответы TwiML.

Теперь добавьте следующий JavaScript в конец вашего файла server.js. Эта часть скрипта настраивает ваше существующее TwiML-приложение, которое мы создали выше. Обратите внимание, что вам нужно будет либо изменить вызов getApplication с вашим app_sid, либо установить переменную окружения, как мы сделали выше.

Этот фрагмент кода настраивает наш callback incomingCall. Он определяет, подключен ли наш бот к серверу Node.js, и если да, то собирает цифры, которые используются для управления ботом, и передает их в функцию обратного вызова getDigits. Вы также можете заметить, что мы также устанавливаем глобальную переменную curr_call для хранения текущего объекта вызова — это будет использовано позже.

Теперь мы можем создать функцию обратного вызова getDigits, на которую мы ссылались в нашем начальном TwiML:

Эта функция снова определяет, подключен ли наш бот, и также добавляет дополнительную проверку нажатых цифр, чтобы убедиться, что бот может их обработать. Если это допустимая цифра, мы передаем её нашему боту через наше TCP-соединение и затем собираем следующую командную цифру.

И наконец, мы настраиваем наш TCP-сервер, к которому подключается наш бот:

У нас есть глобальная переменная (arduinoTcp), установленная для отслеживания сокета нашего бота, так как это приложение не может управлять несколькими роботами. Вы также заметите, что curr_call снова появляется здесь — это чтобы прервать наш текущий поток вызова и передать данные от нашего датчика сонара. Мы называем это «модификацией живого вызова», и это позволяет нам остановить сбор следующей цифры и вместо этого вывести количество дюймов, на которое наш бот удален от объекта перед ним, а затем снова собрать цифры, чтобы мы могли продолжить его управление.

На этом всё для части кода на Node.js, не стесняйтесь сравнить ваш код с завершенным скриптом server.js здесь.

На этом всё для программной части TwilioBot. Полный исходный код можно найти на GitHub по адресу jonmarkgo/TwilioBot. Я призываю вас выйти и создать своего собственного робота, управляемого по телефону! Я приветствую наших будущих роботов-повелителей.

Если у вас есть какие-либо вопросы, отзывы или гневные тирады о том, как ваш робот запер вас вне дома, пожалуйста, не стесняйтесь написать в Твиттер @jonmarkgo или отправить мне письмо на jonmarkgo@twilio.com.