Код для сервопривода.

Тема в разделе "Arduino & Shields", создана пользователем karagad, 25 окт 2013.

  1. karagad

    karagad Нерд

    Нужно управлять сервой от переменного резистора, помогите с кодом пожалуйста.
     
  2. Megakoteyka

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

    Подключите переменный резистор ко входу АЦП.
    Подключите сервопривод к выходу с ШИМ.
    Прочитайте значение с АЦП.
    Приведите значение к интервалу [0: 255].
    Установите полученное значение на выходе ШИМ.

    Если на входе АЦП значение будет меняться в пределах [0..1023],
    достаточно будет написать analogWrite(SERVO_PIN, analogRead(POT_PIN) / 4);
     
    karagad нравится это.
  3. karagad

    karagad Нерд

    большое спасибо
     
  4. karagad

    karagad Нерд

    Решил управлять сервой с помощью ультразвукового дальномера. Возникли проблемы с кодом . Дальномер посылает данные единым потоком. Вот код
    Код (Text):
    #include <Servo.h>
    int inputPin=4; // Echo
    int outputPin=5; // Trig
    int ledpin=13;

    Servo myservo;
    void setup()
    {
      Serial.begin(9600);
      pinMode(ledpin,OUTPUT);
    pinMode(inputPin, INPUT);
    pinMode(outputPin, OUTPUT);


      myservo.attach(9);
    }
    void loop()
    {
      digitalWrite(outputPin, LOW);
    delayMicroseconds(2);
    digitalWrite(outputPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(outputPin, LOW);
    int distance = pulseIn(inputPin, HIGH);
    distance= distance/58;
    Serial.print(distance);
    delay(1000);
    myservo.write(  analogRead(distance)  );
      delay(100);

    }


     
     
  5. Megakoteyka

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

  6. karagad

    karagad Нерд

    А как сделать чтобы ардуина запоминала последние значение в пределах рабочей зоны и серва удерживала его?
     
  7. Megakoteyka

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

    Объясните подробней, чего добиться хотите.
     
  8. karagad

    karagad Нерд

    как только в пределах рабочей зоны (4-22 см) появляется объект, серва принимает соответствующее, положение, и удерживает это положение до появление другого объекта в указанной зоне.
     
  9. Megakoteyka

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

    А как дальномер будет определять, что в зоне его действия появился еще один объект? Дальномеру без разницы, он определяет расстояние до ближайшего.
    Или Вы хотите, чтобы серва реагировала только на приближение объекта, а на удаление не реагировала? Приблизился один раз - серва повернулась. Отдалился - серве пофиг. приблизился еще раз - серва повернулась обратно. Так, что ли?
     
  10. karagad

    karagad Нерд

    В моем проекте движение объекта роли не играет. Важно только текущее положение. Алгоритм действий будет таким: допустим, серва повернута на 180 град. Если мне нужно его изменить подношу руку к дальномеру на расстояние 10 см серва принимает положение 60 градусов я убираю руку и серва сохраняет положение 60 градусов. Когда мне нужно изменить его все повторяется. А сейчас как только я убираю руку Дальномер замечает противоположную стены и серва поворачивается на 180 , а мне этого совсем не надо.
     
  11. Megakoteyka

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

    Ну и проверяйте в своем коде показания дальномера.
    Пускай реагирует только на расстояние меньше 10см, а остальное игнорирует.
    Условным оператором пользоваться умеете?
     
  12. karagad

    karagad Нерд

    вот собственно что получилось.
    Код (Text):
    #include <Servo.h>

    #define coef 10 //(коэффициент соответствия 10 градусов на 1см)
    #define dead_zone 4
    #define max_value 22
    #define servoPin 9

    #define Trig 5
    #define Echo 4
    #define ledPin 13

    Servo myservo;

    void setup()
    {
      pinMode(Trig, OUTPUT); //инициируем как выход
      pinMode(Echo, INPUT);  //инициируем как вход
      pinMode(ledPin, OUTPUT);
      myservo.attach(servoPin);
      myservo.write(0);
    }

    unsigned int impulseTime=0;
    unsigned int distance_sm=0;

    void loop()
    {
      digitalWrite(Trig, HIGH); /* Подаем импульс на вход
      trig дальномера */
      delayMicroseconds(10);  // равный 10 микросекундам
      digitalWrite(Trig, LOW); // Отключаем
      impulseTime = pulseIn(Echo, HIGH); // Замеряем длину импульса
      distance_sm = impulseTime/58; // Пересчитываем в сантиметры
     
      if (distance_sm >= dead_zone && distance_sm <= max_value)
      {
        myservo.write(coef * (distance_sm - dead_zone));
      }
     
        }
    Все равно как только я убираю руку серва упорно занимает 180 град.
     
  13. Megakoteyka

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

    Поставьте в код отладочный вывод проанализируйте то, что увидите в мониторе порта.
    Примерно так:
    Код (Text):
    #include <Servo.h>

    #define coef 10 //(коэффициент соответствия 10 градусов на 1см)
    #define dead_zone 4
    #define max_value 22
    #define servoPin 9

    #define Trig 5
    #define Echo 4

    Servo myservo;
    unsigned int impulseTime=0;
    unsigned int distance_sm=0;

    void setup()
    {
      Serial.begin(9600);
      pinMode(Trig, OUTPUT); //инициируем как выход
      pinMode(Echo, INPUT);  //инициируем как вход
      myservo.attach(servoPin);
      myservo.write(0);
    }

    void loop()
    {
      digitalWrite(Trig, HIGH); // Подаем импульс на вход trig дальномера
      delayMicroseconds(10);    // равный 10 микросекундам
      digitalWrite(Trig, LOW);  // Отключаем
     
      impulseTime = pulseIn(Echo, HIGH); // Замеряем длину импульса
      Serial.print("impulseTime: ");
      Serial.println(impulseTime);
     
      distance_sm = impulseTime/58; // Пересчитываем в сантиметры
      Serial.print("distance_sm: ");
      Serial.println(distance_sm);

      if (distance_sm >= dead_zone && distance_sm <= max_value)
      {
        int value = coef * (distance_sm - dead_zone);
        myservo.write(value);
        Serial.print("value: "); Serial.println(value);
      }
    }
     
    karagad нравится это.
  14. karagad

    karagad Нерд

    Огромное спасибо! Все получилось. Серва двигается идеально!:):)
     
  15. Megakoteyka

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

    А в чем проблема-то была?
     
  16. karagad

    karagad Нерд

    До вашего последнего комментария не получалось. Сейчас прочитал что достаточно закомментировать или убрать строку "myservo.write(0); в исходном коде
     
  17. Megakoteyka

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

    Так ведь эта строка в функции setup() была, т.е. она должна выполняться всего один раз по включении питания. Во время работы зеленый светодиод (питание) случайно не моргает?
     
  18. karagad

    karagad Нерд

    Такая строка была и в loop, ее и надо было убрать.