цикличная работа сервопривода

Тема в разделе "Arduino & Shields", создана пользователем piter pen, 16 ноя 2017.

  1. piter pen

    piter pen Нерд

    Здравствуйте. Стоит задача управлять сервоприводами джойстиком. Т.е. если отклонить джойстик в одной оси сервы будут вращаться туда/обратно в определенном угловом диапазоне. Если джойстик отпускаем - сервы останавливаются в определенном положении (т.е. в том положении, в котором они были в момент отпускания джойстика). Для упрощения понимания кодировки собрал схему с одной сервой (0/180град) и джойстиком. Есть код вращения сервы в определенном угловом диапазоне
    Код (C++):
    #include <Servo.h>


    Servo servo1;

    void setup()
    {

    servo1.attach(9);
    }

    void loop()
    {
    int position;

    for(position = 30; position < 150; position += 5)
    {
    servo1.write(position);  // Перемещаемся на следующую позицию
    delay(30);               // Короткая пауза
    }

    for(position = 150; position >= 30; position -= 5)
    {
    servo1.write(position);  // Переместиться на следующую позицию
    delay(30);               // Короткая пауза
    }
    }
    Есть код управления сервой посредством джойстика
    Код (C++):
    #include <Servo.h> // подключение библиотеки Servo
    Servo servo1;
    const int pinServo1=9; // Пин для подключения 1 сервопривода
    // переменные для хранения углов поворота сервоприводов
    int angleServo1 = 0;
    const int axisX = A0; // ось Х подключена к A0

    int valX = 0; // переменные для хранения значений осей
    void setup()
    {
    // подключить переменную servo1 к выводу pinServo1
    servo1.attach(pinServo1);

    }
    void loop()
    {
    valX = analogRead(axisX); // значение оси Х

    // масштабируем значение к интервалу 0-180
    angleServo1=map(valX,0,1023,0,180);

    // поворот сервоприводов на полученный угол
    servo1.write(angleServo1);

    delay(15); // пауза для ожидания поворота сервоприводов
    }
    Но вот собрать их в один никак у меня не получается... при компиляции постоянно вылетают ошибки...
    Подскажите, как их собрать правильно?
    и еще вопрос - почему во втором скетче серва при включении встает в положение 90 градусов?
     
  2. ostrov

    ostrov Гуру

    Какие ошибки вылетают?
     
  3. rkit

    rkit Гуру

    А вы учебник программирования читать пробовали, перед тем как программировать? Или как всегда?
     
  4. piter pen

    piter pen Нерд

    конечно не "как всегда". читал... и сейчас читаю... но не складывается у меня в голове этот пазл и все тут... по отдельности получается (не все конечно и уж тем более не сразу)... и кнопки в свое время отработал... и диоды...

    по ошибкам сейчас не скажу... в основном на домашнем компьютере все... да и не задумывался их записывать (хотя по опыту знаю что надо было...)
     
  5. piter pen

    piter pen Нерд

    набросал скетч. Но получилось не то что хотел. Во-первых ушел от джойстика, управление переложил на телефон по блютуз.
    Непонятны следующие вещи:
    1. Видимо оператор for() не подходит для моей задачи. Если не for() то как реализовать то что мне нужно?
    2. Пока не пойму как реализовать начало вращения сервы с текущего положения. Использовал servo.read(). Но что то не пошло. Т.е. вводил переменную А и подставлял ее в { for (position = А...
    3. Сейчас смог реализовать отработку команды только по одному нажатию кнопки (применительно для void FORWARD()). Т.е. задачу с работой сервы пока удерживается кнопка пока не решил.
    Подскажите/ подтолкните в верном направлении уважаемые знающие. Заранее премного благодарен.
    P.S.: Если подскажите по первому вопросу - может и с остальными решиться своими силами
    Код (C++):
    #include <SoftwareSerial.h>
    #include <Servo.h>
    #include <String.h>
    SoftwareSerial BT(11, 10); //TX, RX respetively
    String voice;
    int i;


    int position;

    Servo servo1;

    void setup()

    {

      servo1.attach(2);

      BT.begin(9600);
      Serial.begin(9600);

    }

    void INITIAL()
    {
      servo1.write(90);

    }
    void FORWARD()

    { for (position = 50; position < 130; position += 10)

      {
        servo1.write(position);
        delay(250);
      }

      for (position = 130; position >= 50; position -= 10)
      {
        servo1.write(position);
        delay(250);            
      }
    }

    void loop()
    {
      if (BT.available())

        voice = (char)BT.read();

      {
        Serial.println(voice);
        if (voice == "initial")
        {
          INITIAL();
        }
        else if (voice == "forward")

        {
          for (int i = 0; i <= 2; i++)

            FORWARD();

        }

        else if (voice == "2")
        {
          FORWARD();
          FORWARD();
        }

        delay(20);

      }

    }
     
  6. ORLENOK

    ORLENOK Гик

    Знаю циклы - буду использовать везде - Ваш случай. Без обид, но судя по коду это так)
    Чтобы написать код Вам нужно представить, что должно происходить...
    1) Вы пишите, нажимаю на кнопку - серво двигается, не нажимаете - не двигается. Причем тут циклы? Тут нету фраз, серво двигается в течении 10 секунд. Или хоть что-то, что говорило бы о цикличности.
    2) У серво бывают проблемы, что начинают дергаться заходя в крайние положения или вообще, когда передаем невалидные данные. Типо текущий угол -1 или 190. Чтобы понимать какой сейчас угол - нужна переменная, которая отвечает за текущий угол. Т.к. начальное значение угла мы знаем, то и значение переменной тоже.
    3) В loop() обрабатываем:
    if(Нажали 1)
    if(текущий угол больше 0)
    {
    уменьшили текущий угол;
    передали значение текущего угла на серво;
    }
    if(Нажали 2)
    if(текущий угол меньше 180)
    {
    увеличили текущий угол;
    передали значение текущего угла на серво;
    }
    4) Мало просто взять какой-то код, важно понимать что он делает. Ваш FORWARD тоже самое, что и первый пример в первом сообщение. Значит каждый раз, когда запускается этот метод будут происходить тоже самое(качание серво из стороны в сторону АВТОМАТИЧЕСКОЕ). Не по нажатию на какие-то кнопки, а просто потому что так запрограммировано. Вам это не нужно.
     
    piter pen нравится это.
  7. ostrov

    ostrov Гуру

    А общем, как всегда, пишите в Закажу проект.
     
  8. piter pen

    piter pen Нерд

    спасибо за разъяснение. теперь появилась ясность в голове )))
     
  9. piter pen

    piter pen Нерд

    неее... это не наш метод))) если так рассуждать - то проще купить готовый проект полностью а не только код... тут не будет ни интереса, ни удовольствия от процесса. просто некоторые вещи мне даются не просто... поэтому и обращаюсь за помощью к знающим
     
  10. piter pen

    piter pen Нерд

    доброго времени всем. я пытался написать скетч как советовал ORLENOK. но что то не пошло так как рассчитывал... либо я условие неправильно прописал либо с переменными что то не так... Подскажите пожалуста
    Код (C++):
    #include <Servo.h>
    int button = 4; //button pin, connect to ground to move servo
    int press = 0;
    Servo servo;

    int val = 0;

    void setup()
    {
      pinMode(button, OUTPUT); //arduino monitor pin state
      servo.attach(5); //pin for servo control signal
    }
    void loop()
    {
      press = digitalRead(button);
      val = analogRead(5);
      if (press == HIGH && val > 0)
      {
        servo.write(val+1);
    }
    else
    {
      servo.write(val-1);
    }
    }
     
  11. piter pen

    piter pen Нерд

    ах да. забыл совсем. это стандартный пример управления сервой через кнопку.
     
  12. piter pen

    piter pen Нерд

    объясните пожалуйста, почему в данном скетче при добавлении одной сервы скорость их вращения падает? и почему нельзя менять диапазон вращения (if ((pos >= 180) || (pos <= 0)) // конец вращения)?
    Код (C++):
    #include <Servo.h>
    class Sweeper
    {
      Servo servo; // сервопривод
      int pos; // текущее положение сервы
      int increment; // увеличиваем перемещение на каждом шаге
      int updateInterval; // промежуток времени между обновлениями
      unsigned long lastUpdate; // последнее обновление положения
       public:
      Sweeper(int interval)
      {
        updateInterval = interval;
        increment = 1;
      }
      void Attach(int pin)
      {
        servo.attach(pin);
      }
      void Detach()
      {
        servo.detach();
      }
      void Update()
      {
        if((millis() - lastUpdate) > updateInterval) // время обновлять
        {
          lastUpdate = millis();
          pos += increment;
          servo.write(pos);
          Serial.println(pos);
          if ((pos >= 180) || (pos <= 0)) // конец вращения
          {
            // обратное направление
            increment = -increment;
          }
       }
    }
    };
     
    Sweeper sweeper1(0);

    void setup()
    {
      Serial.begin(9600);
      sweeper1.Attach(8);

    }
    void loop()
    {
      if (digitalRead(2) == HIGH)
      {
        sweeper1.Update();

      }
    }
     
  13. ORLENOK

    ORLENOK Гик

    По первому вопросы не подскажу. По второму - меняйте. В чем проблема?
     
  14. piter pen

    piter pen Нерд

    дык в том то и проблема что скетч отказывается работать после смены углов... и не важно на сколько изменены углы... я хотел поставить 179/1 что бы почище серва вращалась...
     
  15. piter pen

    piter pen Нерд

    и еще не совсем понятна эта строка:
    Sweeper sweeper1(0);
    за что она отвечает? т.е. цифра в скобках?
     
  16. ORLENOK

    ORLENOK Гик

    В чем это выражается?
    Код (C++):
      Sweeper(int interval)
      {
        updateInterval = interval;
        increment = 1;
      }
    Соответственно updateInterval смотрите за что отвечает.
     
  17. piter pen

    piter pen Нерд

    по нажатию кнопки серва встает в крайнее положение и все... больше никак не раегирует. причем крайнее положение никак не зависит от указанного диапазона в условии
     
  18. piter pen

    piter pen Нерд

    кстати. первый вопрос решился увеличением increment =1
     
  19. akl

    akl Гуру

    может надо попробовать туда какое-нибудь нормальное число поставить? (100 например), а то получается что угол меняется каждую миллисекунду, возможно серва просто не понимает сигнал который в нее идет
     
    piter pen нравится это.
  20. ORLENOK

    ORLENOK Гик

    Увеличивая это число вы увеличиваете частоту вращения, если так можно сказать. А вот если изменить цифры в 180 и 0, то будет изменяться угол вращения.