Управление роботом на сервомоторах через ИК
- Войдите на сайт для отправки комментариев
Чт, 10/03/2016 - 17:17
#include <IRremote.h> #include<Servo.h> Servo servoG1; Servo servoV1; Servo servoG2; Servo servoV2; Servo servoG3; Servo servoV3; Servo servoG4; Servo servoV4; int RECV_PIN = 11; // назначаем 11-ый вывод для подключения фотоприемника IRrecv irrecv(RECV_PIN); decode_results results; void setup() { servoG1.attach(9); // s is on pin 8 servoV1.attach(2); servoG2.attach(3); servoV2.attach(4); servoG3.attach(5); servoV3.attach(6); servoG4.attach(7); servoV4.attach(8); Serial.begin(9600); // устанавливает скорость обмена данными с компьютером irrecv.enableIRIn(); // функция начала приема } void loop() { if (irrecv.decode(&results)) { // если сигнал принят Serial.println(results.value); // выводим его на экран компьютера if (results.value > 16000000 && results.value < 17000000){ if (results.value == 16718055) // если принятый код равен одному из запомненных нами (кнопка 2) { servoV3.write(60); // 3-я нога вверх servoG3.write(15); // 3-я нога вперёд delay(500); servoV3.write(90); // 3-я нога вниз delay(500); servoV4.write(120); // 4-я нога вверх servoG4.write(165); // 4-я нога вперёд delay(500); servoV4.write(90); // 4-я нога вниз delay(500); servoG1.write(165); // 1-я нога назад servoG2.write(15); // 2-я нога назад servoG3.write(75); // 3-я нога назад servoG4.write(105); // 4-я нога назад delay(500); servoV1.write(120); // 1-я нога вверх servoG1.write(105); // 1-я нога вперёд delay(500); servoV1.write(90); // 1-я нога вниз delay(500); servoV2.write(60); // 2-я нога вверх servoG2.write(75); // 2-я нога вперёд delay(500); servoV2.write(90); // 2-я нога вниз delay(500); } if (results.value == 16726215) // если принятый код равен второму из запомненных нами (кнопка 5) { servoG1.write(105); // 1-я нога servoG2.write(75); // 2-я нога servoG3.write(75); // 3-я нога servoG4.write(105); // 4-я нога servoV1.write(90); // 1-я нога servoV2.write(90); // 2-я нога servoV3.write(90); // 3-я нога servoV4.write(90); // 4-я нога } } irrecv.resume(); // ждем прием следующего сигнала } }
Доброго всем дня. Пилю скетч для управления четырёхногим роботом с 8-ю сервами и с ИК-датчиком. Часть кода написал (вперёд, стоп), но возник вопрос. При движении вперёд (при нажатии на кнопку на ИК-пульте) робот делает цикл перемещения ног (3-4-1-2) и встаёт. Что бы он опять пошёл, приходится опять нажать кнопку. Как завершить цикл движения, что бы он повторялся без нажатия кнопки? Знаю, что мой код с кучей делаев довольно убогий. Мне тут подкидывали код движения вперёд с shwitch-case, но я слабоват пока в программировании и не разобрался как его вписать.
Это вариант кода без делай. В этом варианте для движения вперёд приходится нажимать кнопку для каждого движения ноги (нажал - одна нога сработала, нажал -следующая и т.д.) кроме case 4, когда все четыре ноги поворачиваютя. Код без ИК составляющей работает нормально. Как сделать, что бы цикл движения происходил непрерывно до нажатии кнопки "стоп"?
У вас идет проверка на нажатие кнопки. Сделайте так чтобы в этой проверке не обработчик перемещения стоял, а смена флага. А по флагу уже заставляйте робота шагать или останавливаться.
А как это выглядит вообще? Смена флага?
Создаешь переменную в самом начале
bool _flag_=false;
Дальше обращаешься к ней: Если нажата одна кнопка делаем true, если нажата другая делаем false. Так будет определяться движется робот или нет.
Ну а само движение выполняем только если флаг true.
Попробую, конечно. Но, если можете, вставте мне в код, пожалуйста, что бы я посмотрел, как правильно.
Тогда опишите что происходит по ажатию "2" и "5". Правильно я понимаю что "2" это идти вперед, а "5" это остановка?.
Да, именно так. Я почти дописал скетч с делаями. Добавил назад и развортот влево. Осталось вправо добавить. Выкладывать не стал, чтоб не загромождать. С делаями всё также, одно нажатие-один цикл.
Попробуйте так проверить не на чем
Обязательно попробую в понедельник. Ибо робот там квартирует пока.
Vosara не, не получается. Теперь на каждое нажатие происходит половина движение, т.е. на каждое движение ноги нужно 2 нажатия.
Все верно, думал предложили вариант типа моего, но оказалось немного не так. Проверка флага не должна быть только при нажатой кнопке:
Nevkom результат прежний. Одно нажатие - выполнение case 1, второе - выполнение case 2 и т.д.
Вот полный вариант кода с делаями. Вперёд-стоп-назад-влево-вправо. Иногда, правда, заглючивает. От переизбытка делаев, наверное. Алгоритм прежний, одно нажатие - один цикл. Непрерывно не движется.
Все верно, вынес, но не до конца.
Сделайте 2 фукции: прием нажатия с пульта и обработчик движения. Не срабатывает по причине что ждет когда будет нажата кнопка (
if
(irrecv.decode(&results)) {
// если сигнал принят
). Ну или для начала перенеситеif
(run == 1)
в конец loop:Ну а дальше если теперь будет работать нормально наращивай функционал. Кстати комментарий не читали к коду видимо, иначе додумались бы сдвинуть условие еще ниже.
И кстати начало движения в другую сторону советую сделать через нулевую точку. Хоть так будет и медленнее, но зато заморочек меньше с переходами состояний.
Ага, завтра попробую.
P.s. Это у меня так старший сын типа робототехникой занимается.
nevkom большое спасибо. Всё вроде заработало. Буду сейчас пыжиться остальные части скетча привинчивать. Про нулевую точку знаю (опыт - сын ошибок трудных). Смену направления только через "стоп" делаю во избежании глюков. Про результат отпишусь.
С привинчиванием пока не очень получается. Добавил движение "назад" (кнопка 8). Но при нажатии кнопки 8 всё равно выполняется движение вперёд (кнопка 2). Сначала оставил номера case как в "вперёд", робот идёт вперёд. Поменял на другие - ничего не изменилось, гребёт врепёд. Что-то я недопонял видимо. Что я не так сделал?
Потому что тупо скопировали блок. У вас var меняется не правильно.
Можно сделать проще. Если я правильно понял движения делаются в обратном порядке при движении назад.
Добавьте переменную byte dir. Сделайте так чтобы при движении вперед она принимала значение 1, а при движении назад - 2.
Ну и пример реализации (остальные состояния додумаете сами):
Не хватает ума понять, как сделать. Мне бы понять как правильно var менять, что бы следующий блок движений выполнялся. А то мне ещё влево-вправо описывать.
var определяет у вас порядок движений. Логично предположить что у вас движение назад будет происходить в обратном порядке от движения вперед. Иначе говоря при движении вперед var должен меняться в порядке 0-1-2-...-8, при движении назад порядок должен быть 8-7-6-...-0.
А вот для поворота/движения боком (смотря что вы будете реализовывать) подойдет то что вы сделали в 132-182 строках по логике. Но чтобы перейти на следующий шаг var должна меняться правильно, а у вас он прыгает на первый цикл. Иначе говоря условия вы поменяли, а переходы по условиям не обеспечили. Да и не надо var гнать выше - условие обеспечивает run.
Надеюсь теперь более понятно объяснил.
Да, теперь стало более понятно. Я не понял только, как обеспечить переходы по условиям. Разные варианты пробывал, но не смог переключить на другой цикл.
Вот как должен выглядеть мой код вперед-назад:
Вот как должен выглядеть ваш код, найдите разницу между исправленным и оригиналом, тогда поймете где была ошибка:
Кстати для справки, иде 1.6.7. Первый скетч:
Тут еще оптимизатор компилятора неплохо поработал, но разница хоть и небольшая, но есть. А делают скетчи по идее одно и то же.
Дважды построчно проверил код, разницы не нашёл. Ведёт себя так же, повторяет первый цикл.
Я правильно понял что если со стопа нажать 8, то идет вперед? Код правильный принимается? Движение описано правильно для заднего хода?
Обратите внимание на строки 141, 145, 150, 154, 161, 166, 170, 175 и 179.
Мой код работает как надо? У моего варианта кстати ситуация что не надо переходить через 0 для начала движения назад.
Да, если нажать 8 идёт вперёд. В моём коде с делаями движется правильно. Это загруженый код.
Ваш код при нажатии 8 также имитует движение вперёд, но по довольно кривому алгоритму.
Опишите как он должен шагать. Кажется я понял что простой инверсии движений (перебор в обратном направлении) будет не достаточно. Когда опишите поймете почему. Ваш вариант в этом случае будет работать, а мой не будет (он будет идти также вперед, но иначе перебирая ноги). По моему варианту тоже можно сделать, но состояний нужно больше описывать, в каждом case должны срабатывать все сервы.
При описании указывайте состояние серв (их позиции).
Какова вероятность что ик датчик не срабатывает как надо?
Это полный код с делай. В коде с делай датчик нормально срабатывает, но отрабатывает один цикл и ждёт повторное нажатие кнопки. Мне бы понять как переключить на другой цикл по нажатию кнопки со shwich-case.
Этот код я видел. Также проверил что движения перенесены правильно. Так что двигаться должен назад. Кстати у вас ноги 1 и 4 спереди, а 2 и 3 сзади все верно? Есть подозрение и обоснованое что не происходит переход по run=2. А все потому что тип данных у вас все еще bool, а не byte или int.
Кстати посмотрите статью, там интересно описывают логику, за счет чего можно много уменьшить код: http://cxem.net/uprav/uprav56.php
А вот есть еще двуногий: http://robocraft.ru/blog/projects/681.html
И веселый четырехног: http://robocraft.ru/blog/projects/706.html
Нет, ноги спереди 1 и 2, сзади - 3 и 4. Если представить корпус робота как квадрат, то ноги выходят из углов с небольшими отклонениями от геометрического центра квадрата (90,90,90,90 - если через центр, 105,75,75,105 - у меня). Это положение "стоп", с которого всё начинается. При движении вперёд сначала начинают последовательно двигаться задние ноги (3 и 4), т.к. передние (1 и 2), уже ориентированы вперёд. Затем идёт отработка всех ног одновременно назад (т.е. получается ноги стоят на месте, а корпус перемещается вперёд). Ну и потом , т.к. ноги 1 и 2 перемесились назад, они отрабатывают последовательно движение вперёд. Вот цикл "вперёд". Попробую сейчас bool на byte и int поочереди поменять.
Урраааа!!! bool на byte поменял, вернул var и case номера как в цикле "вперёд" и заработало. Спасибо огромное!!! Сейчас буду влево-вправо прибивать.
На мои радостные крики пришёл начальник и узнав в чём дело сказал, так тип данных Bool, говорит, только 0 и 1 принимает значения. Поэтому циклы дальше еденицы и не работали. Век живи, век учись.