Управление поворота видеокамеры, или нечто подобным

Тема в разделе "Глядите, что я сделал", создана пользователем grx1a, 3 фев 2013.

  1. grx1a

    grx1a Гик

    Здравствуйте создал два проекта предназначенный для управления сервоприводами, проекты законченные и проверенные, хочу поделиться, может кому понадобятся
    Первый проект для управления одним сервоприводом по средствам двух кнопок, при нажатии обеих одновременно происходит центровка (сервопривод устанавливается в заданное положение центра)
    Второй проект управление двумя сервоприводами по средствам пяти кнопок (вверх, вниз, вправо, влево, быстрая центровка на заданный угол)
    Оба проекта имеют возможность быстрой и удобной настройки необходимых параметров,
    Таких как: минимальные и максимальные углы поворота (рабочий сектор, (0-180 град))
    Угол заданной быстрой центровки,( угол в который встанут сервоприводы при выполнении функции быстрой центровки (0-180 град))
    Единичный шаг сервопривода (в градусах)
    Скорость поворота сервопривода.
    Данный проект можно использовать для управления видеокамерой по одной или двум осям вращения, или сделать управляемую турель, мли управление роботом, ну или что то нечто подобное.
    Вообще данный проект лучше всего выполнять на энкодерах, тогда можно будет регулировать не только углы поворота, но скорость поворота по средствам руки (пальцев), когда-нибудь напишу проект и для них, надо две убитых мышки найти с целыми энкодерами.
    Проекты написаны и проверены на ARDUINOMEGA 2560

    /*схема подключения кнопок: через резисторы 10 кОм одной лапой посаженые на общий минус питания
    вторая лапа резистора соединена с одной лапой кнопки а так же с цифровыми PIN входного сигнала на Arduino?
    вторая лапа кнопки соединена с общим плюсовым проводом питания
    Кнопка нормально разомкнутого типа
    Сервомоторы : провода питания подключены на выводы питания к Arduino, сигнальные проводы подключены
    к цифровым выводам PWM (ШИМ) на Arduino

    */
     

    Вложения:

    • Servo 1.txt
      Размер файла:
      2,8 КБ
      Просмотров:
      1.168
    • Servo 2.txt
      Размер файла:
      5,3 КБ
      Просмотров:
      802
    nailxx нравится это.
  2. Danilovdom

    Danilovdom Нуб

    Неплохо!
    А есть действующее использование проекта?
    Например видео, как вы это используете?
     
  3. grx1a

    grx1a Гик

    Данную часть программы собираюсь использовать для мини джойстика встроеного в 3D джойстик, но пока заказаное мною железо по почте еще не пришло, когда придет соберу все вместе и обязательно размещу результаты на сайте
     
  4. grx1a

    grx1a Гик

    пока что конструкция в виде экпериментального образца, невзрачная и не красивая
     
  5. grx1a

    grx1a Гик

    Сегодня нашел магази где еще можно купить шариковые мыши, которых в продаже уже сто лет нет.
    Шариковые мыши мне нужны для того что бы с них снять шарик и оптические энкодеры, на основе этого добра сделаю манипулятор подобный вышеописаному но уже более продвинутый, чувствительность к поворотам будет выше, плюс добавится возможность регулировки скорости поворота аппаратным способом вместо програмного. Или говоря простым языком сделаю манипулятор Track boll Как что получится расскажу. Думаю, наверное для того манипулятора схему лучше собирать не на сервоприводах а на шаговых движках, так наверное целесообразней получится
     
  6. grx1a

    grx1a Гик

    Написал два кода управления сервоприводами при помощи энкодеров, оба кода имеют функцию кнопки быстрой центровки в заданное положение
    1. Первый код: один энкодер управляет одной сервой
    2. Второй код: два энкодера управляют двумя сервами
    Теперь можно делать механическую часть Trackbola
    а так же попробую еще сделать код что бы по одной оси работал шаговый двигатель, например для всеракурсного вращения видеокамерой в горизонтальной плоскости 360+ градусов, а в вертикальной оси работала только серва 0-180 градусов
     
  7. grx1a

    grx1a Гик

    /*
    Программа для управления двумя сервомоторами по средствам двух механических энкодеров
    */
    #define pinA 3 //PIN А Сигнала с первого энкодера
    #define pinB 4 //PIN В Сигнала с первого энкодера
    #define pinC 5 //PIN С Сигнала с второго энкодера
    #define pinD 6 //PIN D Сигнала с второго энкодера
    #define pinCenter 10 //PIN кнопки быстрой центровки
    #include <Servo.h>
    Servo SerX; //Название первой сервомашины "SerX"
    int servoPinX = 8; //Сервомотор "SerX" подключен на PIN 8
    Servo SerZ; //Название второй сервомашины "SerZ"
    int servoPinZ = 9; //Сервомотор "SerZ" подключен на PIN 9
    long time; //Переменная таймера задержки в функции стабилизации импульса

    //X AXIS
    int initialAngleX = 90; //Угол центрального положения по оси Х "Быстрая центровка"(сервомотор принимает этот угол при нажатии кнопки быстрой центровки)
    int angleX = 90; //Текущий угол поворота оси Х (при запуске программы будет автоматический вставать в указаное положение)
    int maxAngleX = 180; //Максимальный угол поворота сервомотора по оси Х (градусов)
    int minAngleX = 0; //Минимальный угол поворота сервомотора по оси Х(градусов)
    int angleStepX = 5; //Угол единичного шага по оси Х(градусов)
    int stepSpeedX =1; //Скорость шага (Время задержки шага)по оси Х
    boolean valA=0; //Текущее переменное значение енкодера на А ыходе первого энкодера
    boolean valB=0; //Текущее переменное значение енкодера на В ыходе первого энкодера
    boolean EstateX=0; //Вспомогательная переменная необходимая для определения вращения энкодера по оси Х
    boolean pulseX = 0; //Импульс шага в любом направлении по оси Х не стабилизированый
    boolean DirX =0; //Переменная направления вращения энкодера по оси Х (Если=1 то влево, если=0 то вправо)
    boolean zapretX=LOW; //Вспомогательная переменная необходимая для стабилизации импульса шага по оси Х
    boolean outsigX=LOW; //Импульс шага в любом направлении, стабилизированный по оси Х

    //Z AXIS
    int initialAngleZ = 90; //Угол центрального положения по оси Z "Быстрая центровка"(сервомотор принимает этот угол при нажатии кнопки быстрой центровки)
    int angleZ = 90; //Текущий угол поворота по оси Z (при запуске программы будет автоматический вставать в указаное положение)
    int maxAngleZ = 180; //Максимальный угол поворота сервомотора по оси Z(градусов)
    int minAngleZ = 0; //Минимальный угол поворота сервомотора по оси Z(градусов)
    int angleStepZ = 5; //Угол единичного шага по оси Z (градусов)
    int stepSpeedZ = 1; //Скорость шага (Время задержки шага)по оси Z
    boolean valC=0; //Текущее переменное значение енкодера на С ыходе второго энкодера
    boolean valD=0; //Текущее переменное значение енкодера на D ыходе второго энкодера
    boolean valCenter=LOW; //Переменная быстрой центровки
    boolean EstateZ=0; //Вспомогательная переменная необходимая для определения вращения энкодера по оси Z
    boolean pulseZ = 0; //Импульс шага в любом направлении по оси Z не стабилизированый
    boolean DirZ =0; //Переменная направления вращения по оси Z (Если=1 то влево, если=0 то вправо)
    boolean zapretZ=LOW; //Вспомогательная переменная необходимая для стабилизации импульса шага по оси Z
    boolean outsigZ=LOW; //Импульс шага в любом направлении, стабилизированный по оси Z


    void setup(){
    SerX.attach(servoPinX);
    SerZ.attach(servoPinZ);
    pinMode(pinA,INPUT); //Цифровой вход A c первого энкодера
    pinMode(pinB,INPUT); //Цифровой вход B c первого энкодера
    pinMode(pinC,INPUT); //Цифровой вход C c второго энкодера
    pinMode(pinD,INPUT); //Цифровой вход D c второго энкодера
    pinMode(pinCenter,INPUT);} //Цифровой вход кнопки быстрой центровки
    void loop(){
    valA=digitalRead(pinA); //Читает и запоминает текущее состояние на выходе первого энкодера (Выход А)
    valB=digitalRead(pinB); //Читает и запоминает текущее состояние на выходе первого энкодера (Выход B)
    valC=digitalRead(pinC); //Читает и запоминает текущее состояние на выходе второго энкодера (Выход C)
    valD=digitalRead(pinD); //Читает и запоминает текущее состояние на выходе второго энкодера (Выход D)
    valCenter=digitalRead(pinCenter);
    //БЫСТРАЯ ЦЕНТРОВКА
    if(valCenter==HIGH) //Условие быстрой центровки Если кнопк быстрой центровки нажата
    {angleX=initialAngleX; //сервомотор по оси Х устанавливается в центральное положениз заданное значением initAngleХ
    angleZ=initialAngleZ;} //сервомотор по оси Z устанавливается в центральное положениз заданное значением initAngleZ

    //РАСПОЗНАНИЕ ШАГА
    if(valA+valB==HIGH){pulseX=1;} //Определяет шаг и дает не стабилизированый импульс шага по оси Х
    else{pulseX=0;}
    if(valC+valD==HIGH){pulseZ=1;} //Определяет шаг и дает не стабилизированый импульс шага по оси Z
    else{pulseZ=0;}
    //СТАБИЛИЗАТОР ИМПУЛЬСА ШАГА
    if((pulseX==HIGH)&&(zapretX==LOW)){ //Условие работы стабилизатора выходного импульса
    time = millis(); //Запуск таймера
    outsigX = HIGH;} //Стабилизированый выходной импульс шага
    zapretX=HIGH;
    if(outsigX && (millis() - time) > 1) //(2)-Временная длинна выходного импульса
    {outsigX = LOW;} //Остановка таймера
    if(pulseX==LOW){
    zapretX=LOW;
    }
    if((pulseZ==HIGH)&&(zapretZ==LOW)){
    time = millis();
    outsigZ = HIGH;}
    zapretZ=HIGH;
    if(outsigZ && (millis() - time) > 1)
    {outsigZ = LOW;}
    if(pulseZ==LOW){
    zapretZ=LOW;
    }

    //ОПРЕДЕЛЕНИЕ ВСПОМОГАТЕЛЬНОЙ ПЕРЕМЕННОЙ
    //ДЛЯ ОПРЕДЕЛЕНИЯ НАПРАВЛЕНИЯ ВРАЩЕНИЯ
    if((valA==LOW)&&(valB==LOW)
    &&(valA<1)&&(valB<1))
    {EstateX=1;} //Вспомогательная переменная для определения направления вращения энкодера на (+) по оси X
    if((valA==HIGH)&&(valB==HIGH)
    &&(valA>0)&&(valB>0))
    {EstateX=0;} //Вспомогательная переменная для определения направления вращения энкодера на (-) по оси X
    if((valC==LOW)&&(valD==LOW)
    &&(valC<1)&&(valD<1))
    {EstateZ=1;} //Вспомогательная переменная для определения направления вращения колеса на (+) по оси Z
    if((valC==HIGH)&&(valD==HIGH)
    &&(valC>0)&&(valD>0))
    {EstateZ=0;} //Вспомогательная переменная для определения направления вращения колеса на (-) по оси Z

    //ОПРЕДЕЛЕНИЕ НАПРАВЛЕНИЯ ВРАЩЕНИЯ
    if(((EstateX==1)&&(valA==LOW)&&(valB==HIGH))|| //Условия направления вращения(+) по оси X
    ((EstateX==0)&&(valA==HIGH)&&(valB==LOW)))
    {DirX=1;} //Направление вращения (+) по оси X
    if(((EstateX==1)&&(valA==HIGH)&&(valB==LOW))|| //Условия направления вращения(-) по оси X
    ((EstateX==0)&&(valA==LOW)&&(valB==HIGH)))
    {DirX=0;} //Направление вращения(-) по оси X
    if(((EstateZ==1)&&(valC==LOW)&&(valD==HIGH))|| //Условия направления вращения(+) по оси Z
    ((EstateZ==0)&&(valC==HIGH)&&(valD==LOW)))
    {DirZ=1;} //Направление вращения (+)по оси Z
    if(((EstateZ==1)&&(valC==HIGH)&&(valD==LOW))|| //Условия направления вращения(-)по оси Z
    ((EstateZ==0)&&(valC==LOW)&&(valD==HIGH)))
    {DirZ=0;} //Направление вращения(-) по оси Z
    //ВЫХОДНОЙ СИГНАЛ
    if((DirX==1)&&(outsigX==HIGH)) //Условие поворота в одну из строн
    {angleX=angleX+angleStepX; //тогда угол поворота сервомотора меняется по шагово на величину шага
    if (angleX>maxAngleX)
    {angleX=maxAngleX;}} //Ограничитель угла поворота по оси Х
    if((DirX==0)&&(outsigX==HIGH)) //Все тоже самое как для предидущей функции но с !инверсией
    {angleX=angleX-angleStepX;
    if (angleX<minAngleX)
    {angleX=minAngleX;}}
    if((DirZ==1)&&(outsigZ==HIGH))
    {angleZ=angleZ+angleStepZ;
    if (angleZ>maxAngleZ)
    {angleZ=maxAngleZ;}}
    if((DirZ==0)&&(outsigZ==HIGH))
    {angleZ=angleZ-angleStepZ;
    if (angleZ<minAngleZ)
    {angleZ=minAngleZ;}}
    {SerX.write(angleX);
    delay(stepSpeedX);} //Задержка шага по оси X
    {SerZ.write(angleZ);
    delay(stepSpeedZ);} //Задержка шага по оси Z
    }
     
    sanik нравится это.
  8. grx1a

    grx1a Гик

    /*
    Программа для управления одним сервомотором по средствам одного механического энкодера
    */
    #define pinA 3 //Первый PIN Сигнала с энкодера
    #define pinB 4 //Второй PIN Сигнала с энкодера
    #define pinC 10 //PIN кнопки быстрой центровки
    #include <Servo.h>
    Servo Rul; //Название сервомашины "Руль"
    int servoPin = 8; //Сервомотор подключен на PIN 8
    int initialAngle = 90; //Угол центрального положения "Быстрая центровка"
    int angle = 90; //Текущий угол поворота (при запуске программы будет автоматический вставать в указаное положение)
    int maxAngle = 180; //Максимальный угол поворота сервомотора (градусов)
    int minAngle = 0; //Минимальный угол поворота сервомотора (градусов)
    int angleStep = 5; //Угол единичного шага (градусов)
    int stepSpeed = 10; //Скорость шага (Время задержки шага)

    boolean valA=0; //Текущее переменное значение енкодера на выходе энкодера А
    boolean valB=0; //Текущее переменное значение енкодера на выходе энкодера В
    boolean valC=0; //Переменная функции быстрой центровки
    boolean Estate=0; //Вспомогательная переменная необходимая для определения направления вращения
    boolean pulse = 0; //Импульс шага в любом направлении, не стабилизированный
    boolean Dir =0; //Переменная направления вращения (Если=1 то влево, если=0 то вправо)
    boolean zapret=LOW; //Вспомогательная переменная необходимая для стабилизации импульса шага
    boolean outsig=LOW; //Импульс шага в любом направлении, стабилизированный
    long time; //Переменная таймера задержки в функции стабилизации
    void setup(){
    Rul.attach(servoPin);
    pinMode(pinC,INPUT); //Цифровой вход С кнопки быстрой центровки
    pinMode(pinA,INPUT); //Цифровой вход A c энкодера
    pinMode(pinB,INPUT); } //Цифровой вход В c энкодера
    void loop(){
    valA=digitalRead(pinA); //Читает и запоминает текущее состояние на выходе энкодера (Выход А)
    valB=digitalRead(pinB); //Читает и запоминает текущее состояние на выходе энкодера (Выход В)
    valC=digitalRead(pinC); //Читает и запоминает текущее состояние кнопки быстрой центровки
    //БЫСТРАЯ ЦЕНТРОВКА
    if(valC==HIGH){ //Условие быстрой центровки (Если кнопк быстрой центровки нажата)
    angle=initialAngle;} //сервомотор устанавливается в центральное положениз заданное значением initAngle
    //РАСПОЗНАНИЕ ШАГА
    if(valA+valB==HIGH){pulse=1;} //Определяет шаг и дает не сабилизированный импульс шага
    else{pulse=0;}
    //СТАБИЛИЗАТОР ИМПУЛЬСА ШАГА
    if((pulse==HIGH)&&(zapret==LOW)){ //Условие работы стабилизатора выходного импульса
    time = millis(); //Запуск таймера
    outsig = HIGH;} //Стабилизированый выходной импульс шага
    zapret=HIGH;
    if(outsig && (millis() - time) > 1) //(2)-Временная длинна выходного импульса
    {outsig = LOW;} //Остановка таймера
    if(pulse==LOW){
    zapret=LOW;
    } //Антидребезг

    //ОПРЕДЕЛЕНИЕ ВСПОМОГАТЕЛЬНОЙ ПЕРЕМЕННОЙ
    //ДЛЯ ОПРЕДЕЛЕНИЯ НАПРАВЛЕНИЯ ВРАЩЕНИЯ
    if((valA==LOW)&&(valB==LOW)
    &&(valA<1)&&(valB<1))
    {Estate=1;} //Вспомогательная переменная для определения направления вращения энкодера на (+)
    if((valA==HIGH)&&(valB==HIGH)
    &&(valA>0)&&(valB>0))
    {Estate=0;} //Вспомогательная переменная для определения направления вращения энкодера на (-)

    //ОПРЕДЕЛЕНИЕ НАПРАВЛЕНИЯ ВРАЩЕНИЯ
    if(((Estate==1)&&(valA==LOW)&&(valB==HIGH))|| //Условия направления вращения(+)
    ((Estate==0)&&(valA==HIGH)&&(valB==LOW)))
    {Dir=1;} //Направление вращения (+)
    if(((Estate==1)&&(valA==HIGH)&&(valB==LOW))|| //Условия направления вращения(-)
    ((Estate==0)&&(valA==LOW)&&(valB==HIGH)))
    {Dir=0;} //Направление вращения(-)
    //ВЫХОДНОЙ СИГНАЛ
    if((Dir==1)&&(outsig==HIGH)) //Условие поворота в одну из строн (Направление + стабилизированый сигнал шага)
    {angle=angle+angleStep; //угол поворота сервомотора меняется по шагово на заданную величину шага
    if (angle>maxAngle)
    {angle=maxAngle;}} //Ограничитель угла поворота исполнительного устройства (Рабочий диапозон)
    if((Dir==0)&&(outsig==HIGH)) //Все тоже самое как для предидущей функции но с !инверсией
    {angle=angle-angleStep; //угол поворота сервомотора меняется по шагово на заданную величину шага
    if (angle<minAngle)
    {angle=minAngle;}} //Ограничитель угла поворота исполнительного устройства (Рабочий диапозон)

    {Rul.write(angle); //Входной сигнал на сервомотор
    delay(stepSpeed);} //Скорость шага (время задержки шага)
    }
     
  9. sanik

    sanik Гик

    Вот отлично подготовленный материал для новичка!
     
  10. grx1a

    grx1a Гик

    Меня просто прет от этих дел, я сейчас на параходе, возможности интернета ограничены, вернусь в июле продолжу дальше программы писать
     
  11. Megakoteyka

    Megakoteyka Оракул Модератор

    Осталось только код отформатировать и сунуть под соответствующий тэг, а то читать невозможно.
     
  12. grx1a

    grx1a Гик

    ))) Да парой сам ужасаюсь от такого количества символов, думаю с опытом будет получатся компактней
     
  13. Megakoteyka

    Megakoteyka Оракул Модератор

    Дело не в количестве символов или компактности, а в невозможности такой код нормально прочесть. Не видно структуры кода. Правильно оформленный код читается, понимается и отлаживается на порядок проще. Используйте тэг CODE, он подсветит синтаксис.
    Стандарт оформления кода
    Правильное оформление исходного кода
     
    9xA59kK и grx1a нравится это.
  14. grx1a

    grx1a Гик

    спасибо!!!
     
  15. grx1a

    grx1a Гик

    кажется я понял о чем идет речь, ну.......опыта в програмировании пока только два месяца, да и образование никакого отношения к програмированию не имеет. Буду над этим вопросом работать, спасибо за направление на правильный путь. В дальнейшем постораюсь коды писать читаемые
     
  16. grx1a

    grx1a Гик

    а что такое тэг?
     
  17. Megakoteyka

    Megakoteyka Оракул Модератор

  18. grx1a

    grx1a Гик

    Все понял, спасибо, а то думал как это код цветным сделать как в програматоре ардуинки
     
  19. grx1a

    grx1a Гик

    Есть проблема, подскажите пожалуста, собрал Pan tilt устройство на двух сервах, манипулятор - джойстик на двух потенциометрах через аналоговые входы, через функцию map, все работает нормально но есть одно но, одна серва работает нормально в состоянии покоя стоит как вкопаная (когда не воздействую на манипулятор)
    вторая серва либо стоит нормально в состоянии покоя либо тресется в пределах +/- два три градуса в секунду, в видеоуроках Джереми Блума есть упоминание на этот счет, он называет это проблема связаная с фильтром и обещает обяснить функцию фильтра в следующих уроках, но обьяснения нет, скажите пожалуйста что за фильтр и как его сделать, я так понимаю проблема в железе!
     
  20. grx1a

    grx1a Гик

    или может одна серва бракованая, вторая то вроде нормально работает,