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

Управление робот-танком Arduino с беспроводным джойстиком PS2

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

Arduino UNO × 1
Драйвер двигателей L298N (Dual H-Bridge) × 1
Набор для сборки робот-танка (DIY robotic tank kit) × 1
Беспроводной контроллер Sony PS2 × 1
Аккумуляторы 18650 3.7V (3 шт.) × 3
Держатель для 3х аккумуляторов 18650 (3S) × 1
Зарядное устройство для 18650 × 1
Перемычки (male-female, male-male) × 1
USB-кабель Type-B × 1

Инструменты

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

О проекте

В этом уроке показано, как управлять робот-танком с помощью беспроводного джойстика PlayStation 2. В ядре проекта используется плата Arduino Uno. Она принимает команды от контроллера и задаёт скорость двигателей. Принципы можно перенести на другие платы (NodeMCU, FireBeetle и др.) и другие модели роботов.

Ранее я создавал танк под управление через Blynk (Wi-Fi, управление со смартфона: кнопки, слайдеры, акселерометр). Также экспериментировал с голосовым управлением через Google Assistant, Adafruit.io и IFTTT — полезно для людей с ограниченными возможностями. Можно собирать роботов из подручных материалов без 3D-принтеров и лазерной резки.

Управление робот-танком Arduino с беспроводным джойстиком PS2
Управление робот-танком Arduino с беспроводным джойстиком PS2
Управление робот-танком Arduino с беспроводным джойстиком PS2
Управление робот-танком Arduino с беспроводным джойстиком PS2

Шаг 1: Инструменты и материалы

Управление робот-танком Arduino с беспроводным джойстиком PS2

Используемые инструменты: паяльник, ЭВА-пена для изоляции, двусторонний скотч, ножницы.

Железо: Arduino Uno, модуль L298N, набор танка (двигатели, гусеницы, крепеж — инструменты в комплекте), пульт PS2, 3 аккумулятора 18650, держатель 3S, зарядка, перемыжки, USB-кабель.

Ссылки на магазины — лишь рекомендации, покупайте где удобно.

Управление робот-танком Arduino с беспроводным джойстиком PS2
Управление робот-танком Arduino с беспроводным джойстиком PS2

Шаг 2: Сборка робота

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

Шаг 3: Схема подключения

Управление робот-танком Arduino с беспроводным джойстиком PS2

Батарейный блок (3×18650 = 11.1 В) на тыле танка питает 12-вольтовые двигатели. Модуль L298N усиливает 5-вольтовые сигналы Arduino до 12 В и позволяет реверсировать двигатели.

Управление робот-танком Arduino с беспроводным джойстиком PS2

Распиновка

Arduino Uno:

H-Bridge:

PS2 приёмник:

Управление робот-танком Arduino с беспроводным джойстиком PS2
Управление робот-танком Arduino с беспроводным джойстиком PS2

Шаг 4: Настройка Arduino IDE

  1. Скачайте и установите последнюю версию Arduino IDE с arduino.cc.
  2. Установите библиотеку PS2X от Bill Porter: скачайте с GitHub, распакуйте и скопируйте папки в libraries Arduino IDE.

Шаг 5: Библиотека PS2X — обзор

Управление робот-танком Arduino с беспроводным джойстиком PS2

PS2-контроллер даёт 20 цифровых кнопок и 2 аналоговых стика — огромные возможности для управления. Библиотека PS2X определяет класс PS2X с методами чтения цифровых и аналоговых входов.

Создание объекта: PS2X ps2x;

Настройка пинов: error = ps2x.config_gamepad(clock, command, attention, data, pressures?, rumble?);

Чтение кнопки: ps2x.Button(button) — возвращает true/false.

Кнопки: D-pad (UP, DOWN, LEFT, RIGHT), Action (TRIANGLE, CIRCLE, CROSS, SQUARE), Triggers (L1, R1, L2, R2), Sticks (L3, R3), Menu (SELECT, START).

Чтение стика: ps2x.Analog(stick_axis) — значение 0–255. Оси: PSS_LY, PSS_LX, PSS_RY, PSS_RX.

Шаг 6: Скетч №1 — кнопки D-pad

Управление робот-танком Arduino с беспроводным джойстиком PS2

Эмуляция управления старых консолей (Sega, SNES). Кнопки D-pad — только вкл/выкл, двигатели работают на полной мощности.

Управление робот-танком Arduino с беспроводным джойстиком PS2

Код (фрагмент цикла):

// ВПЕРЁД
if (ps2x.Button(PSB_PAD_UP)) {
  digitalWrite(MOTORA_1, LOW);
  digitalWrite(MOTORA_2, HIGH);
  digitalWrite(MOTORB_1, HIGH);
  digitalWrite(MOTORB_2, LOW);
  analogWrite(ENB, 1023);
  analogWrite(ENA, 1023);
  Serial.println("Move forward");
}
// НАПРАВО
if (ps2x.Button(PSB_PAD_RIGHT)) {
  digitalWrite(MOTORA_1, HIGH);
  digitalWrite(MOTORA_2, LOW);
  digitalWrite(MOTORB_1, HIGH);
  digitalWrite(MOTORB_2, LOW);
  analogWrite(ENB, 1023);
  analogWrite(ENA, 1023);
  Serial.println("Turn right");
}
// НАЛЕВО
if (ps2x.Button(PSB_PAD_LEFT)) {
  digitalWrite(MOTORA_1, LOW);
  digitalWrite(MOTORA_2, HIGH);
  digitalWrite(MOTORB_1, LOW);
  digitalWrite(MOTORB_2, HIGH);
  analogWrite(ENB, 1023);
  analogWrite(ENA, 1023);
  Serial.println("Turn left");
}
// НАЗАД
if (ps2x.Button(PSB_PAD_DOWN)) {
  digitalWrite(MOTORA_1, HIGH);
  digitalWrite(MOTORA_2, LOW);
  digitalWrite(MOTORB_1, LOW);
  digitalWrite(MOTORB_2, HIGH);
  analogWrite(ENB, 1023);
  analogWrite(ENA, 1023);
  Serial.println("Move back");
}
// СТОП
if (!ps2x.Button(PSB_PAD_DOWN) && !ps2x.Button(PSB_PAD_UP) && 
    !ps2x.Button(PSB_PAD_RIGHT) && !ps2x.Button(PSB_PAD_LEFT)) {
  analogWrite(ENB, 0);
  analogWrite(ENA, 0);
}
delay(50);

Шаг 7: Скетч №2 — левый аналоговый стик + кнопки L2/R2

Управление робот-танком Arduino с беспроводным джойстиком PS2

Аналоговый стик задаёт поворот, L2/R2 — газа/тормоз/задний ход (как в Mario Kart).

Управление робот-танком Arduino с беспроводным джойстиком PS2

Считываем X левого стика, маппим 0–255 → -1023…1023, корректируем скорость каждого гусеничника. R2 — вперёд, L2 — назад, ни одной — стоп.

Шаг 8: Скетч №3 — два аналоговых стика (дифференциальное управление)

Управление робот-танком Arduino с беспроводным джойстиком PS2

Левый стик — левый гусеничник, правый — правый. Максимальный реализм управления танком.

Управление робот-танком Arduino с беспроводным джойстиком PS2

Читаем Y обеих стиков, маппим, задаём направление и включаем PWM=1023 (можно сделать переменным). Мёртвая зона ±50.

Шаг 9: Скетч №4 — только левый стик (микшер)

Управление робот-танком Arduino с беспроводным джойстиком PS2

Один стик управляет и скоростью, и поворотом (микширование X и Y). Экономит кнопки, но сложнее в освоении. Алгоритм из этой статьи.

Управление робот-танком Arduino с беспроводным джойстиком PS2

Шаг 10: Заключение

Проект сделан максимально понятным и обучающим. Если понравилось — поставьте лайк и поделитесь! Другие мои проекты по робототехнике:

Поддержать будущие проекты: BTC 1FiWFYSjRaL7sLdr5wr6h86QkMA6pQxkXJ

Управление робот-танком Arduino с беспроводным джойстиком PS2

Код (полные скетчи)

Скетч №1 — D-pad

// PS2 Tank by Igor Fonseca @2019
#include <PS2X_lib.h>
#define ENA 3
#define MOTORA_1 4
#define MOTORA_2 5
#define MOTORB_1 8
#define MOTORB_2 7
#define ENB 6
PS2X ps2x;
int error = 0;
byte type = 0;
byte vibrate = 0;

void setup() {
  pinMode(ENA, OUTPUT); pinMode(MOTORA_1, OUTPUT); pinMode(MOTORA_2, OUTPUT);
  pinMode(ENB, OUTPUT); pinMode(MOTORB_1, OUTPUT); pinMode(MOTORB_2, OUTPUT);
  digitalWrite(ENA, 0); digitalWrite(ENB, 0);
  Serial.begin(57600);
  error = ps2x.config_gamepad(13, 11, 10, 12, true, true);
  if (error == 0) Serial.println("Found Controller, configured successful");
  else if (error == 1) Serial.println("No controller found, check wiring or reset the Arduino");
  else if (error == 2) Serial.println("Controller found but not accepting commands");
  else if (error == 3) Serial.println("Controller refusing to enter Pressures mode, may not support it.");
  type = ps2x.readType();
  switch (type) {
    case 0: Serial.println("Unknown Controller type"); break;
    case 1: Serial.println("DualShock Controller Found"); break;
    case 2: Serial.println("GuitarHero Controller Found"); break;
  }
}

void loop() {
  if (error == 1) return;
  ps2x.read_gamepad(false, vibrate);
  // ... (код движения как выше) ...
  delay(50);
}

Скетч №2 — Аналоговый стик + L2/R2

// ... те же настройки ...
int motor_right_speed = 0;
int motor_left_speed = 0;

void loop() {
  if (error == 1) return;
  ps2x.read_gamepad(false, vibrate);
  int nJoyL = ps2x.Analog(PSS_LX);
  nJoyL = map(nJoyL, 0, 255, 1023, -1023);
  motor_right_speed = 1023;
  motor_left_speed = 1023;
  if (nJoyL < 0) motor_right_speed += nJoyL;
  if (nJoyL > 0) motor_left_speed -= nJoyL;

  if (ps2x.Button(PSB_R2)) { // вперёд
    digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, HIGH);
    digitalWrite(MOTORB_1, HIGH); digitalWrite(MOTORB_2, LOW);
    analogWrite(ENA, motor_right_speed); analogWrite(ENB, motor_left_speed);
  }
  if (ps2x.Button(PSB_L2)) { // назад
    digitalWrite(MOTORA_1, HIGH); digitalWrite(MOTORA_2, LOW);
    digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH);
    analogWrite(ENA, motor_right_speed); analogWrite(ENB, motor_left_speed);
  }
  if (!ps2x.Button(PSB_L2) && !ps2x.Button(PSB_R2)) {
    analogWrite(ENA, 0); analogWrite(ENB, 0);
  }
  delay(50);
}

Скетч №3 — Два стика

void loop() {
  if (error == 1) return;
  ps2x.read_gamepad(false, vibrate);
  int nJoyL = ps2x.Analog(PSS_LY);
  int nJoyR = ps2x.Analog(PSS_RY);
  nJoyL = map(nJoyL, 0, 255, 1023, -1023);
  nJoyR = map(nJoyR, 0, 255, -1023, 1023);

  // Правый двигатель (MOTORA)
  if (nJoyR > 50) { digitalWrite(MOTORA_1, HIGH); digitalWrite(MOTORA_2, LOW); analogWrite(ENA, 1023); }
  else if (nJoyR < -50) { digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, HIGH); analogWrite(ENA, 1023); }
  else { analogWrite(ENA, 0); }

  // Левый двигатель (MOTORB)
  if (nJoyL > 50) { digitalWrite(MOTORB_1, HIGH); digitalWrite(MOTORB_2, LOW); analogWrite(ENB, 1023); }
  else if (nJoyL < -50) { digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH); analogWrite(ENB, 1023); }
  else { analogWrite(ENB, 0); }
  delay(50);
}

Скетч №4 — Один левый стик (микшер)

void loop() {
  if (error == 1) return;
  ps2x.read_gamepad(false, vibrate);
  int nJoyX = ps2x.Analog(PSS_LX);
  int nJoyY = ps2x.Analog(PSS_LY);
  nJoyX = map(nJoyX, 0, 255, -1023, 1023);
  nJoyY = map(nJoyY, 0, 255, 1023, -1023);

  float nMotPremixL, nMotPremixR, nPivSpeed, fPivScale;
  const float fPivYLimit = 1023.0;

  if (nJoyY >= 0) {
    nMotPremixL = (nJoyX >= 0) ? 1023.0 : (1023.0 + nJoyX);
    nMotPremixR = (nJoyX >= 0) ? (1023.0 - nJoyX) : 1023.0;
  } else {
    nMotPremixL = (nJoyX >= 0) ? (1023.0 - nJoyX) : 1023.0;
    nMotPremixR = (nJoyX >= 0) ? 1023.0 : (1023.0 + nJoyX);
  }
  nMotPremixL = nMotPremixL * nJoyY / 1023.0;
  nMotPremixR = nMotPremixR * nJoyY / 1023.0;

  nPivSpeed = nJoyX;
  fPivScale = (abs(nJoyY) > fPivYLimit) ? 0.0 : (1.0 - abs(nJoyY) / fPivYLimit);

  int nMotMixL = (1.0 - fPivScale) * nMotPremixL + fPivScale * nPivSpeed;
  int nMotMixR = (1.0 - fPivScale) * nMotPremixR + fPivScale * (-nPivSpeed);

  motor_left_speed = nMotMixL;
  motor_right_speed = nMotMixR;

  // Установка направления и PWM для левого двигателя
  if (motor_left_speed > 50) { digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, HIGH); }
  else if (motor_left_speed < -50) { digitalWrite(MOTORA_1, HIGH); digitalWrite(MOTORA_2, LOW); }
  else { digitalWrite(MOTORA_1, LOW); digitalWrite(MOTORA_2, LOW); }

  // Правый двигатель
  if (motor_right_speed > 50) { digitalWrite(MOTORB_1, HIGH); digitalWrite(MOTORB_2, LOW); }
  else if (motor_right_speed < -50) { digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, HIGH); }
  else { digitalWrite(MOTORB_1, LOW); digitalWrite(MOTORB_2, LOW); }

  analogWrite(ENA, abs(motor_left_speed));
  analogWrite(ENB, abs(motor_right_speed));
  delay(50);
}

Схемы

Управление робот-танком Arduino с беспроводным джойстиком PS2 Управление робот-танком Arduino с беспроводным джойстиком PS2

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

  1. Создание интернет-управляемого видеostreaming-робота на Arduino и Raspberry Pi
  2. Unopad: Бесшовный Arduino MIDI-контроллер для Ableton Live
  3. Робот-ускользатор на сервоприводе: сборка на Arduino и HC-SR04
  4. Управление Roomba Create 2 через Arduino и Android: пошаговое руководство
  5. Роботизированная рука 6 степеней свободы на Arduino Mega с управлением через Nunchuk
  6. Управление двумя шаговыми двигателями через джойстик на Arduino Nano — простой урок (Visuino)
  7. Своё рулевое управление (джойстик) для игр на Arduino
  8. Создание боевого робота с управлением от геймпада PS2 на базе Arduino
  9. Управление манипулятором LittleArm через Android-приложение по Bluetooth
  10. Робот-«едобот» на Arduino Nano: открывает рот при подаче еды (HC-SR04 + сервопривод)