Планируем попасть на отборочный тур соревнований "Hello, Robot! Arduino". Смотрел видео с предыдущих, там было много конструкций на платформе с такими редукторами и колесами .. вот и стало интересно кто может оказаться в конкурентах.
Вторая версия колесного аппарата. Почти вся элементная база с первой версии. Основное отличие - это конструкция. Теперь платформа вырезана лазером из фанеры, также другие колеса с двигателями. Пока здесь только ардуина, светодиод и приемник на 433МГц. В дальнейшем постараюсь перенести все датчики с первой версии.
Испытание ультразвуковых датчиков прошло успешно. Аппарат едет назад, вперед и останавливается.
#ifndef KemaCrash_h
#define KemaCrash_h
#include "Arduino.h"
class KemaCrash
{
public:
KemaCrash(int crashL, int crashR);
int pingL();
int pingR();
private:
int _crashL;
int _crashR;
};
#endif
у меня больше. я в 13 году задумал новый танк, вырезал на чпу кое что и понеслось. сейчас 2017 и я его почти доделал)) правда почти неизвестно на сколько растянется
Блин.. озадачили. Одни мы с сыном чтоли практически за неделю вот это наклепали, причем "из говна и палок", а оно ещё и лучший результат на России показало? :)
Подскажите как колеса от конструктора с отверстием около 5 мм насадить на сервопривод?
http://ru.aliexpress.com/item/Practical-SG90-9g-Mini-Micro-Servo-For-RC-...
https://market.yandex.ru/product/11865474?hid=10470548&show-uid=54435858...
В таких конструкторах бывают П-образные скобы.
С помощью длинного болта крепите колесо к ушкам скобы.
Торец скобы - к серве.
самый простой это взять крестик(качалка) от сервы и на термоклей приклеить к колесу
да, в моем случае так и делал, приклеил редуктор с колесом к крестику.
Поздравляю. Здорово получилось. Делаем что-то подобное, но на базе Лего деталек, причем вперемежку обычное Лего и Техник.
Какова предельная скорость движения вашего бота на таких моторах? Сантиметров 60 в сек. сможет проехать?
не измерял, в моих испытаниях 20 - 30 см/с наверно было
Спасибо, это радует. :)
Планируем попасть на отборочный тур соревнований "Hello, Robot! Arduino". Смотрел видео с предыдущих, там было много конструкций на платформе с такими редукторами и колесами .. вот и стало интересно кто может оказаться в конкурентах.
Вторая версия колесного аппарата. Почти вся элементная база с первой версии. Основное отличие - это конструкция. Теперь платформа вырезана лазером из фанеры, также другие колеса с двигателями. Пока здесь только ардуина, светодиод и приемник на 433МГц. В дальнейшем постараюсь перенести все датчики с первой версии.
Испытание ультразвуковых датчиков прошло успешно. Аппарат едет назад, вперед и останавливается.
видео https://vk.com/video-73778892_456239018
Последнее фото с установленными ультразвуковыми и инфракрасными датчиками:
Последний скетч:
#include <KemaUS.h> #include <KemaIR.h> #include <KemaState.h> #include <KemaDrive.h> #include <KemaLED.h> #include <KemaMem.h> #include <VirtualWire.h> //pin 11 KemaDrive myDrive; KemaLED myLED(8,9,12); KemaState curState; KemaState prevState; KemaUS ultraSonic(22,23,24,25); KemaIR myIR(30,31); KemaMem myMem; long prevTime = 0; long deltaTime = 0; int incomingByte = 0; boolean rfCtrl = true; boolean past = false; char passRfCtrl[4] = {'k', 'e', 'm', 'a'}; char act = '?'; byte disallow = B00000000; // 0 - back. 1 - stop. 2 - forward. int speedInd = 0; void setup() { myLED.led('B'); Serial.begin(9600); vw_set_ptt_inverted(true); // Required for DR3100 vw_setup(2000); // Bits per sec vw_rx_start(); } void loop() { if(rfCtrl) myLED.led('W'); disallow = B00000000; prevTime = millis(); uint8_t buf[VW_MAX_MESSAGE_LEN]; uint8_t buflen = VW_MAX_MESSAGE_LEN; // ---------------------------------------------------- Sensor Section curState.setEchoR(ultraSonic.pingR()); curState.setEchoL(ultraSonic.pingL()); curState.setIRL(myIR.pingL()); curState.setIRR(myIR.pingR()); //----------------------------------------------------- RF control if (vw_get_message(buf, &buflen)) // Non-blocking { int i; char letter; boolean getSignal = false; for (i = 0; i < buflen-1; i++) { letter = buf[i]; if(letter != passRfCtrl[i]) break; getSignal = true; } letter = buf[buflen-1]; if((getSignal)&&(letter == 'M')) { rfCtrl = !rfCtrl; //Serial.println("M"); // Serial.println(rfCtrl); } if((rfCtrl)&&(getSignal)) { //Serial.println(letter); switch (letter) { case 'S': curState.setAct('S'); curState.setSpeed(0); act = 'S'; break; case 'B': curState.setAct('B'); curState.setSpeed(curState.speed()-1); act = 'B'; break; case 'F': curState.setAct('F'); curState.setSpeed(curState.speed()+1); act = 'F'; break; case 'R': curState.setAct('R'); curState.setTurnAng(curState.turnAng() + 10); act = 'R'; break; case 'L': curState.setAct('L'); curState.setTurnAng(curState.turnAng() - 10); act = 'L'; break; case 'W': curState.setAct('W'); curState.setTurnAng(0); act = 'W'; break; case 'P': past = true; break; } } } // ---------------------------------------------------- Smart Section if(past) { if(myMem.isNext()) { curState.setSpeed(-myMem.getSpeed()); curState.setTurnAng(myMem.getAngel()); rfCtrl = false; // Serial.println(curState.turnAng()); } else { past = false; rfCtrl = true; } } curState.setLed('G'); if((curState.echoR() < 300) && (curState.echoL() < 300)) //stop { if((curState.echoR() != 0) && (curState.echoL() != 0)) //forward { bitSet(disallow, 2); curState.setLed('Y'); } } if((curState.irL() == 1)||(curState.irR() == 1)) //stop { bitSet(disallow, 2); curState.setLed('Y'); } if((curState.echoR() < 150) && (curState.echoL() < 150)) //back { if((curState.echoR() != 0) && (curState.echoL() != 0)) //forward { bitSet(disallow, 1); curState.setLed('R'); } } if (Serial.available() > 0) { incomingByte = Serial.read(); Serial.println("command"); if (incomingByte == 52) { curState.setAct('L'); curState.setTurnAng(curState.turnAng() - 10); act = 'L'; Serial.println("left"); } if (incomingByte == 53) { curState.setAct('W'); curState.setTurnAng(0); act = 'W'; Serial.println("stop"); } if (incomingByte == 54) { curState.setAct('R'); curState.setTurnAng(curState.turnAng() + 10); act = 'R'; Serial.println("right"); } } // ---------------------------------------------------- Drive Section if(past) { if(curState.speed() != prevState.speed()) myDrive.move(curState.speed()); if(curState.turnAng() != prevState.turnAng()) myDrive.turn(curState.turnAng(), curState.speed()); } if(rfCtrl) { switch (act) { case 'S': myDrive.stop(); break; case 'B': myDrive.move(curState.speed()); break; case 'F': myDrive.move(curState.speed()); break; case 'R': myDrive.turn(curState.turnAng(), curState.speed()); break; case 'L': myDrive.turn(curState.turnAng(), curState.speed()); break; } } else { if(!past) { if(!bitRead(disallow, 2)) curState.setSpeed(1); else { if(!bitRead(disallow, 1)) curState.setSpeed(0); else { if(!bitRead(disallow, 0)) curState.setSpeed(-1); else curState.setSpeed(0); } } myDrive.move(curState.speed()); } } // ---------------------------------------------------- Memory Section if(!past) { myMem.push(curState.speed(), curState.turnAng()); } // --------------------------------------------------- Final Section act = '?'; prevState = curState; deltaTime = millis() - prevTime; if(past) myLED.led('B'); else myLED.led(curState.led()); if((deltaTime < 100)&&(deltaTime > 0)) delay(100 - deltaTime); }Ссылки на библиотеки, схемы и т. д. в теме моей группы: https://vk.com/topic-73778892_35223613
Пульт управления.
Состав пульта: Ардуино Нано, джойстик, клавиатура на 5 кнопок, передатчик 433МГц.
Питание от Li-ion аккумулятора на 9В.
Текущий скетч для пульта:
#include <VirtualWire.h> int VRx; int VRy; int SW; int adc_key_val [5] = {1, 140, 300, 490, 710}; int key = -1; unsigned long curTime; char act, prevAct; char *msg = "kema"; void setup() { Serial.begin(9600); vw_set_ptt_inverted(true); // Required for DR3100 vw_setup(2000); // Bits per sec } // the loop routine runs over and over again forever: void loop() { VRx = analogRead(0); if(VRx < 200) { act = 'L'; msg = "kemaL"; curTime = millis(); } if(VRx > 800) { act = 'R'; msg = "kemaR"; curTime = millis(); } VRy = analogRead(1); //Serial.println(VRy); if(VRy < 200) { act = 'F'; msg = "kemaF"; curTime = millis(); } if(VRy > 800) { act = 'B'; msg = "kemaB"; curTime = millis(); } key = get_key (analogRead (3)); switch (key) { case 0: act = 'M'; msg = "kemaM"; curTime = millis(); break; case 1: break; case 2: break; case 3: act = 'P'; msg = "kemaP"; curTime = millis(); break; case 4: act = 'S'; msg = "kemaS"; curTime = millis(); break; } if(prevAct != act) { //Serial.println(act); vw_send((uint8_t *)msg, strlen(msg)); vw_wait_tx(); } if(( millis() - curTime) > 500) act = '?'; prevAct = act; delay(200); } int get_key (unsigned int input) { int k; int delta; if(input != 1023) Serial.println(input); for (k = 0; k < 5; k++) { delta = input - adc_key_val [k]; if (abs(delta) < 40) return k; } if (k >= 5) k = -1; // No valid key pressed return k; }Испытание инфракрасных датчиков колесного робота. Датчики фиксируют потерю поверхности перед колесами, робот останавливается на краю стола.
Видео https://vk.com/video-73778892_456239019
Добавил простой класс для работы с датчиками столкновения:
KemaCrash.cpp:
#include "Arduino.h" #include "KemaCrash.h" KemaCrash::KemaCrash(int crashL, int crashR) { _crashL = crashL; _crashR = crashR; pinMode(_crashL, INPUT); pinMode(_crashR, INPUT); } int KemaCrash::pingL() { return digitalRead(_crashL); } int KemaCrash::pingR() { return digitalRead(_crashR); }KemaCrash.h:
#ifndef KemaCrash_h #define KemaCrash_h #include "Arduino.h" class KemaCrash { public: KemaCrash(int crashL, int crashR); int pingL(); int pingR(); private: int _crashL; int _crashR; }; #endifЯ бы организовал классы так. Полный скетч здесь https://yadi.sk/d/d85yc6tx3EzPQg
Головной файл выкладываю.
/*Class_KemaCrash.ino */ // датчики #include "Cl_KemaCrash.h" const byte KemaCrashLeft_pin = 2; Cl_KemaCrash KemaCrashLeft(KemaCrashLeft_pin); void Do_KemaCrashLeft() { Serial.println("Stop"); } const byte KemaCrashRight_pin = 3; Cl_KemaCrash KemaCrashRight(KemaCrashRight_pin); void Do_KemaCrashRight() { Serial.println("Stop"); } void setup() { Serial.begin(9600); // датчики KemaCrashLeft.setup(); KemaCrashRight.setup(); } void loop() { // датчики KemaCrashLeft.loop (& Do_KemaCrashLeft); KemaCrashRight.loop(& Do_KemaCrashRight); }Вы же делаете машинку для Реального времени. Так пусть сами датчики и командуют остановку в опасных ситуациях.
Хорошо сделано, не спорю.
Но изначально у меня была концепция такая, что датчики не должны командовать, это не их дело.
Командовать должен "мозг" , а датчики лишь давать показания, когда их об этом попросят.
В моем случае опрос датчиков в основном скетче идет 10 раз в секунду, этого хватает в данном проекте.
Установил новые моторы. В связи с этим появилось несколько изменений:
1. Добавил дополнительно 2 аккумулятора (их стало 8 шт.), чтобы напряжение было 9В.
2. Блок с аккумуляторами закрепил под днищем колесного робота.
3. Так как редукторы малооборотистые, то достаточно стало 2-х скоростей.
Изменения в скетче и классе KemaDrive для Ардуино будут позже.
Схемы, скетчи и ссылки на детали в теме: https://vk.com/topic-73778892_35223613
и сколько ты его уже делаешь? еще с идеи, набросков, рисунков и т.д.
с весны 2014-го, но почти с 2-х летним перерывом)
то была 1я версия, а текущая версия с конца 2016 г
у меня больше. я в 13 году задумал новый танк, вырезал на чпу кое что и понеслось. сейчас 2017 и я его почти доделал)) правда почти неизвестно на сколько растянется
Блин.. озадачили. Одни мы с сыном чтоли практически за неделю вот это наклепали, причем "из говна и палок", а оно ещё и лучший результат на России показало? :)
а что ты хотел, один делает несколько лет, а двое за неделю))
научил своего робота поворачивать)
Оставил две скорости, мощности моторов достаточно, чтобы колесный робот поворачивался:
https://youtu.be/dissl3xMw9Y
да мощности этих моторов хватит и гусеницы крутить. я желтыми редукторами крутил, целый красный кирпич даже на танке для теста перевозил