Здравствуйте. Извините меня пожалуйста, если кому то мой вопрос покажется слишком «детским», но я не специалист в области робототехники. Я занимаюсь созданием Воздушных змеев и попутно пытаюсь приобщиться к КАП (фотографирование с воздушных змеев).
А для создания 360°-панорамной съёмки нужно чтобы камера поворачивалась по горизонту на все 360° и по вертикали на 180°, а также это должно происходить послойно с остановками на съёмку и в момент остановки нажимается кнопка затвора. Выглядит это приспособление держащее камеру вот так

Программное действие установки:
1. Камера повёрнута до максимума в верх, первый снимок.
2. Камера проворачивается по горизонтальной на определённый угол. Угол зависит от фокусного угла камеры, то есть например если это «мыльница» ею приходиться делать около 20 и более снимков чтоб охватить горизонт вокруг полностью. На каждой такой остановке идёт нажим кнопки сервой.
3. Когда камера проходит полностью круг по горизонту, она перемещается относительно вертикали в низ также на определённый угол зависящий от камеры. От максимума до полного полного низа около пяти получается. И на каждом таком повороте по вертикали происходит полный цикл проворота по горизонтали.
Управление должно производиться двумя сервмашинками и одним двигателем. Электродвигатель проворачивает по горизонтали, одна сервмашинка разворачивает по вертикали и одна сервмашинка делает нажим на кнопку затвора.
Также хотелось бы чтоб запуск производился с дистанционки на расстоянии около 200 метров, на такую высоту примерно поднимается камера. Команда одна единственная «старт», а остановка производиться уже по завершению полного цикла. Или на крайний случай таймер который будет запускать установку с задержкой времени, пока камера поднимается в воздух.
Теперь вопросы. Сможет ли CraftDuino управлять сразу тремя объектами: двумя сервами и двигателем? (не пинайтесь пожалуйста 🙂 ) Если не трудно то подскажите как собрать электрически всю эту штуку, то есть схемку если можно. Я так понял у вас как раз всё есть то что мне нужно:
1. https://robocraft.ru/store/catalog/1 САМ мозг 🙂
2. https://robocraft.ru/store/catalog/3 не очень сильная серва для кнопки
3. https://robocraft.ru/store/catalog/7 серва по мощней для поворота по вертикали (жаль что её нет у вас в наличии сейчас, но думаю это временно)
4. https://robocraft.ru/store/catalog/32 электродвигатель для поворота платформы по горизонтали. Но вот здесь возникает ещё один вопрос: можно ли управлять таким двигателем чтоб он останавливался в точном месте, — мне кажется для таких целей нужен шаговый электродвигатель??? Хотя можно использовать на сколько я знаю серву переделав её немного, так чтоб она крутилась на 360°.
Рад всё это у вас заказать и ни я один буду так как нас много, но мучают вопросы…
Помогите с решением этих вопросов пожалуйста если вам не трудно. Заранее благодарен. 🙂

18 комментариев на «“Использование CraftDuino в капинге”»
Интересное увлечение=)
Крафтдуины(Ардуины) в качестве мозгов, конечно же, более чем хватит.
С спуском по дистанционке готового решения предложить не могу… Может по проводку?=) Ну а по — легко.
Как работать с сервой описано и .
Как подключить моторчик — .
Использование шагового двигателя, ИМХО, весьма избыточное решение — точность такая вам, похоже, необязательна, а вес коснрукции выйдет больший.Тяжёлые они — КПД низкий и при одинаковом усилии шаговик будет тяжелее и крупнее моторредуктора или сервы.
Да, серву можно переделать(не оч сложно, но и не слишком легко=)
Да, можно заставить моторчик останавливатся в определённых положениях но это сложнее, тем более что его и подключить сложнее(понадобится драйвер)
Помоему проще с сервой.
Кстати, т.к. вес вам, похоже, важен, стоит посмотреть в сторону .
Спасибо за подробный ответ. 🙂 Ответ на самый главный вопрос: сколько можно подключить серв — был получен, то есть до 12 и мне это хватит за глаза 🙂 Что касается «старта» для начала буду использовать таймер, и если найду передатчик/приёмник на 200 метров и лёгкий, то можно будет подключить его через реле.
Пойду на страницу заказов. Друг тоже загорелся так что сразу два CraftDuino заказывать будем 🙂
Возможно, будет удобнее использовать модуль XBeePro? Его заявленная дальность больше километра.-) Правда, тут придётся сравнивать вес шилда с этим модулем (плюс, возможно, более ёмкий аккумулятор) и нить/корд, которой Вы пользуетесь.
Ну и, возможно, цена сыграет какую-то роль. Но зато какая гибкость всего устройства приобретается!
Удачи!
Как мало человеку надо для полного счастья 🙂 Я сегодня получил посылочку с детальками среди которых две платки CraftDuino, одна мне, другая другу. От радости не знаю теперь с какой стороны к ним подходить 🙂 Оперативненько так. Даже и не думал что за шесть дней придёт посылка. Спасибо 🙂
sanders, да интересная штука, спасибо что подсказали. По поводу цены… знаете уж очень хочется чтоб моё «дитятко» ну хоть капельку не хуже забугорных было, поэтому на цену наверно придётся закрыть глаза 🙂
Начинаю собирать результаты обязательно выложу здесь, если интересно.
Вот что получилось у меня 🙂
Круто=)))
Когда боевые испытания?
Проблемы все решились?
Прошу прощение, что очень долго не отвечал, я думал что мой топик ни кто не читает ну и сам перестал здесь появляться 🙂
Да все вопросы решил сам. Код переписал полностью по другому, была переделана серва под 180гр и ещё очень чего много.
«Боевые» испытания прошёл и уже во всю хожу снимаю 🙂
Сейчас новый вопрос возник, а задавать здесь уже боюсь… похоже здесь на вопросы отвечать не любят 🙂
я бы сказал — не успевают :)))
О как зацепило то 🙂 Ну тогда может у кого нибудь найдётся немного времени на меня? Про управление инфракрасниками здесь на сайте есть темы но они немного не о том… У меня в фотоаппарате находиться датчик инфракрасный, который предназначен чтоб управлять фотоаппаратом с пульта. Хочу отказаться от сервы которая нажимает на кнопку затвора и поставить инфракрасный диод(?)
Напрямую к ардуинко я так понимаю диод не подключишь… тогда что за блочёк нужен, какая схема? Что за сигнал нужно подавать с ардуино? Ну и может что-то ещё не знаю… Буду очень благодарен за помощь. Спасибо.
найдётся=)
также раздуплюсь ответить на предыдущие вопросы и мож койчего ещё полезного подсоветую=)
В хронологическом порядке:
Чтоб СРАЗУ реогировало на концевик надо использовать .
Чтоб уменьшить инерцию двигателя (на видео работы платформы видно, что имеется выбег) надо использовать динамическое торможение — на все входы драйвера(EN1, IN1, IN2) — еденицы.
Про эмулятор — низнаю=)
К дуинам светодиоды можно подключать напрямую, но ненужно=) В простейшем случае просто через резистор 100-200ом. , например, может пропускать ток до 100мА — чтоб наполную засветить понадобится транзистор. Но вам на полную и не надо — будет же впритык к фотоаппрату, да?
Проблемней узнать/поймать/воспроизвести нужную команду для фотика. Пульт то хоть есть?
Кстати, тогда в голову не пришло — можно и команду на старт подавать по ИК-каналу — на змея к дуине , в руки пульт самодельный (МК+кнопка+ИК-светодиод(ы)через транзистор)), тот же можно разогнать до ампера в импульсе, ещё можно поставить несколько светодиодов… добьёт в ясную погоду я думаю=)
Любят-любят, но иногда не успеваем, иногда и забЫваем=(
Кстати, классные фотки=)
Всем огромное спасибо 🙂 на все вопросы ответы нашёл результат достигнут
Супер=)
может опишете своё решение — скетч, схема (в отдельном посте=)?
Да и про вашу систему подвеса вцелом многим былобы интересно почитать поподробней.
К сожалению это не моё решение и приписывать к себе я не буду 🙂 Управление ИК портом фотоаппарата через Ардуину разработал я лишь взял готовое. Там у него всё подробно расписано.
А в целом о риге (тоже не моё изобритение 🙂 ) в принципе можно, только нужно время чтоб собраться, хотя о нём всё и так уже 🙂 И не только о моём но о ригах других участников идут более подробные обсуждения.
Помогите пожалуйста написать код или правильно подсоединить детали.

На эмуляторе в замен драйвера (нет в библиотеке) поставил светодиоды, а концевик — кнопка:
Увеличить
Это электрическая схема:

Увеличить
#include <Servo.h> //Сервы Servo servo_big; // создаём объект для контроля сервы вертикального наклона Servo servo_sm; // создаём объект для контроля сервы затвора int pos = 0; // переменная для счётчика int angle = 6; // количество горизонтальных проходов int valserv = 0; // перемнная для определения положения серв //мотор int in1 = 7; //INPUT1 драйвера двигателя подключен к 7 пину int in2 = 8; //INPUT2 драйвера двигателя подключен к 8 пину int enable = 11; //ENABLE1 драйвера двигателя подключен к 11 пину //концевик int btnPin = 12; //концевик подключен к 12 пину int btnval = LOW; //положение концевика (LOW - разомкнут, HIGH - замкнут) int btn = 0; //перменная счётчика нажатия концевика //--- void setup() { servo_big.attach(5); // серва вертикальная подключена к 5-му пину servo_sm.attach(6); // серва затвора подключена к 6-му пину pinMode(in1, OUTPUT); // выходы на драйвер pinMode(in2, OUTPUT); pinMode(enable, OUTPUT); pinMode(btnPin, INPUT); // вход концевика Serial.begin(9600); // общение с COM портом (на всякий случай для проверок) digitalWrite(in1, HIGH); // подача сигналов на контакты драйвера двигателя digitalWrite(in2, LOW); } //---- void loop() { //---- if(btn == 0) // если нулевой (верхний) уровень { servo_sm.write(0); // выставляем серву затвора в ноль valserv = servo_big.read(); // и проверяем положение вертикальной сервы if(valserv>0) // если не в нулевом положении { for(pos = valserv; pos > 0; pos -= 1) // медленно выводим в ноль { servo_big.write(pos); delay(100); } } } //---- if(btn < angle) // контроль количества срабатывания концевика { analogWrite(enable, 255); // запуск двигателя горизонтального разворота delay(2000); // пауза для обработки снимка //--- for(pos = 0; pos < 90; pos += 1) // малая серва нажимает на спуск затвора { servo_sm.write(pos); delay(15); } servo_sm.write(0); // возвращаеться назад //---- btnval = digitalRead(btnPin); // проверяем состояние концевика if(btnval == HIGH) // если замкнут { analogWrite(enable, 0); // останавливаем двигатель for(pos = btn * (180 / angle); pos < btn * (180 / angle) + 180 / angle; pos += 1) { servo_big.write(pos); // переводим серву на заданный угол delay(100); } btn += 1; // подщитываем количество раз нажатий на концевик delay(100); // пауза передначалом движения по горизонту analogWrite(enable, 255); // запускаем двигатель } } //---- if(btn >= angle) // если весь цикл пройден { analogWrite(enable, 0); // двигатель отключаеться servo_sm.write(0); // сервы возвращаються в нулевые состояния valserv = servo_big.read(); for(pos = valserv; pos > 0; pos -= 1) { servo_big.write(pos); // серва наклона камеры возвращаеться медлено delay(100); } } //---- }Проблема в том, что идёт обработка данных по ступенькам, а это не очень нравиться… если нажат концевик то всё должно останавливаться и занимать новую позицию… а здесь получается, что пока не пройдёт чтение всего кода, система не среагирует на концевик. То есть надо жать на концевик пока система не определит, что концевик нажат, а за это время двигатель прокрутит платформу ещё дальше, разумеется концевик от пустится и система его уже не увидит…
Ка сделать, чтоб по нажатию концевика система начинала сразу же обрабатывать данные.
Концевик показывает что платформа развернулась на 360°. В этот момент останавливается двигатель горизонтального движения, и серва вертикального поворота передвигается на следующий уровень. Двигатель запускается и идёт следующий круг. Вместе с движением платформы по кругу срабатывает серва кнопки затвора, нажимая на кнопку с заданным интервалом.
По эмуляции вроде серва кнопки работает одновременно с движением двигателя, но на практике ещё не проверил, так как платформа ещё не собрана. Но двигатель и концевик уже подсоединены и двигатель останавливается если удерживать концевик при этом двигатель проворачивается почти на целый оборот иногда на полтора.
И ещё, тоже в эмуляторе, на нулевой позиции серва вертикального поворота почему то становиться на 90° ???
Пожалуйста помогите, кроме вас обратиться не к кому, а у самого уже свой мозг начинает плавиться. 🙂
Я так и знал что про меня забыли 🙂 вот и стал ножками стучать чтоб меня увидели 🙂
Не могу понять как же это пропустил статью про … а я решил эту часть с помощью разбивки на шаги движение двигателя. Хотя может и моё решение лучше (?) было по причине того, что на морозе двигатель отказывался крутиться, если на него подавалось небольшое напряжение, при уменьшении скорости его движения. Скажем при подаче от 200 и ниже двигатель отказывался крутиться (может смазка замерзала не знаю, но в тепле начинал двигаться) А так как мне надо было регулировать скорость поворота платформы то я просто стал его разбивать на импульсы с полной подачей напряжения. Можно было менять скорость разворота платформы, отсчитывать также, опираясь на шаги двигателя, количество раз нажимания на затвор в круге. А чтоб двигатель не дёргал платформу и не протягивался, подача импульса происходит с плавным нарастанием/убыванием, используется for():
void Moto() { int dpos; for(dpos=0; dpos<255; dpos+=5) { analogWrite(moto_pin,dpos); } delay(10); for(dpos=255; dpos>0; dpos-=5) { analogWrite(moto_pin,dpos); } delay(10); }Естественно в момент остановки проверяется замкнуты ли контакты геркона(за место концевика поставил геркон) если замкнуты то производиться действие, и фиксируется запрет на дальнейшую проверку геркона на замыкание, пока платформа не выйдет в разомкнутую зону. При выходе — запрет снимается.
Спасибо Zoltberg но на прошлые вопросы уже можно не отвечать 🙂 на главный с прерыванием вы уже ответили, остальные я уже решил 🙂 Если интересно приведу код который сейчас управляет ригом:
// Pekavet v4 #include <Servo.h> //---- int TimeDelayStart = 300; // время задержки старта в секундах int Cycle = 5; // количество полных циклов int cycleStep; Servo servosm; // создаём объект для контроля сервы затвора int ZatvStep = 10; // задержка между срабатываниями сервы затвора в шагах двигателя int zatv; unsigned long time; // переменная отсчитавающая время int servosm_pin = 5; // пин для сервы затвора Servo servobig; // создаём объект для контроля сервы вертикального поворота // 809, 2180 int min_servo = 1200; int max_servo = 2180; int LevelStep = 4; // количество круговых уровней сделанных платформой int levelval; // переменная для хранения количиства уровней int servobig_pin = 6; // пин для сервы вертекального поворота камеры //---- int moto_pin = 11; // пин для управления двигателем горизонтальногоразворота камеры int motoIN2_pin = 8; // пин для драйвера IN2 двигателем горизонтальногоразворота камеры int motoIN1_pin = 7; // пин для драйвера IN1 двигателем горизонтальногоразворота камеры int motostep; // шаги двигателя //---- int btnval; // переменная состояния концевика int btn_pin = 12; // пин для концевика boolean btn_block = false; // контроль концевика от удержания boolean foto_go = false; int kadr; //------------------------------------------------------------------------------------------------------ void setup() { //---- pinMode(motoIN2_pin, OUTPUT); // назначение выход 8-му пину для IN2 драйвера двигателя pinMode(motoIN1_pin, OUTPUT); // назначение выход 7-му пину для IN1 драйвера двигателя digitalWrite(motoIN2_pin, LOW); // назначение направление движения digitalWrite(motoIN1_pin, HIGH); // для двигателя analogWrite(moto_pin,0); //---- pinMode(btn_pin, INPUT); // назначение входа для концевика //---- Serial.begin(9600); // инициализация работы с COM-портом } //------------------------------------------------------------------------------------------------------ void loop() { //----------------------- if(cycleStep > Cycle-1) // если циклы пройдены полностью то останавливаем программу { ServoBig (809); return; } //----------------------- if(TimeDelayStart > 0) // задержка работы перед стартом для поднятия камеры { delay(1000); TimeDelayStart--; ServoBig (2000); kadr++; if(kadr>=30) { kadr=0; ServoSmall(); } } else { //----------------------- // запуск двигателя Moto (); //----------------------- btnval = digitalRead(btn_pin); // узнаём состояние концевика if(btnval==HIGH && btn_block==false) // если концевик зажат и не стоит блокировка { if(levelval==LevelStep) // подсчитываем уровни и циклы { levelval=0; cycleStep++; } if(levelval <LevelStep) { analogWrite(moto_pin,0); levelval++; ServoBig (min_servo + ((max_servo-min_servo)/(LevelStep-1))*(levelval-1)); // выставление вертикальной сервы на угол согластно уровня ServoSmall(); // делаем снимок foto_go=true; // разрешаем делать съёмку } btn_block=true; // ставим блокировку от зажима концевика } if(btnval==LOW) // если концевик отпущен { btn_block=false; // снимаем блокировку } //----------------------- if(foto_go==true) { motostep++; if(levelval==1 || levelval==LevelStep) { zatv=ZatvStep*3; } if(levelval>1 && levelval<LevelStep) { zatv=ZatvStep; } if(motostep >= zatv) // если наступил момент для срабатывания сервы для затвора { ServoSmall(); // делаем снимок motostep=0; } } //----------------------- } } //------------------------------------------------------------------------------------------------------ void Moto() { int dpos; for(dpos=0; dpos<255; dpos+=5) { analogWrite(moto_pin,dpos); } delay(10); for(dpos=255; dpos>0; dpos-=5) { analogWrite(moto_pin,dpos); } delay(10); } //------------------------------------------------------------------------------------------------------ void ServoBig (int posAngle) // функция поворота вертикальной сервы { servobig.attach(servobig_pin, min_servo, max_servo); int pos = servobig.readMicroseconds(); // определение положения сервы вертикального наклона while(pos > posAngle) { pos--; delay(5); servobig.writeMicroseconds(pos); } while(pos < posAngle) { pos++; delay(5); servobig.writeMicroseconds(pos); } servobig.detach(); // отключаем серву } //------------------------------------------------------------------------------------------------------ void ServoSmall() // функция поворота сервы затвора { servosm.attach(servosm_pin); // подключаем серву кнопки затвора к 5-му пину int pos; //---- for(pos = 580; pos <= 800; pos +=5) // делаем нажим на кнопку затвора { // здесь нужно проработать код servosm.writeMicroseconds(pos); // для подстройки к параметрам фотоаппарата delay(5); } delay(700); //---- for(pos = 800; pos >= 580; pos -=5) // делаем нажим на кнопку затвора { // здесь нужно проработать код servosm.writeMicroseconds(pos); // для подстройки к параметрам фотоаппарата delay(5); } //---- servosm.detach(); // отключаем серву }В коде пока реализована задержка на срабатывание кода для того чтоб успеть поднять камеру на высоту. Скоро должны придти на 300 метров и тогда перепишу уже код. Управлять стартом диодом может и можно было бы но
не на большое расстояние, поэтому как-то сразу откинул.
А вот управлять кнопкой затвора ИК диодом это в самый раз, меньше городить арматуру подвески.
Но вот с ним то как раз таки и возник вопрос. Весь прикол в этих импульсах. Есть конечно уже готовые решения например но когда я увидел цену меня чуть кикоз не скрутил, это ж надо люди десяти рублёвый диод за такие бабки продают, хотя бы уж какой нибудь корпусик соорудили да проводки, как на сервах спаяли бы в лапшу. Есть ещё один вариант (точнее варианты на ебау)http://viewitem.eim.ebay.ru/15M-Remote-Sony-NEX-5-A550-A380-A330-A850—RMTDSLR1/270697615827/item здесь уже более менее цена адекватная да и девайс по приличней :). Диод закрепить на стойке возле глазка фотоаппарата, платку спрятать вместе с Ардуинкой, ну и естественно подключит управление замыканием контактов кнопок.
Но вот всё таки хочу сначала попробовать сам собрать, но для этого нужно выяснить на какой чистоте идёт приём у фотоаппарата, каким образом добиться выдачу этой чистоты с Ардуинки. И какой импульс нужен для срабатывания в фотоаппарате затвора.
И ещё чем отличаются ИК-диоды в пультах от TSAL4400? Можно ли пультовые использовать? И почему они прозрачные в пультах, а TSAL4400 с голубоватым оттенком?
Про подключение на прямую я имел ввиду без того блочка который виднеется под кембриком у gentlesовцев. Кстати спасибо я понял теперь зачем транзистор: для усиления свечения диода. Это разуметься не нужно, диод в плотную будет стоять к ИК-порту.
Спасибо за оценку фоток 🙂