Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Управление Arduino Rover с помощью Firmata и контроллера Xbox One

Компоненты и расходные материалы

Контроллер Microsoft Xbox и беспроводной адаптер для Windows
Этот контроллер можно добавить к ПК с Windows с помощью адаптера
× 1
Bluetooth-модем SparkFun - BlueSMiRF Silver
Или идентичный (HC-05, HC-06) модуль Bluetooth
× 1
Arduino UNO
× 1

Приложения и онлайн-сервисы

Microsoft Windows 10 IoT Core
Это приложение является промежуточным между стандартным эскизом Firmata и контроллером Xbox One

Об этом проекте

Несколько месяцев назад я купил маленький вездеход (управляемый Arduino Uno) по очень хорошей цене. Набор был очень полным:автомобильное шасси, 2 автомобильных колеса, 2 мотор-редуктора постоянного тока, UNO R3, двойной H-мостовой контроллер двигателя L298N и несколько других компонентов.

Этот марсоход предназначен для автономной работы. Следовательно, в комплект также добавляются ультразвуковой датчик и сервопривод. Также в комплекте хороший сенсорный экран 5 Arduino. Да, это была выгодная сделка;-)

Но моя идея заключалась в том, чтобы использовать как контроллер Xbox One, так и протокол Firmata, чтобы управлять им один или один из моих сыновей. И работает очень хорошо!

Вот видео окончательного решения:

В этом проекте используются следующие основные части:

  • Комплект ровера (для этой демонстрации мы используем только часть деталей:опорную пластину, колеса, двигатели, Arduino Uno, держатель батареи на 9 В и контроллер двигателя L298N с двойным мостом H-Bridge)
  • Дополнительный батарейный отсек для 6 батареек AA.
  • Модуль Bluetooth (HC-06)
  • Контроллер Xbox One с беспроводным адаптером для Windows (для подключения к ноутбуку)
  • Ноутбук (с Windows 10 + VS2015 + адаптер Bluetooth)
  • Мигающий свет только для драматического эффекта.

Сборка комплекта

Собрать комплект не так уж и сложно. Хотя инструкция по сборке была на китайском языке, все кажется довольно логичным. Опорная плита только одна, поэтому мне пришлось положить некоторые компоненты сверху, а некоторые - снизу (теперь контроллер мотора):

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

Подключение двигателей - разводка контактов контроллера

На этот раз самое главное оборудование - это не Arduino Uno, а контроллер двигателя.

«L298 - это двойной H-мостовой драйвер для щеточных двигателей постоянного тока и шаговых двигателей. Он поддерживает широкий диапазон рабочих напряжений и может выдавать 2 А на канал в сквозном корпусе, доступном для самостоятельных проектов ».

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

Схема расположения контактов двойного H-мостового контроллера двигателя L298N:

  • Плюс + двигателя постоянного тока 1
  • Минус - двигателя постоянного тока 1
  • Включение питания. Я питаю 9 вольт от отдельного батарейного отсека.
  • Общие точки соприкосновения. Подключен как к моему отдельному держателю батареи, так и к Arduino.
  • Отключение . Может выдавать 5 вольт ( не используется . Моя Arduino получает питание от другого держателя батареи)
  • ENA подключена к Arduino D10. Этот порт поддерживает ШИМ (белый цвет)
  • IN1 подключен к Arduino D9. (серый)
  • IN2 подключен к Arduino D8. (фиолетовый)
  • IN3 подключен к Arduino D7. (синий)
  • IN4 подключен к Arduino D6. (зеленый)
  • ENB подключен к Arduino D5. Этот порт поддерживает ШИМ (желтый)
  • Плюс + двигателя постоянного тока 2
  • Минус - двигателя постоянного тока 2
  • Перемычка рядом с цифрами 2 и 3 НЕ удаляется потому что я не превышаю входную мощность более 12 вольт (до 35 вольт) (перемычка не отмечена на картинке)

Примечание:контроллер имеет собственный источник питания. У Arduino тоже есть. Чтобы все работало, дайте им общий язык . См. Пункт 4 выше)

Подключение двигателей - схема контактов Arduino

Подключить Arduino довольно просто. Подключаем землю и 5 вольт блока питания к Arduino. И мы подключаем шесть линий (ENA, IN1-4 и ENB) к контактам с D10 по D5.

Должно быть ясно, что порты 7 и 8 (а также 9 и 10 для другого двигателя) являются обычным портом GPIO. Они будут использоваться для направления двигателя. Если оба порта (например, 7 и 8) в НИЗКОМ состоянии, двигатель ничего не сделает (остановится). Если один ВЫСОКИЙ, а другой НИЗКИЙ, двигатель будет вращаться в одном направлении. При обратном подключении (первый установлен на НИЗКИЙ, а другой - на ВЫСОКИЙ), подключенный двигатель будет работать в другом направлении.

Но .. просто установка этих контактов ни к чему не приведет. Пока нет движущихся частей!

Магия будет исходить от контактов 5 и 10. Это «специальные» контакты, которые могут генерировать сигнал ШИМ. Установка значения от 0 до 255 приведет к работе двигателя ОЧЕНЬ медленно (остановлен) или на высокой скорости.

Примечание. Каждый порт Arduino Uno, поддерживающий ШИМ, отмечен тильдой (~).

Подключение Bluetooth

Модуль Bluetooth, который я использую, нужно подключить только к портам RX и TX (пересекайте линии), и ему требуется питание 5 В и заземление от Arduino.

Скетч фирмы на Arduino

Скетч Firmata StandardFirmata - это все, что нам нужно на Arduino! Просто возьмите его из примеров Arduino IDE и загрузите (возможно, вам нужно сначала открепить TX / RX, чтобы завершить загрузку).

Примечание:из-за низкого качества моего модуля Bluetooth я всегда снижаю скорость передачи, которая жестко запрограммирована внутри скетча, и устанавливаю ее на 9600.

Господа, заводите двигатели

Или проверьте соединение…

Так почему я использую Firmata? потому что это легко. Как легко? Очень просто. И это можно сделать даже без программирования. Просто запустите приложение Windows Remote Arduino Experience (доступно в магазине и также работает на устройстве с Windows 10 Mobile).

Сначала вам нужно будет подключиться к уже спаренному Bluetooth-модулю HC-6.

После сопряжения перейдите на страницу ШИМ. Включите цифровой вывод 5 и присвойте ему значение, скажем, 128.

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

Затем перейдите на цифровую страницу. И нажмите переключатель цифрового контакта 6.

Теперь, если все подключено и работает, один из двигателей будет вращаться!

Если это так, вы можете проверить другие скорости (используя более высокое или меньшее значение ШИМ) или изменить направление (установите цифровой вывод 6 на 0 В, а цифровой вывод 7 на 5 В).

Вот и все. Вы можете управлять этим колесом!

Но это еще не все, то же самое касается контакта 10 (ШИМ), цифрового контакта 9 и цифрового контакта 8.

Оба колеса ходят. Теперь приступим к кодированию…

Приложение UWP как средство поиска матчей

Должно быть ясно, что нам нужно новое приложение UWP между контроллером Xbox One и ровером.

Я уже писал здесь об использовании контроллера Xbox One. На этот раз мы объединим эти знания с нашим вездеходом.

Давайте посмотрим на интерфейс нашего приложения UWP:

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

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

Примечание. Если вы запустите новое приложение UWP, не забудьте добавить возможность Bluetooth. И вам нужно будет установить пакет nuget для Firmata.

Сначала мы добавляем фрагмент XAML (см. Раздел кода для исходного кода Xaml) в сетку основной формы, чтобы у нас было несколько кнопок.

Затем мы добавляем код (см. Раздел кода для исходного кода C #) основной формы. Я в основном разделен на две части. Сначала мы устанавливаем соединение через Bluetooth с протоколом Firmata. Затем мы начинаем прослушивать ввод на контроллере Xbox One.

В цикле проверки элементов управления мы решаем, направлен ли ползунок вперед или назад или находится в диапазоне «стоп». После этого мы решаем, какое значение будет у вывода ШИМ.

Интересно видеть, что запись значения ШИМ представлена ​​в Firmata как запись аналогового значения в цифровой порт. В классе Arduino нет специального метода ШИМ.

Я добавил два метода «ArduinoDigitalWrite» и «ArduinoAnalogWrite», чтобы предотвратить повторную запись одного и того же значения в Arduino. Это загромождает связь и снижает производительность Arduino. (В гораздо более богатой конструкции я добавил зуммер. Без игнорирования повторяющихся команд работа зуммера была очень плохой и ужасно слышной).

Когда двигатели получают низкие импульсы PMW, двигатель не запускается напрямую, он будет завывать с очень характерным звуком. Это нормальное поведение. Так я узнал, что мне нужно добавить два источника питания. Первый раз все подключил, подумал, что контроллер сломался. Ничего не случилось. Пока я не отключил один из двигателей, и другой не начал скулить.

Вот как это работает:

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

Код

  • Элементы управления Xaml для начала взаимодействия
  • Внутренний код основной формы приложения UWP.
Элементы управления Xaml для запуска обмена сниппетов
Вставьте это в основную форму вашего нового приложения UWP
  
Внутренний код основной формы приложения UWP C #
Этот код подключается к роверу с помощью Firmata и передает команды контроллера Xbox One
 публичный запечатанный частичный класс MainPage:Page {private BluetoothSerial _bluetooth; частный RemoteDevice _arduino; частный UwpFirmata _firmata =null; частный геймпад _Gamepad =null; // Мы никогда не предоставляем ШИМ больше 255 * 0,75 private double _SpeedLimit =0.75; // значения ниже этого абсолютного значения останавливают ровер private double _ActionPoint =0.15; закрытый байт _LeftForward =6; закрытый байт _LeftBackward =7; закрытый байт _LeftValue =5; закрытый байт _RightForward =9; закрытый байт _RightBackward =8; закрытый байт _RightValue =10; частный словарь  _CurrentPinStates =new Dictionary  (); частный словарь  _CurrentSpeedValues ​​=new Dictionary  (); общедоступная MainPage () {this.InitializeComponent (); } private void btnStart_Click (отправитель объекта, RoutedEventArgs e) {btnStart.IsEnabled =false; Gamepad.GamepadAdded + =Gamepad_GamepadAdded; Gamepad.GamepadRemoved + =Gamepad_GamepadRemoved; _bluetooth =новый BluetoothSerial ("HC-06"); _bluetooth.ConnectionLost + =BluetoothConnectionLost; _bluetooth.ConnectionFailed + =BluetoothConnectionFailed; _bluetooth.ConnectionEstablished + =OnConnectionEstablished; _firmata =новый UwpFirmata (); _arduino =новое удаленное устройство (_firmata); _firmata.begin (_bluetooth); _bluetooth.begin (9600, SerialConfig.SERIAL_8N1); _arduino.DeviceReady + =ArduinoDeviceReady; } private async void BluetoothConnectionLost (строковое сообщение) {ожидание Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="ConnectionLost" + message; btnStart.IsEnabled =true;}); } private async void BluetoothConnectionFailed (строковое сообщение) {ожидание Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="ConnectionFailed" + message; btnStart.IsEnabled =true;}); } private async void ArduinoDeviceReady () {ожидание Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="Устройство готово";}); } private void OnConnectionEstablished () {var action =Dispatcher.RunAsync (CoreDispatcherPriority.Normal, new DispatchedHandler (() => {DisableEnableButtons (true); ArduinoDigitalWrite (_LeftForward, PinStateLOW); (_RightBackward, PinState.LOW); ArduinoDigitalWrite (_RightForward, PinState.LOW);})); } private void DisableEnableButtons (bool enabled) {// Отключить все кнопки. В противном случае // 'A' будет нажимать на тот, который находится в фокусе. btnController.IsEnabled =включен; btnStart.IsEnabled =включен; } private async void Gamepad_GamepadRemoved (отправитель объекта, Gamepad e) {_Gamepad =null; await Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="Контроллер удален";}); } private async void Gamepad_GamepadAdded (отправитель объекта, Gamepad e) {_Gamepad =e; ждать Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {tbRead.Text ="Контроллер добавлен";}); } private async void btnController_Click (отправитель объекта, RoutedEventArgs e) {DisableEnableButtons (false); while (true) {ожидание Task.Delay (TimeSpan.FromMilliseconds (3)); если (_Gamepad ==null) {продолжить; } // Получить текущее состояние var read =_Gamepad.GetCurrentReading (); если (Math.Abs ​​(чтение.LeftThumbstickY) <_ActionPoint) {ArduinoDigitalWrite (_LeftForward, PinState.LOW); ArduinoDigitalWrite (_LeftBackward, PinState.LOW); sldrLeftSpeed.Value =0; } иначе, если (чтение.LeftThumbstickY> =_ActionPoint) {ArduinoDigitalWrite (_LeftForward, PinState.HIGH); ArduinoDigitalWrite (_LeftBackward, PinState.LOW); sldrLeftSpeed.Value =255 * Math.Abs ​​(чтение.LeftThumbstickY) * _SpeedLimit; } иначе, если (чтение.LeftThumbstickY <=-_ActionPoint) {ArduinoDigitalWrite (_LeftForward, PinState.LOW); ArduinoDigitalWrite (_LeftBackward, PinState.HIGH); sldrLeftSpeed.Value =255 * Math.Abs ​​(чтение.LeftThumbstickY) * _SpeedLimit; } если (Math.Abs ​​(read.RightThumbstickY) <_ActionPoint) {ArduinoDigitalWrite (_RightForward, PinState.LOW); ArduinoDigitalWrite (_RightBackward, PinState.LOW); sldrRightSpeed.Value =0; } иначе, если (чтение.RightThumbstickY> =_ActionPoint) {ArduinoDigitalWrite (_RightForward, PinState.HIGH); ArduinoDigitalWrite (_RightBackward, PinState.LOW); sldrRightSpeed.Value =255 * Math.Abs ​​(чтение.RightThumbstickY) * _SpeedLimit; } иначе, если (чтение.RightThumbstickY <=-_ActionPoint) {ArduinoDigitalWrite (_RightForward, PinState.LOW); ArduinoDigitalWrite (_RightBackward, PinState.HIGH); sldrRightSpeed.Value =255 * Math.Abs ​​(чтение.RightThumbstickY) * _SpeedLimit; }}} private void ArduinoDigitalWrite (байтовый порт, состояние PinState) {// игнорировать повторяющиеся команды var exists =_CurrentPinStates.ContainsKey (port); если (! существует || _CurrentPinStates [порт]! =состояние) {_CurrentPinStates [порт] =состояние; _arduino.digitalWrite (порт, состояние); }} private void ArduinoAnalogWrite (порт байта, значение ushort) {// игнорировать повторяющиеся команды var exists =_CurrentSpeedValues.ContainsKey (port); если (! существует || _CurrentSpeedValues ​​[порт]! =значение) {_CurrentSpeedValues ​​[порт] =значение; _arduino.analogWrite (порт, значение); }}} 

Производственный процесс

  1. Система посещаемости с использованием Arduino и RFID с Python
  2. Универсальный пульт дистанционного управления с использованием Arduino, 1Sheeld и Android
  3. Вольтметр своими руками с использованием Arduino и смартфона
  4. Использование Интернета вещей для удаленного управления манипулятором
  5. Измерение частоты и рабочего цикла с использованием Arduino
  6. Сонар с использованием Arduino и отображение при обработке IDE
  7. Управление яркостью светодиода с помощью Bolt и Arduino
  8. Простая и умная роботизированная рука с использованием Arduino
  9. Полный контроль над вашим телевизором с помощью Alexa и Arduino IoT Cloud
  10. FM-радио с использованием Arduino и RDA8057M