Линейный привод управления Arduino

Обновление:

Вот моя первая попытка на основе найденного кода, но она не сработала. Когда я впервые загрузил его, он переместился на «текущее позиционное значение». Но не выполнил часть цикла void. Просто держит позиции.

Спасибо.

    //Включает
    #include <Servo.h> 

    //Определяет
    #define LINEAR_1_100PIN 11        //Цифровой вывод линейного привода
    #define LINEAR_2_100PIN 6      //Цифровой вывод линейного привода

    String msg;

    //максимальные/минимальные значения импульсов в микросекундах для линейных приводов
    #define LINEAR_1_100_MIN      1050  //
    #define LINEAR_1_100_MAX      2000 //
    #define LINEAR_2_100_MIN  1050     //
    #define LINEAR_2_100_MAX  2000    //


    Servo LINEAR_1_100, LINEAR_2_100;  // создаем сервообъекты для управления линейными приводами
    //int РучкаValue, слайдерValue; //переменные для хранения последних показаний с аналоговых выводов

    int linear100Value_1 = 1051;   //текущее позиционное значение отправляется на линейный привод.
    int linear100Value_2 = 1051;  //текущее позиционное значение отправляется на линейный привод.

    int speed = 10;

    void setup() 
    { 
      //инициализируем сервоприводы
      LINEAR_1_100.attach(LINEAR_1_100PIN, LINEAR_1_100_MIN, LINEAR_1_100_MAX);      // прикрепляет/активирует линейный привод как сервообъект
      LINEAR_2_100.attach(LINEAR_2_100PIN, LINEAR_2_100_MIN, LINEAR_2_100_MAX);  // прикрепляет/активирует линейный привод как сервообъект

      //Аналоговые контакты не нуждаются в инициализации

      //используем writeMicroсекунды, чтобы установить линейные приводы в положения по умолчанию
      LINEAR_1_100.writeMicroseconds(linear100Value_1); 
      LINEAR_2_100.writeMicroseconds(linear100Value_2);
    } 

    void loop() 
    { 
   LINEAR_1_100.write(90); 
   delay(1000);
   LINEAR_1_100.write(0); 
   delay(1000);
   LINEAR_2_100.write(90); 
   delay(1000);
   LINEAR_2_100.write(0); 
   delay(1000);
    }

Старый вопрос:

Я пытаюсь написать код, описанный в этом уроке:

http ://learn.robotgeek.com/demo-code/118-arduino-linear-actuator-tutorial-analog-direct-control-of-small-linear-actuator.html

https://github.com/robotgeek/firgelliDirectControl/blob/master/firgelliDirectControl/firgelliDirectControl .ino

Работа с ШИМ от Ардуино, без дополнительной платы.

Пока что примеры Arduino>Servo>Sweep работает так, как мне хотелось бы (задержка изменена на 30 мс), но очень медленно, и кажется, что он не просто делает 180 шагов, ждет 30 мс и снова 180 шагов. Иногда он движется дважды в одном направлении. Если я изменю шаги с 1 на 5, сервопривод больше не будет двигаться (я ожидал, что он будет работать быстрее).

С помощью приведенного выше кода я понимаю, что могу управлять сервоприводом с помощью ручки или ползунка, но мне хотелось бы понять, как я могу управлять этим сервоприводом линейного привода с помощью ШИМ от контакта Arduino PMW (например, 11) и изменять скорость. Наконец, я хотел бы, чтобы сервопривод последовательно делал x шагов, ждал x мс и снова возвращался на такое же количество шагов.

Самое главное, я хотел бы убедиться, что он всегда заканчивается на позиции 0 и не накапливает ошибок.

Спасибо за любую помощь.

, 👍1


1 ответ


Лучший ответ:

1

Что касается уверенности в возврате в позицию 0, то это не проблема. На самом деле вы ничего не контролируете с помощью ШИМ. Вы всего лишь посылаете сигнал микросхеме внутри сервопривода, чтобы сообщить ей, куда переместить привод. Эта микросхема знает, в каком положении находится привод в любой момент, обычно с помощью какого-либо энкодера (это называется системой с замкнутым контуром), и она будет следить за тем, чтобы он возвращался точно в 0 всякий раз, когда вы скажите ему перейти в 0.

Если вы хотите внести ясность, вы можете использовать метод write для отправки значения на сервопривод.

void Servo::write(int value)
{
  if(value < MIN_PULSE_WIDTH)
  {  // значения меньше 544 обрабатываются как углы в градусах (допустимые значения в микросекундах обрабатываются как микросекунды)
    if(value < 0) value = 0;
    if(value > 180) value = 180;
    value = map(value, 0, 180, SERVO_MIN(),  SERVO_MAX());
  }
  this->writeMicroseconds(value);
}

Любое значение от 0 до 180 задает положение, в которое сервопривод будет перемещаться от минимального до максимально возможного положения. Нет необходимости вручную рассчитывать микросекунды.

Нужно помнить, что ШИМ работает постоянно. Если вы напишете, например, LINEAR_1_100.writeMicroсекунды(1051), этот код установит некоторые таймеры, счетчики и прескалеры внутри чипа ATmega на плате Arduino, и значение ШИМ будет отправляться постоянно, пока вы его не измените.

Таким образом, delay(2000) не останавливает сигнал ШИМ, и сервопривод остается в постоянном положении.

Проблема здесь:

LINEAR_1_100.writeMicroseconds(1800); 
LINEAR_1_100.writeMicroseconds(1051); 

Вы установили значение 1800, а затем сразу же установили значение 1051, но у ATmega даже не было времени отправить первое значение на сервопривод. Добавьте delay(1000) после каждого вызова write или writeMicroсекунды, чтобы позволить ШИМ фактически отправляться на сервопривод.

,

Спасибо за пояснение. Но как я могу интегрировать это в свой код? Могу ли я просто вызвать void servo из цикла void? Нужно ли мне определять MIN_PULSE_WIDTH, SERVO_MIN, MAX? Это похоже на решение, но как я могу изменить свой код. Кроме того, :: кажется мне кодом C++, и я не так часто с этим сталкиваюсь. Еще раз спасибо., @digit

Извините, что запутал вас. Вы уже определили эти значения, когда создавали/прикрепляли LINEAR_1_100 и LINEAR_2_100, код взят из библиотеки Servo.h. Не вдавайтесь в это слишком много. Все, что вам нужно сделать, это написать в коде LINEAR_1_100.write(90) и добавить после него delay(1000), чтобы дать Arduino некоторое время для фактической отправки значения ШИМ на сервопривод., @Filip Franik

Я изменил свой код (см. выше), но он все равно не перемещается. Я просто слышу, как он тикает, но никакого движения., @digit

Вы случайно не подключаете сервопривод напрямую от Arduino, подключенного к вашему ПК? Я смоделировал ваш код в Tinkercad, и он отлично работает с обычными виртуальными сервоприводами. Возможно, ваши линейные сервоприводы потребляют слишком много тока, и схема защиты (в ноутбуке) срабатывает и отключает питание. Запитайте их от внешнего источника 5 В (не через Arduino, потому что он тоже может сгореть)., @Filip Franik

Хорошо, спасибо за отзыв. Я нет, но, возможно, степени магистра недостаточно., @digit