Новости

Дистанційно керований танк (машинка) на Arduino

  1. Дистанційне керування на bluetooth модулі HC-06
  2. • Управління танком без контрольного символу
  3. Дистанційне керування на радіомодулів APC220
  4. Маневрування танком на APC220
  5. Управління танком на APC220 на дальній дистанції (приблизно 70-80м)

Сьогодні був чудовий весняний день, ми вибралися на природу, відмінно провели час, перевірили роботу написаної нами програми Z-Controller.

І найголовніше - протестували на дальність роботи блютуз модуль HC-06, а також радіомодулі APC220.

Ну, про все по порядку.

Ну, про все по порядку

Компоненти для повторення (купити в Китаї):

• Керуюча плата

Arduino UNO 16U2 , Або більш дешева Arduino UNO CH340G ,

Arduino Nano CH340G , або Arduino MEGA 16U2 , Або більш дешева Arduino MEGA CH340G ,

модуль L298N

• Плата управління моторами

Плата розширення L293D , або модуль L298N , або Плата розширення L298P (немає в статті)

Z- Motor Shield L293D (припинено випуск)

• радіомодулів

радіомодулі APC220 або Блютуз модуль HC-06

• Комплекти проводів з'єднувальних

З'єднувальні дроти тато-мама

З'єднувальні дроти тато-тато

Цікаві платформи:

Платформа1 (акрил 2 колеса)

Платформа2 (метал гусенична)

Платформа3 (метал гусенична)

Отже, почнемо з залізної частини. Збірка машинки проводиться елементарно. Одним рухом руки вставляємо Шилд в плату Arduino, потім підключаємо до гвинтових клемник мотори і подаємо на плату живлення від акумулятора або батарейок.

Залишається тільки підключити блютуз або радіомодуль за допомогою джамперів "тато-мама".

Bluetooth HC-06Arduino

VCC + 5V GND GND TX RX RX TX

VCC + 5V    GND GND TX RX RX TX

Дистанційне керування на bluetooth модулі HC-06

Почнемо з блютуза. Про з'єднання з комп'ютером можна прочитати тут

Про з'єднання з комп'ютером можна прочитати   тут

Управління буде здійснюватися з комп'ютера через написану нами програму Z-Controller. Завантажити її можна тут , керівництво користувача тут .

Програма вийшла функціональної. У неї можна додавати свої кнопки, називати їх як хочеш, прив'язувати до них найусілякіші клавіші на реальній клавіатурі, посилати в порт задаються значення при натисканні і відпусканні клавіші. Іншими словами - дай двом людям програму і у кожного вона буде зі своїм інтерфейсом.

У зв'язку з цим, для управління танком необхідно буде завантажити в програму файл настройок під наш код ( завантажити ).

Головною особливістю Z-Controller'а від інших додатків є наявність контрольного символу спамящегося з задається частотою, про його призначення ми розповімо далі, а поки розглянемо найпростіший спосіб.

Управління танком без контрольного символу

Візьмемо, наприклад, простий до неподобства код без контрольного символу.

У разі якщо ви не розраховуєте працювати на граничному для блютуза відстані, де можливий обрив зв'язку або обрив зв'язку не настільки критичний, то можна зупиниться на цьому легкому скетчі.

Приклад програмного коду // Тестувалося на Arduino 1.0.3 int val; int IN1 = 4; int IN2 = 2; int EN1 = 3; int EN2 = 5; int LED = 13; void setup () {Serial. begin (9600); pinMode (IN1, OUTPUT); pinMode (IN2, OUTPUT); pinMode (EN1, OUTPUT); pinMode (EN2, OUTPUT); // використовуємо 13 пін як індикатор включеної Ардуіно pinMode (LED, OUTPUT); digitalWrite (LED, HIGH); } Void loop () {if (Serial. Available ()) {val = Serial. read (); // Задаємо рух вперед if (val == 'W') // При натисканні клавіші "W" {// Висновки конфигурируются згідно раьот Motor Shield'а // Мотори крутяться вперед digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, HIGH); digitalWrite (IN2, HIGH); } // Задаємо рух назад if (val == 'S') {digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); } // Задаємо рух вправо if (val == 'D') {digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); } // Задаємо рух вліво if (val == 'A') {digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); } // Стоп режим // При відпуску клавіш в програмі в порт шле "T" if (val == 'T') // При натисканні клавіші "T" {// Висновки ENABLE притягнуті до мінуса, мотори не працюють digitalWrite (EN1 , LOW); digitalWrite (EN2, LOW); }}}

Як ми бачимо з скетчу, при отриманні символу "W", наш танк поїде вперед і зупиниться коли ми відпустимо кнопку і в порт буде посланий символ "T" (тому що символ "T" у нас поставлено на відпускання клавіші W).

А тепер уявімо, що стався обрив зв'язку після відправки символу 'W' (або пристрій вийшов з радіусу дії) і наступні символи 'T' вже не отримати. Як результат - наш робот їде вперед до переможного, наприклад, куди-небудь в воду :)

На наведених нижче відео ми і продемонструємо втрату керованості при виході з радіусу дії блютуза.

Відкриваємо Z-controller, підключаємося до порту яким отпределілся блютуз і їдемо.

Управління Такна з контрольним символом

Перейдемо до управління з контрольним символом. Z-Controller з налагодження з конфігураційного файлу спамить контрольний символ "P" кожні 100 мс. Тепер, якщо зв'язок обірвався, і в перебігу 150мс на контролер не прийшов сигнал "P", то танк зупиниться.

Код буде однаковим і для HC-06 і для APC220

Приклад програмного коду // Тестувалося на Arduino 1.0.3 const int TIMEOUT_TIME_MS = 150; unsigned long lastPilotSymbolTime; char symbol; int val; int IN1 = 4; int IN2 = 2; int EN1 = 3; int EN2 = 5; int LED = 13; // використовуємо вбудований світлодіод для індикації роботи enum States {WAITING, READING, RUNNING, ERROR, TIMEOUT}; States state; States onWait (); States onRead (); States onRun (); States onError (); States onTimeout (); void setup () {Serial. begin (9600); lastPilotSymbolTime = 0; pinMode (IN1, OUTPUT); pinMode (IN2, OUTPUT); pinMode (EN1, OUTPUT); pinMode (EN2, OUTPUT); // використовуємо 13 пін як індикатор включеної Ардуіно pinMode (LED, OUTPUT); digitalWrite (LED, HIGH); } Void loop () {switch (state) {case WAITING: state = onWait (); break; case READING: state = onRead (); break; case RUNNING: state = onRun (); break; case TIMEOUT: state = onTimeout (); break; default: state = onError (); }} States onWait () {if (Serial. Available ()> 0) {return READING; } If (lastPilotSymbolTime && (millis () - lastPilotSymbolTime> TIMEOUT_TIME_MS)) {return TIMEOUT; } Return WAITING; } States onRead () {symbol = Serial. read (); return RUNNING; } States onRun () {switch (symbol) {case 'W': // початок дій при отриманому символі 'W' (вперед) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, HIGH); digitalWrite (IN2, HIGH); break; case 'S': // початок дій при отриманому символі 'S' (тому) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); break; case 'D': // початок дій при отриманому символі 'D' (вправо) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); break; case 'A': // початок дій при отриманому символі 'A' (вліво) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (EN1, HIGH); digitalWrite (EN2, HIGH); digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); break; case 'T': // початок дій при отриманому символі 'T' (зупинка) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (EN1, LOW); digitalWrite (EN2, LOW); break; case 'P': // отримали контрольний символ, не змінюйте цей код lastPilotSymbolTime = millis (); break; default: return ERROR; } Return WAITING; } States onError () {// Отримано необумовлені символи. Очищаємо введення і продовжуємо. // Тут можна додати якісь дії для цієї ситуації. // ... while (Serial. Available ()) {Serial. read (); } Return WAITING; } States onTimeout () {// Дії при таймауті. // Ймовірно, зв'язок втрачено, // але при отриманні контрольного символу вона буде відновлена. // Тут, наприклад, доречно вимкнути двигуни // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (EN1, LOW); // На висновки ENABLE подані сигнали низького рівня, мотори не працюють digitalWrite (EN2, LOW); if (Serial. available ()) {return READING; } Return TIMEOUT; }

Як ми можемо спостерігати, дистанція управління з контрольним символом стала менше ніж без нього. Це обумовлюється тим, що в першому випадку танк "залипає", безконтрольно їхав вперед, потім знову пробивався сигнал, він входив в штатний режим і знову втрачав зв'язок.

На другому відео вже видно, що стійка, без обривів дистанція роботи блютуза лежить в межах 15 метрів. Потім сигнал дуже поганий, як видно на відео, сигнал все-таки буде місцями доходити, і танк буде виконувати дії, але це вже не той сигнал, який потрібен для повноцінного управління.

Дистанційне керування на радіомодулів APC220

Підключення модуля і програмний код для роботи точно такі ж як і у bluetooth HC-06.

Керівництво користувача даного модуля з комп'ютером тут

Радіомодулі APC220Arduino

VCC + 5V GND GND TX RX RX TX

VCC + 5V    GND GND TX RX RX TX

Маневрування танком на APC220

Управління танком на APC220 на дальній дистанції (приблизно 70-80м)

Хочеться сказати пару слів про APC220. Радіомодулі відмінні, але є деякі особливості при роботі. При розташуванні модуля на танку, він знаходився на висоті 5 см від землі (тобто на нього поширювався фактор поглинання радіосигналу підстильної поверхнею), і максимальна дистанція управління танком склала метрів 100. Заради інтересу я взяв танк в руки, підняв на рівень грудей і пішов далі, зайшов в ліс, пройшовся ще метрів 200-250 і сигнал ловив відмінно. Далі не пішов тому стежинка початку закруглятися. У підсумку можна прийти до висновку, що для отримання хорошої дистанції, радіопередавачі слід кріпити як можна вище від землі.

Модуль драйвера двигунів L298N підключення до Arduino (Стаття про роботу)

При складанні машинки на модулі L298N так само нічого складного немає. Просто доведеться з'єднати модуль з платою Arduino за допомогою джамперів "тато-мама" як показано на зображенні.

Просто доведеться з'єднати модуль з платою Arduino за допомогою джамперів тато-мама як показано на зображенні

приклад програмного коду:

// Тестувалося на Arduino 1.0.3 const int TIMEOUT_TIME_MS = 150; unsigned long lastPilotSymbolTime; char symbol; int val; int IN1 = 7; // висновки модуля L298N підключені до наступних пінам Arduino int IN2 = 6; int IN3 = 5; int IN4 = 4; int LED = 13; // використовуємо вбудований світлодіод для індикації роботи enum States {WAITING, READING, RUNNING, ERROR, TIMEOUT}; States state; States onWait (); States onRead (); States onRun (); States onError (); States onTimeout (); void setup () {Serial. begin (9600); lastPilotSymbolTime = 0; pinMode (IN1, OUTPUT); pinMode (IN2, OUTPUT); pinMode (IN3, OUTPUT); pinMode (IN4, OUTPUT); // використовуємо 13 пін як індикатор включеної Ардуіно pinMode (LED, OUTPUT); digitalWrite (LED, HIGH); } Void loop () {switch (state) {case WAITING: state = onWait (); break; case READING: state = onRead (); break; case RUNNING: state = onRun (); break; case TIMEOUT: state = onTimeout (); break; default: state = onError (); }} States onWait () {if (Serial. Available ()> 0) {return READING; } If (lastPilotSymbolTime && (millis () - lastPilotSymbolTime> TIMEOUT_TIME_MS)) {return TIMEOUT; } Return WAITING; } States onRead () {symbol = Serial. read (); return RUNNING; } States onRun () {switch (symbol) {case 'W': // початок дій при отриманому символі 'W' (вперед) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); break; case 'S': // початок дій при отриманому символі 'S' (тому) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); break; case 'D': // початок дій при отриманому символі 'D' (вправо) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); break; case 'A': // початок дій при отриманому символі 'A' (вліво) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); break; case 'T': // початок дій при отриманому символі 'T' (зупинка) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); break; case 'P': // отримали контрольний символ, не змінюйте цей код lastPilotSymbolTime = millis (); break; default: return ERROR; } Return WAITING; } States onError () {// Отримано необумовлені символи. Очищаємо введення і продовжуємо. // Тут можна додати якісь дії для цієї ситуації. // ... while (Serial. Available ()) {Serial. read (); } Return WAITING; } States onTimeout () {// Дії при таймауті. // Ймовірно, зв'язок втрачено, // але при отриманні контрольного символу вона буде відновлена. // Тут, наприклад, доречно вимкнути двигуни // [ДОДАТИ СВІЙ КОД НИЖЧЕ] digitalWrite (IN1, LOW); // На пари висновків IN подані сигнали однакового рівня, мотори не працюють digitalWrite (IN2, LOW); digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); if (Serial. available ()) {return READING; } Return TIMEOUT; }

Збірка ідентичною дистанційно керованої машинки,

але на базі Arduino і Adafruit Motor Shield

Adafruit motor shield підключення до Arduino (Стаття про роботу)

При складанні машинки на Adafruit motor shield можуть виникнути деякі труднощі якщо ви не вміти паяти. Виробники Шілд не комплектують плату гребінками "тато-мама", по-цьому з'єднати Шилд з блютуз модулем за допомогою джамперів вийде - доведеться підпоюють.

Приклад програмного коду:

// Тестувалося на Arduino 1.0.3 #include <AFMotor.h> // Підключаємо бібліотеку для роботи з Шілд const int TIMEOUT_TIME_MS = 150; unsigned long lastPilotSymbolTime; char symbol; int val; // Підключаємо мотори до клемники M3, M4 AF_DCMotor motor3 (3); AF_DCMotor motor4 (4); int LED = 13; // використовуємо вбудований світлодіод для індикації роботи enum States {WAITING, READING, RUNNING, ERROR, TIMEOUT}; States state; States onWait (); States onRead (); States onRun (); States onError (); States onTimeout (); void setup () {Serial. begin (9600); lastPilotSymbolTime = 0; // Задаємо максимальну швидкість обертання моторів (аналог роботи PWM) motor3. setSpeed ​​(255); motor3.run (RELEASE); motor4. setSpeed ​​(255); motor4.run (RELEASE); // використовуємо 13 пін як індикатор включеної Ардуіно pinMode (LED, OUTPUT); digitalWrite (LED, HIGH); } Void loop () {switch (state) {case WAITING: state = onWait (); break; case READING: state = onRead (); break; case RUNNING: state = onRun (); break; case TIMEOUT: state = onTimeout (); break; default: state = onError (); }} States onWait () {if (Serial. Available ()> 0) {return READING; } If (lastPilotSymbolTime && (millis () - lastPilotSymbolTime> TIMEOUT_TIME_MS)) {return TIMEOUT; } Return WAITING; } States onRead () {symbol = Serial. read (); return RUNNING; } States onRun () {switch (symbol) {case 'W': // початок дій при отриманому символі 'W' (вперед) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] motor3.run (FORWARD); motor4.run (FORWARD); motor3. setSpeed ​​(255); // Задаємо швидкість руху motor4. setSpeed ​​(255); break; case 'S': // початок дій при отриманому символі 'S' (тому) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] motor3.run (BACKWARD); motor4.run (BACKWARD); motor3. setSpeed ​​(255); // Задаємо швидкість руху motor4. setSpeed ​​(255); break; case 'D': // початок дій при отриманому символі 'D' (вправо) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] motor3.run (BACKWARD); motor4.run (FORWARD); motor3. setSpeed ​​(255); // Задаємо швидкість руху motor4. setSpeed ​​(255); break; case 'A': // початок дій при отриманому символі 'A' (вліво) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] motor3.run (FORWARD); motor4.run (BACKWARD); motor3. setSpeed ​​(255); // Задаємо швидкість руху motor4. setSpeed ​​(255); break; case 'T': // початок дій при отриманому символі 'T' (зупинка) // [ДОДАТИ СВІЙ КОД НИЖЧЕ] motor3.run (RELEASE); motor4.run (RELEASE); break; case 'P': // отримали контрольний символ, не змінюйте цей код lastPilotSymbolTime = millis (); break; default: return ERROR; } Return WAITING; } States onError () {// Отримано необумовлені символи. Очищаємо введення і продовжуємо. // Тут можна додати якісь дії для цієї ситуації. // ... while (Serial. Available ()) {Serial. read (); } Return WAITING; } States onTimeout () {// Дії при таймауті. // Ймовірно, зв'язок втрачено, // але при отриманні контрольного символу вона буде відновлена. // Тут, наприклад, доречно вимкнути двигуни // [ДОДАТИ СВІЙ КОД НИЖЧЕ] motor3.run (RELEASE); // зупиняємо двигуни motor4.run (RELEASE); if (Serial. available ()) {return READING; } Return TIMEOUT; }

В даний момент ще не в усіх елементи нашої спільноти. Ми активно працюємо над ним і найближчим часом можливість коментування статей буде додана.

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

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: