Начну с небольшой предыстории:
Изначально я не планировал собирать такого робота, мне просто нужны были 2 детских огнетушителя — брызгалки, для детских конкурсов.
в магазинах города найти не удалось, а в интернете я случайно наткнулся робота с танковым шасси и водометом на борту.
поскольку у меня мало времени и совсем нет опыта, я и не думал сам что либо собирать, попросил человека продать готовое устройство. Но мне отказали и предложили — собери сам…
Начал с поиска чего либо интересного в интернет магазинах. и на разных форумах.
нашел такой вариант:
но посмотрев видео обзоры понял что шасси неустойчивое и может опрокидываться при резких стартах и торможении.
в общем в итоге после долгих поисков и обсуждений на форумах, купил такой комплект:
платформа: Wild Thumper 6WD Black 75:1 with 2 encoders
плата управления TREX controller — он же ардуино контролер.
так же для управления потребовался блютус модуль HC-06
для водомета были куплены такие детали:
2х осевой вращатель камеры
Сервопривод Tower Pro 9g SG90 две штуки:
Водяной насос (помпа)
комплект капельницы из аптеки(гибкий шланг)
Сборка не заняла много времени, и как я думал вначале все будет быстро и легко.
собрал, включил — поехали…
но меня ждали ГРАБЛИ 🙂
1. моя ошибка — источник питания, я наивно полагал что простых батареек для теста хватит. для работы ардуино — вполне, для двигателей НЕТ!
далее из одной крайности в другую:
тяжелый свинец на 12в 7,4 амперчаса…
из за тяжелого веса и повышенной мощности, от резких стартов была сорвана шестерня в редукторе, найти нужную не удалось, пришлось заказывать с интерет магазинов мотор редуктор в сборе.
2. основная проблема, которая отняла много времени и сил — «хитрая» плата управления.
дело в том что на ней изначально есть разъем для подключения блютус модуля, и если в него включить модуль этого же производителя, то все заработает, если стороннего то нет!
все дело в том что сигнальные контакты RX и TX нужно менять местами!
3. к моей необычной плате управления шли примеры программы(скетч) и приложение для андроида, управлялка с телефона
но почему то программа управления страшно глючила, машина с трудом двигалась вперед, дергаясь в конвульсиях.
не без помощи добрых людей удалось состряпать новый скетч именно под мою платформу.
на первом, полноценном этапе получилось такое чудо:
машина с 6х6 с тяжелым акумом и водометом. в качестве кнопки включения служила старая пробка 🙂
а тут видео как это работало:
на данный момент у меня такая тележка:
как видно на фото полностью поменялась компоновка, теперь спереди стоит захват манипулятора. а водомет позади.
в качестве аккумуляторов было решено использовать «банки» от испорченного ноутбучного акума. всего 6 банок.
я долго искал для них бат блоки, но к сожалению на них оказался дефицит. на местном радио рынке блок под 1 акум, купил и пожалел об этом, он оказался с очень хлипкими проводами, и тут в голову пришла идея со шприцами, они идеально подошли для этой цели!
вместо старой пробки был куплен новый пакетник 🙂
на видео машина используется по назначению — развлекает детей на детском празднике.
а тут презентационный ролик ))
испытания проходимости
недавно решил что робот должен обладать хоть немного автоматизмом.
и как раз была у меня одна незадействованая кнопка, сделал на нее функцию автоматического захвата предметов
для управления использую смартфон, и приложение BTCA2A
подробнее о нем можно почитать: http://robocontroller.ru/news/btca2a_upravlenie_arduino_po_bluetooth_pri_pomoshhi_android/2013-11-16-40
проект находиться в стадии разработки, ожидаю с недели на неделю новые запчасти, а именно механизм стрельбы 6мм шариками от модели танков. буду делать пушку 🙂
забыл выложить скетч:
// Скетч для управления через блютус, Wild Thumper 6WD, на ардуино совместимом контролере TREX controller. реализовано движение и стрельба с водомета, захват клешней манипулятором. // по вопросам и предложениям писать на почту [email protected] // новые фото и видео можно найти на www.шоуальянс.com #include <BTCA2ALite.h>// Добавляем библиотеку блютус программы #include <Servo.h> // Добавляем библиотеку серво Servo myservoH; // Горизонтальная серва углы от 0 до 180 (центровка 89) Servo myservoV; // Вертикальная серва углы от 1 до 45 Servo myservoZ; // серва Клешня Servo myservoR; // серва рука клешни const int Z_SERVO_PIN = 5; // добовляем пин захвата const int R_SERVO_PIN = 6; // добовляем пин руки манипулятора const int H_SERVO_PIN = 7; // Горизонтальная серва подключена к пину 7 const int V_SERVO_PIN = 8; //Пин вертикального сервопривода 8 const float Z_L_ANGLE = 116; // Максимальные угл поворота башни налево const float Z_R_ANGLE = 45; // Максимальные угл поворота башни направо const float Z_DEF_ANGLE = 50; // Дефолтный угол (центровка) const float R_L_ANGLE = 170; // Максимальные угл поднятия руки const float R_R_ANGLE = 3; // Максимальные угл наклона руки const float R_DEF_ANGLE = 160; // Дефолтный угол руки const float H_L_ANGLE = 180; // Максимальные угл поворота башни налево const float H_R_ANGLE = 0; // Максимальные угл поворота башни направо const float H_DEF_ANGLE = 84; // Дефолтный угол (центровка) const float V_U_ANGLE = 175; // Максимальные угл поворота башни вверх const float V_D_ANGLE = 125; // Максимальные угл поворота башни вниз const float V_DEF_ANGLE = 160; // Дефолтный угол (центровка) //Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали. const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали const float Z_STEP = 0.012; // шаг захвата const float R_STEP = 0.012; // шаг руки float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы float curZAngle = Z_DEF_ANGLE; // float curRAngle = R_DEF_ANGLE; // bool moveServoVUp = false; //Флаг движения верт. сервы вверх bool moveServoVDown = false; //Флаг движения верт. сервы вниз bool moveServoHLeft = false; //Флаг движения гор. сервы влево bool moveServoHRight = false; //Флаг движения гор. сервы вправо bool moveServoZLeft = false; //Флаг движения гор. сервы влево bool moveServoZRight = false; //Флаг движения гор. сервы вправо bool moveServoRLeft = false; //Флаг движения гор. сервы влево bool moveServoRRight = false; //Флаг движения гор. сервы вправо btca2aLite btca2aLite; // Конструктор btca2aLite // задаем пины для левого мотора #define Dir_L 2 #define Pwm_L 3 #define Brake_L 4 // задаем пины для правого мотора #define Dir_R 10 #define Pwm_R 11 #define Brake_R 9 // Задаем скорости для движения byte MaxSpeed = 230; // Максимальная скорость byte MinSpeed = 90; // Минимальная скорость int forw_back = 0; int righ_left = 0; byte step_fb = 5; // Шаг изменения скорости движения вперед - назад byte step_stop = 10; // Шаг изменения скорости остановки byte step_rl = 10; // Шаг изменения скорости движения вправо - влево byte step_dir = 10; // Шаг изменения скорости выравнивания #define SHOT 12 // пин для водомета enum States { WAITING, READING, RUNNING, ERROR, TIMEOUT }; States state; States onWait(); States onRead(); States onRun(); States onError(); States onTimeout(); void performServo(); // добовляем сервы void setup(){ Serial.begin(9600); // Скорость BT и порта должна быть 9600 //Моторы pinMode (Pwm_L, OUTPUT); pinMode (Dir_L, OUTPUT); pinMode (Brake_L, OUTPUT); pinMode (Pwm_R, OUTPUT); pinMode (Dir_R, OUTPUT); pinMode (Brake_R, OUTPUT); digitalWrite (Pwm_L, LOW); digitalWrite (Pwm_R, LOW); digitalWrite (Brake_L, LOW); digitalWrite (Brake_R, LOW); pinMode(SHOT, OUTPUT); // задаем выход для стрельбы водой // устанавливаем пин как вывод управления сервой myservoH.attach(H_SERVO_PIN); myservoV.attach(V_SERVO_PIN); myservoZ.attach(Z_SERVO_PIN); myservoR.attach(R_SERVO_PIN); myservoH.write(curHAngle); myservoV.write(curVAngle); myservoZ.write(curZAngle); myservoR.write(curRAngle); //Светодиод pinMode(13, OUTPUT); // Инициализируем пин светодиода digitalWrite(13, HIGH); // Светодиод выключен } void loop(){ btca2aLite.ReadCommand(); // Считывание принятых команд (кодов кнопок) //Вызываем функцию управление сервами performServo(); //этот код для меня темный лес, мне его дали для плавного старта и торможения моторов. если ехать вперед и резко нажать кнопку назад, машина продолжит ехать вперед, плавно остановиться и только потом поедет назад, это спасает редуктора от разрушения. //если ктото знает что тут к чему, прокоментируйте пожалуйста, чтоб я тоже понимал :) static unsigned long pre_millis = 0; if(millis()-pre_millis > 50) { pre_millis = millis(); if(btca2aLite.ButtonPressed(KEYCODE_DPAD_UP)) { forw_back += step_fb; if(forw_back > 0 && forw_back < MinSpeed) forw_back = MinSpeed; } else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN)) { forw_back -= step_fb; if(forw_back < 0 && forw_back > MinSpeed*-1) forw_back = MinSpeed*-1; } else { if(forw_back < 0) forw_back += step_stop; else if(forw_back > 0) forw_back -= step_stop; if(abs(forw_back) < MinSpeed) forw_back = 0; } forw_back = constrain(forw_back, MaxSpeed*-1, MaxSpeed); if(btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)) { righ_left += step_rl; if(righ_left > 0 && righ_left < MinSpeed) righ_left = MinSpeed; } else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT)) { righ_left -= step_rl; if(righ_left < 0 && righ_left > MinSpeed*-1) righ_left = MinSpeed*-1; } else { if(righ_left < 0) righ_left += step_dir; else if(righ_left > 0) righ_left -= step_dir; if(abs(righ_left) < MinSpeed) righ_left = 0; } righ_left = constrain(righ_left, MaxSpeed*-1, MaxSpeed); int pwm_l = forw_back + righ_left; int pwm_r = forw_back - righ_left; pwm_l = constrain(pwm_l, MaxSpeed*-1, MaxSpeed); pwm_r = constrain(pwm_r, MaxSpeed*-1, MaxSpeed); digitalWrite(Dir_L, (pwm_l<0)?0:1); digitalWrite(Dir_R, (pwm_r<0)?0:1); analogWrite(Pwm_L, abs(pwm_l)); analogWrite(Pwm_R, abs(pwm_r)); } //дальше идут кнопки управления //-------— включение насоса —------------- if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_SELECT)) { digitalWrite (SHOT, HIGH); } //-------— выключение насоса происходит автоматически после отпускания кнопки—------------- if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_SELECT)) { digitalWrite (SHOT, LOW); } if(btca2aLite.Button(KEYCODE_BUTTON_START)) // алгоритм автоматического хватания предметов { // машина делает шаг вперед digitalWrite (Dir_L, HIGH); analogWrite (Pwm_L, 150); digitalWrite (Dir_R, HIGH); analogWrite (Pwm_R, 150); delay (100); // потом стоп analogWrite (Pwm_L, 0); analogWrite (Pwm_R, 0); delay (500); myservoZ.write(45);; // Клешня разжимается myservoR.write(3);; // рука клешни опускаем delay(2000); /* ждем 2 секунды, */ myservoZ.write(116);; // Клешня сжимаем delay(1000); /* ждем 1 секунду, */ myservoR.write(170);; // рука клешни поднимаем delay(600); /* ждем */ myservoZ.write(45);; // Клешня разжимаем } //--------— Повороты серв при нажатии кнопок —------------- if(btca2aLite.Button(KEYCODE_BUTTON_X)) // поворот водомета вниз { moveServoVDown = true; } if(btca2aLite.Button(KEYCODE_BUTTON_A)) // поворот водомета направо { moveServoHRight = true; } if(btca2aLite.Button(KEYCODE_BUTTON_B)) // поворот водомета вверх { moveServoVUp = true; } if(btca2aLite.Button(KEYCODE_BUTTON_Y)) // поворот водомета налево { moveServoHLeft = true; } if(btca2aLite.Button(KEYCODE_BUTTON_R1)) // зхахват сжать { moveServoZLeft = true; } if(btca2aLite.Button(KEYCODE_BUTTON_R2)) // захват разжать { moveServoZRight = true; } if(btca2aLite.Button(KEYCODE_BUTTON_L1)) // рука клешни вниз { moveServoRLeft = true; } if(btca2aLite.Button(KEYCODE_BUTTON_L2)) // рука клешни вверх { moveServoRRight = true; } //--------— чтобы сервы не продолжали движения при отжатых кнопках —------------- if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X)) { moveServoVDown = false; } if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B)) { moveServoVUp = false; } if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A)) { moveServoHRight = false; } if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y)) { moveServoHLeft = false; } if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_R2)) { moveServoZRight = false; } if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_R1)) { moveServoZLeft = false; } if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_L2)) { moveServoRRight = false; } if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_L1)) { moveServoRLeft = false; } //----------------— Стоп —--------------------- // Если не нажата ни одна кнопка курсора происходит остановка, скорость 0 для каждого мотора if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){ analogWrite (Pwm_L, 0); analogWrite (Pwm_R, 0); } } //Функция управления сервоприводами (вызывается в теле loop на каждой итерации) //Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения //Флаги устанавливаются согласно поступившим символам управления сервами void performServo() { //Установлен флаг движения вверх и текущий угол не максимальный if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE) { //К текущему верт. углу прибавляем шаг curVAngle += V_STEP; } //Установлен флаг движения вниз и текущий угол не минимален else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE) { //От текущего верт. угла отнимаем шаг curVAngle -= V_STEP; } //Установлен флаг движения влево и текущий угол не максимален if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE) { //К текущему гор. углу прибавляем гор. шаг curHAngle += H_STEP; } //Установлен флаг движения вправо и текущий угол не минимален else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE) { //От текущего угла отнимаем гор. шаг curHAngle -= H_STEP; } //Установлен if (moveServoZLeft && curZAngle + Z_STEP <= Z_L_ANGLE) { //К текущему гор. углу прибавляем гор. шаг curZAngle += Z_STEP; } //Установлен флаг движения вправо и текущий угол не минимален else if (moveServoZRight && curZAngle - Z_STEP >= Z_R_ANGLE) { //От текущего угла отнимаем гор. шаг curZAngle -= Z_STEP; } //Установлен if (moveServoRLeft && curRAngle + R_STEP <= R_L_ANGLE) { //К текущему гор. углу прибавляем гор. шаг curRAngle += R_STEP; } //Установлен флаг движения вправо и текущий угол не минимален else if (moveServoRRight && curRAngle - R_STEP >= R_R_ANGLE) { //От текущего угла отнимаем гор. шаг curRAngle -= R_STEP; } //Если было движние по вертикали if (moveServoVUp || moveServoVDown) { myservoV.write(curVAngle); } //Если было движение по горизонтали if (moveServoHLeft || moveServoHRight) { myservoH.write(curHAngle); } if (moveServoZLeft || moveServoZRight) { myservoZ.write(curZAngle); } if (moveServoRLeft || moveServoRRight) { myservoR.write(curRAngle); } }
новое видео:
временно снял водомет, и установил пушку, стреляет 6мм шариками
и прикрутил приехавшую из Китая пушку…
правда это была не совсем пушка, а механизм стрельбы 6мм шариками от модельных танком Henlong, чтобы не покупать целый танк за 3000-5000 я купил запасть за 550руб.
почему я не купил гирбокс от страйкбола?
на то 2 причины:
1. сильно мощное, может кого то покалечить..
2. цена в 10 раз выше 🙂
есть недостаток у этого механизма — низкая скорострельность, на видео особенно низкая т.к питаю от 3х в, хотя можно 6 — 9
http://images.sevstar.net/viewer.php?file=59094243184497828873.jpg
http://images.sevstar.net/viewer.php?file=87142517578332600977.jpg
http://images.sevstar.net/viewer.php?file=68702878424694602806.jpg
http://images.sevstar.net/viewer.php?file=61506990518273702824.jpg
http://images.sevstar.net/viewer.php?file=67439761693001393174.jpg
ствол и уплотнительная резинка в комплект механизма не входят!
поэтому чтобы стрелять пришлось купить детский пистолет и позаимствовать у него ствол и резинку.
http://images.sevstar.net/viewer.php?file=15374563575590298148.jpg
на фото нет новых доработок, добавил лазерный прицел и дымогенератор с подсветкой для пущего эффекта…
0 комментариев на «“Фиксиход — тележка с манипулятором и водометом”»
Классная платформа, а водомет лучше поставить от ваз 2108-2115 с бачка омывателя ветрового стекла цена примерно 100-150 р. зато производительность гораздо лучше, тогда будет водяная пушка а не брызгалка 😉
спасибо за свовет, возможно так и сделаю, а пока снял водомет, поставил пушку, а потом и пушку снял и отлаживаю подключение к джойстику
http://www.youtube.com/watch?v=M3YJXgwfJlw
в перспективе установка пушки и водомета, и клешня само собой 🙂