Автоматическая панорамная головка
- Войдите на сайт для отправки комментариев
Друзья здравствуйте!
Давно хотел собрать подвес для фотоаппарата для авто-съемки панорам
Механику всю собрал, там все просто. фотик небольшой 400гр, так что всего
2 сервомашинки постоянного вращения без редукторов вращают фото в 2 плоскостях.
Я сначала хотел делать все на шаговых двигателях, но не нашел нормальных , пришлось заказывать 2 сервы SM-S4315r постоянного вращения. (Меня подкупил высокий момент до 15 кгс)Лишь когда они приехали, я понял что лоханулся, что такие сервы нельзя позиционировать в пространстве.
Пришлось покупать 2 потенциометра и начинать изучать программирование на ардуино.
Пытаюсь делать сам, принципы понимаю но спотыкаюсь на мелочах.
и так проблема №1:
Мне нужно чтобы серва1 крутила подвес и останавливалась каждые 45 градусов(всего 9 раз) после каждой остановки происходил бы спуск затвора, ну это позже и отдельная тема.
Я поковырялся и написал скетч который просто ставил серву в определенный угол, дабы проверить потенциометр.
#include <Servo.h>
Servo servo1;
int servopin1=10;
int potensiometr = A9;
int val;
void setup()
{
servo1.attach(servopin1);
}
void loop(){
val = analogRead(potensiometr);
int pos = map(val,0,1023,0,200);
if(pos<30)
{
servo1.write(80); //гоним серву вперед до заданного положения
}
else if(pos>30)
{
servo1.write(100); //гоним серву назад до заданного положения
}
else{
servo1.write(90); //иначе останавливаемся, т.е то что нужно.
delay(1000);
}
}
}
И он даже работает, что вызывает у меня дикую радость, так как это первый мой скетч и он заработал, но дальше я начал спотыкаться. Я понимаю что нужно запускать FOR. но как я не пытался исхитриться у меня ничего не получается. серва начинает дергаться или просто тупо кружиться. Помогите, пожалуйста, если кто может))) Если кому интересно выложу фото подвеса. а если соберу доконца, то опишу в проектах. механика собрана на 80%. Прилагаю последний код на котором я встал. [CODE]
#include <Servo.h> Servo servo1;
int servopin1=10;
int potensiometr = A9;
int val;
void setup()
{
servo1.attach(servopin1);
}
void loop()
{
val = analogRead(potensiometr);
int pos = map(val,0,1023,0,200);
for(int i=1;i<=101;i=i+20)
{
if(pos<i)
{ servo1.write(80); }
else if(pos>i)
{ servo1.write(100); }
else
{ servo1.write(90); delay(1000);
} } }
Криво вставился код, не знаю как исправить(((( дублирую в правильном виде то, что у меня не получилось.
#include <Servo.h> Servo servo1; int servopin1=10; int potensiometr = A9; int val; void setup() { servo1.attach(servopin1); } void loop(){ val = analogRead(potensiometr); int pos = map(val,0,1023,0,200); for(int i=1;i<=101;i=i+20) { if(pos<i) { servo1.write(80); } else if(pos>i) { servo1.write(100); } else{ servo1.write(90); delay(1000); } } }Так как не известно какая конкретно зависимость направлений вращений потенциометра и сервы ,то попробуйте раскомментировать строку 21, закомментировав строку 22.
#include <Servo.h> #define servopin1 10 #define pot A9 Servo servo1; int poss[] = {23, 273, 523, 723, 1023}; // заданные положения void setup() { servo1.attach(servopin1); } void loop() { static byte i; int pos = analogRead(pot); if(pos < poss[i]-3 || pos > poss[i]+3) { //pos = map(pos, 0, poss[i], 0, 90); pos = map(pos, 0, poss[i], 180, 90); pos = consnrain(pos, 0, 180); servo1.write(pos); } else { delay(2000); i++; if(i == 5) i = 0; } delay(10); }Выше реалазовано всего лишь пропорциональное регулирование, а значит будет статическая ошибка.
Так как не известно какая конкретно зависимость направлений вращений потенциометра и сервы ,то попробуйте раскомментировать строку 21, закомментировав строку 22.
#include <Servo.h> #define servopin1 10 #define pot A9 Servo servo1; int poss[] = {23, 273, 523, 723, 1023}; // заданные положения void setup() { servo1.attach(servopin1); } void loop() { static byte i; int pos = analogRead(pot); if(pos < poss[i]-3 || pos > poss[i]+3) { //pos = map(pos, 0, poss[i], 0, 90); pos = map(pos, 0, poss[i], 180, 90); pos = consnrain(pos, 0, 180); servo1.write(pos); } else { delay(2000); i++; if(i == 5) i = 0; } delay(10); }Выше реалазовано всего лишь пропорциональное регулирование, а значит будет статическая ошибка.
Спасибо, пытаюсь разобраться в написаном.
А что делает эта строка строка, непойму?
consnrain это команда какая-то или переменная новая. Ардуино ругается именно на эту строку error: 'consnrain' was not declared in this scope
там опечатка
а что она делает написано тут Программирование в разделе Математические функции.
Попробовал, что-то идет не так. серва начинает либо бешено кружиться, либо если использовать 21 строку вместо 22 ,серва крутится и останавливается в одном положении и далее не двигается.
Это и есть статическая ошибка - тоесть до нужной позиции не дотягивает, пока просто снизте точность позиционирования
#include <Servo.h> #define servopin1 10 #define pot A9 Servo servo1; int poss[] = {23, 273, 523, 723, 1023}; // заданные положения void setup() { servo1.attach(servopin1); } void loop() { static byte i; int pos = analogRead(pot); if(pos < poss[i]-30 || pos > poss[i]+30) { pos = map(pos, 0, poss[i], 0, 90); //pos = map(pos, 0, poss[i], 180, 90); pos = consnrain(pos, 0, 180); servo1.write(pos); } else { delay(2000); i++; if(i == 5) i = 0; } delay(10); }если 30 мало, то сделайте побольше... аесли многовато, то поменьше...
Подскажите, голову удалось запустить т.е скетч дописать,поделиться им можете?
Головку запустил, даже сделал несколько панорам в автоматическом режиме.
Осталось просто доработать механику.
Код получился некрасивый, но иначе (по правилам с циклами переменными)ничерта не работал. Пришлось как всегда изобретать велосипед.
Но в итоге работает.
Так как катастрофически не хватает времени, проект забросил. и где код лежит уже не помню. Но он залит в Ардуино. Можно его оттуда какнить выудить?
А, не, наврал. Код нашел. В программировании не разбираюсь но логику понимаю, поэтому не все может быть понятно.
#define ANGLE_LIMIT 63 #define ANGLE_STEP 7 #include <Servo.h> #define STOP_SPEED 90 #define CW_SPEED (STOP_SPEED -9) #define CCW_SPEED (STOP_SPEED + 9) int pulscount=1; // Счетчик числа импульсов в пакете ИК int puls = 4; // Число пакетов ИК int wzat = 2000; // Время нажатия кнопки затвора - 3 с int wp = 3000; // Пауза перед спуском затвора - 4 с Servo servo; Servo servov; void setup(){ TCCR1A = _BV(COM1A1) | _BV(COM1B1) ; // phase and frequency correct mode. NON-inverted mode TCCR1B = _BV(WGM13) | _BV(CS10); // Делитель N = 1 - (_BV(CS10)); 8 - (_BV(CS11)) OCR1B = 0; // Скважность 102 - рабочий сигнал, 0 - сигнал отсутствует ICR1 = 210; // Частота 16мГц/2*N*ICR1 = 16000кГц/(2*1*210)=38095Гц pinMode(12, OUTPUT); // К 12 (на mega) ножке подключен ИК светодиод АЛ107 через сопротивление 1 кОм servo.attach(10); servo.write(90); servov.attach(9); servov.write(90); } void loop() { for (int targetAngle = 0; targetAngle < ANGLE_LIMIT; targetAngle += ANGLE_STEP) { servo.write(CW_SPEED); // запускаем движение вперёд while (map(analogRead(A10), 0, 1023, 0, 207) < targetAngle) ; // ждём пока докрутимся до нужного угла servo.write(STOP_SPEED); // стоп машина! delay(50); // ждём полной остановки IR_Sony(); // Нажимаем спусковую кнопку } servo.write(CCW_SPEED); // запускаем движение назад while (map(analogRead(A10), 0, 1023, 0, 207) > 0); // ждём пока докрутимся до старта servo.write(STOP_SPEED); delay(50); step_vert1(); for (int targetAngle = 0; targetAngle < ANGLE_LIMIT; targetAngle += ANGLE_STEP) { servo.write(CW_SPEED); // запускаем движение вперёд while (map(analogRead(A10), 0, 1023, 0, 207) < targetAngle) ; // ждём пока докрутимся до нужного угла servo.write(STOP_SPEED); // стоп машина! delay(50); // ждём полной остановки IR_Sony(); // Нажимаем спусковую кнопку } servo.write(CCW_SPEED); // запускаем движение назад while (map(analogRead(A10), 0, 1023, 0, 207) > 0); // ждём пока докрутимся до старта servo.write(STOP_SPEED); delay(50); step_vert2(); for (int targetAngle = 0; targetAngle < ANGLE_LIMIT; targetAngle += ANGLE_STEP) { servo.write(CW_SPEED); // запускаем движение вперёд while (map(analogRead(A10), 0, 1023, 0, 207) < targetAngle) ; // ждём пока докрутимся до нужного угла servo.write(STOP_SPEED); // стоп машина! delay(50); // ждём полной остановки IR_Sony(); // Нажимаем спусковую кнопку } servo.write(CCW_SPEED); // запускаем движение назад while (map(analogRead(A10), 0, 1023, 0, 207) > 0); // ждём пока докрутимся до старта servo.write(STOP_SPEED); delay(50); step_vert3(); IR_Sony(); startvert(); } void IR_Sony() { //Подпрограмма подачи ИК сигналя для спуска зотвора камеры NEX5 digitalWrite(13, HIGH);//Индикация паузы светодиодом на плате delay(wp);// Пауза перед спуском затвора digitalWrite(13, LOW); pulscount=1; while (pulscount<puls) // цикл пакета импульсов {OCR1B = 102; // включаем светодиод delayMicroseconds(2432); // светодиод горит микросекунд OCR1B = 0; // выключаем светодиод delayMicroseconds(576); // светодиод выключен микросекунд OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(640); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(576); OCR1B = 102; // включаем светодиод delayMicroseconds(1216); OCR1B = 0; delayMicroseconds(11136); pulscount++; } digitalWrite(13, HIGH); delay(wzat); // Время нажатия кнопки затвора digitalWrite(13, LOW); } void step_vert1() { servov.write(100); while (map(analogRead(A11), 0, 1023, 0, 100) < 9); servov.write(90); delay(500); } void step_vert2() { servov.write(100); while (map(analogRead(A11), 0, 1023, 0, 100) < 18); servov.write(90); delay(500); } void step_vert3() { servov.write(100); while (map(analogRead(A11), 0, 1023, 0, 100) < 27); servov.write(90); delay(500); } void startvert() {servov.write(80); while (map(analogRead(A11), 0, 1023, 0, 100) > 0); servov.write(90); delay(500); }Благодарю!