Управление двумя сервомашинками
- Войдите на сайт для отправки комментариев
Пнд, 16/07/2012 - 08:28
Сразу скажу, что не программист. Необходимо управлять 2мя сервомашинками. Алгоритм простой. Первая серва поворачивается на угол 15 град останавливается и ждет пока вторая прошагает от 0 до 150 град и вернется назад, затем поворачивается еще на 15 и вновь ждет танго от второй. Так первая серва должна пробраться до 150 градусов. Написал топорный код. Проблема в том, что все вроде и работает но при выполнении второго цикла сервы начинают бесится, постоянно загорается L светодиод (как я понял ардуино перезагружается). Питание не просаживается. Проверял на нескольких платах. Исход один - слезы, печаль и уныние.
#include <Servo.h> Servo myservov; // создаём объект для контроля сервы (вертикаль) Servo myservog; // создаём объект для контроля сервы (горизонталь) int posv = 0; // переменная для хранения позиции сервы (вертикаль) int posg = 0; // переменная для хранения позиции сервы (горизонталь) int PhotoPin=9; // переменная для фотопина void setup() { myservog.attach(4); // серва горизонтали подключена у 4-му пину myservov.attach(7); // серва вертикали подключена у 7-му пину pinMode(PhotoPin, OUTPUT); // девятый пин на выход (управление фото) } void loop() { myservog.write(30); // горизонтальную серву повернули на 30 градусов delay(1000); // ждем 1 с for(posv = 0; posv < 150; posv += 30) // вертикальную серву с шагом 30 прогнали до 150 град { myservov.write(posv); // delay(1000); // ждём 1000 с пока серва займёт новое положение } myservov.write(0); // вернули вертикальную серву в 0 градусов delay(1000); // ждем 1 с //////////////////////////////////////////////////////////////// myservog.write(60); // горизонтальную серву повернули до 60 градусов delay(1000); // ждем 1 с for(posv = 0; posv < 150; posv += 30) // вертикальную серву с шагом 30 прогнали до 150 град { myservov.write(posv); // delay(1000); // ждём 1000 с пока серва займёт новое положение } myservov.write(0); // вернули вертикальную серву в 0 градусов delay(1000); // ждем 1 с //////////////////////////////////////////////////////////////// myservog.write(90); // горизонтальную серву повернули до 90 градусов delay(1000); // ждем 1 с for(posv = 0; posv < 150; posv += 30) // вертикальную серву с шагом 30 прогнали до 150 град { myservov.write(posv); // delay(1000); // ждём 1000 с пока серва займёт новое положение } myservov.write(0); // вернули вертикальную серву в 0 градусов delay(1000); // ждем 1 с //////////////////////////////////////////////////////////////// for(posg = 180; posg>=1; posg-=1) // вернули горизонтальную серву в 0 градусов { myservog.write(posg); delay(15); } return; }
Как раз все симптомы на то что именно просадка напряжения. И что вы проверяли, когда меняли платы? И как по вашему разные платы могут повлиять на просадку? Подключите сервы от отдельного источника питания соединив земли дуины и этого источника, тогда просадки не будет.
Изначально полагал, что проблема в коде. Вот и менял платы. Проверял питание очень просто - при работе сервомашинок цеплялся мультиметром к выводам акк.батареи, напряжение не просаживается. Вот и думается мне что дело в коде. Завтро попробую запитать серву от отдельного источика.
А какая батарея? и как вы сервы подключаете?
Если севрвы подключены к +5В дуины, то естественно на батарее вы никакой просадки не увидите. Если батарея не больше 7,5 вольт то можно подключить питание серв напрямую к батарее.
Батарея на 7.4 1500 мАч. Сервы действительно сидят на 5 В ардуины. Напругу смотрю непосредственно на батареи. И она вполне себе ничего. Загвоздка в том, что прошивая сторонний код, написанный программистом сервы крутят вполне приемлемо. Плата не перезагружается. Правда код сложноват для меня. Вот и пытаюсь написать свой понятный и простой.
Скорее всего в том коде реализован плавный старт сервы для уменьшения токов и увеличения ресурса шестерней. Просто подключите питание серв к аккумулятору напрямую.
А сервы наверное что то типа HX12K, HX5010, MG995 или SG5010 ?
У меня SA1135
http://sferahobby.ru/item/view/id/143
Плавный ход в сторонней программе действительно есть. Появилась проблемка - при старте серва крутится на все 180 сначала в одну затем в другую стороны. И так 2 - 3 захода затем пошел на исполнение код. Видимо тяжело ей нуль найти.
Это при подключении напрямую к аккумулятору?
запитал сервы отдельно от аккум. Плата запитана от отдельного источника. Объеденил землю ардуины с минусом аккум. ноль эффекта. Теперь сервы вообще молчат. Нужно ли объеденить нейтраль источника для ардуины и минус батареи?
запитал сервы отдельно от аккум. Плата запитана от отдельного источника. Объеденил землю ардуины с минусом аккум. ноль эффекта. Теперь сервы вообще молчат. Нужно ли объеденить нейтраль источника для ардуины и минус батареи?
Косяк нашел. Все работат. Действительно для серв нужен отдельный источник. maksim спасибо за помощь.
Ну почему же... можно использовать тот же источник, только питание нужно брать не с дуины, а либо с аккумулятора, либо с отдельного стабилизатора (DC-DC преобразователя) , подключенного к аккумулятору.
Уже заказал инвертер. Вот теперь то мы развернемся. Может вы мне подскажете как из цикла void loop выходить? А то они у меня до третьей мировой крутят.
Самый простой способ - это в него не заходить.
Я так понимаю это какая-то панорамная головка?
Да панорамка простейшая. А без цикла совсем никак. Ругань и слезы. Но я так понимаю можно цикл loop вообще не использовать?
Можно не использовать, но быть должен. Я же вам выше код написал, не работает?
Кстати, для вращения на 360 градусов можно серву переделать, но тогда положение можно будет определить только по времени работы сервы.
Код не проверил разберать макетку лень. Но смысл понял. По поводу 360 не совсем понял. Если стандартой серве задается угол, то после переделки под 360, задается скорость? Тоесть после переделки получается серва постоянного вращения?
Да, при переделке потенциометр внутри сервы фиксируют так, что бы серва стояла на месте при myservo.write(90); и при меньших значениях она крутится в одну сторону, а при больших в другую и чем больше отклонение от 90 тем выше скорость вращения.
Проверил ваш вариант кода. Цикл все равно есть. И выползти из него никак. Спасаюсь дикой задержкой в конце кода.
>Цикл все равно есть.
Конечно. Его не может не быть. В любом скетче, в неявном виде, присутсвует "главная функция".
Ее добавляет ArduinoIDE без вашего желания. Замечу, так же что если бы этого не делала она - это обязательно должны было-бы делать вы.
>И выползти из него никак
А куда вы выползти хотите? Куда, по вашему, должно передатся управление при выходе из цикла? Операционной системы, как на компе, тут нет, вернуть "код возврата" - некому. Вся "вселенная" состоит из одного только скетча. Да и на большом "компе" возврат в операционку - не означает выход из цикла, потому как сама операционка - большой цикл (опроса монитора, клавиатуры и т.д. и т.п.)
>Спасаюсь
Да от чего спасаетесть-то? Чем вам пустой цикл "колет"? Какой негативный эффект вы в этом усматриваете?
>дикой задержкой в конце кода
Fail. Не спаслись. Все умерли. :) Как вы думаете реализованна задержка? Функция delay() не вызывает локальной инкапсуляции пространственно временного континиума :).
Так что "задержка", это такой же цикл как и тот от которого вы бежали. Только крутится не бесконечно, а "пока не пройдет определенной количество миллисекунд").
А раз задержка вас "спасает" - значит проблема не техническая. Так как "задержка" в данном случае это "плацебо" в чистом виде. Что-то "лечить" она может только если эта "болезнь" - не существует.
Вообщем сформулируйте проблему, а не способ которым вы пытаетесть ее решить (выход из цикла).
Цикличности (если я правильно понимаю) не может быть никак, так как я весь ваш код поместил в функцию setup(), пока не нажмется ресет или не выключите-включите питание программа выполнятся по новой не будет. Вы может не тот скейтч залили? Он находится в #13 сообщении в свернутом виде.
Еще раз его копирую вот он:
Да и кстати, еще можно сделать вместо дикой задержки безконечную задержку:
Скейтч работает на ура. И даже задержки не потребовалось. Спасибо.
Ещё бы в одну функцию все это засунуть. Красивей и экономней.
Что "все это" ? И если имелся ввиду код, то он и так в одной функции находится, в первом случае в функции setup() , а во втором в функции loop().
Что "все это" ? И если имелся ввиду код, то он и так в одной функции находится, в первом случае в функции setup() , а во втором в функции loop().
Скорее всего имелся ввиду рефакторинг: вынос похожих кусков кода в функцию. снижения дублирования.
Топикстартеру:
Кстати, если воспользоватся поиском, то можно найти обсуждения подобных задачь
http://arduino.ru/forum/programmirovanie/preryvanie-i-servy#comment-11697
В #13 я там как раз и дал функцию. При этом еще сервы поворачиваются синхронно и с регулируемой скоростью.
И, опять-таки похожее было в http://arduino.ru/forum/programmirovanie/zapominanie-poziii-servo#comment-10321