Высокая точность управления оборотами

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем MXXX, 9 фев 2016.

  1. MXXX

    MXXX Гик

    Приветствую товарищи!
    Наткнулся на неожиданную проблему. На производственной линии нужно сделать ролик постоянного вращения.
    Требования:
    1. Скорость вращения 0-100 оборотов/мин.
    2. Управление скоростью вращения с точностью 0.01 оборота в мин.

    Попробовал с шаговиком. Подключил его через L298N. На скетче вывел управление шагами на аппаратный таймер, а управление логикой в loop(). И выяснил, что шаговик при таком подходе меняет скорость не плавно, а дискретно. Величина шага прямопропорциональна оборотам. Если на низах шаг почти не заметен, то на оборотах более 60 он уже порядка 5-6 оборотов в минуту. То есть я могу сделать либо 57, либо 62 об/мин.

    Вот тестовый код скетча:
    Код (C++):

    #include "Arduino.h"
    #include <TimerOne.h>
    #include <Encoder.h>
    #include <Stepper.h>

    //Наш шаговый двигатель. Подключен через драйвер L298N
    Stepper myStepper(200, 22, 24, 26, 28);

    //Энкодер для управления оборотами
    Encoder InterfaceEncoder = Encoder(18, 19);
    long EncoderPosition = 0;

    void setup()
    {
      //Подключенние к аппаратному таймеру прерываний
      Timer1.initialize(500);
      Timer1.attachInterrupt(Timer_Action_ForMotorSteps);
    }

    //Обработчик прерывания по таймеру
    void Timer_Action_ForMotorSteps()
    {
      //Генерируем шаги мотора
      myStepper.step(1);
    }

    void loop()
    {
      //Если ручка энкодера изменила положение, то устанавливаем обороты двигателя
      //равные положению ручки
      long NewPosition = InterfaceEncoder.read();
      if (NewPosition != EncoderPosition)
      {
        myStepper.setSpeed(NewPosition);
        EncoderPosition = NewPosition;
      }
    }
     
    Здесь еще зависимость такая, что чем меньше задержка между вызовами myStepper.step(1), тем более плавно получается управлять оборотами. Но я уже и так довольно часто дергаю таймер. Если еще чаще. то он уже парализует работу всего остального.

    Управлять шаговиком пробовал и через штатную Stepper и через AccelStepper. Разницы никакой. Может как-то его обороты на ШИМ завязать?
     
  2. Onkel

    Onkel Гуру

    это вряд ли.
    напишите свой код и делов. Логика работы шд проста, если нагрузка небольшая, можно в получашаговом режиме, если шд используете на всю - в полношаговом. Мне, например, проще код написать, чем разбираться куда какой таймер в коде из библиотеки. Код простой.
     
  3. MXXX

    MXXX Гик

    Так я и написал свой код. Куда еще своее? )) Мой пример можно и без таймера запустить.

    Код (C++):
    #include "Arduino.h"
    #include <Encoder.h>
    #include <Stepper.h>

    //Наш шаговый двигатель. Подключен через драйвер L298N
    Stepper myStepper(200, 22, 24, 26, 28);

    //Энкодер для управления оборотами
    Encoder InterfaceEncoder = Encoder(18, 19);
    long EncoderPosition = 0;

    void setup()
    {
     
    }

    void loop()
    {
      //Если ручка энкодера изменила положение, то устанавливаем обороты двигателя
      //равные положению ручки
      long NewPosition = InterfaceEncoder.read();
      if (NewPosition != EncoderPosition)
      {
        myStepper.setSpeed(NewPosition);
        EncoderPosition = NewPosition;
      }

      myStepper.step(1);
      delay(10);
    }
    Разницы то никакой. Таймер нужен был чтобы управление шагами двигателя вынести в отдельный поток.
     
  4. viudo

    viudo Нуб

    100 об/м-330.333 Гц, 99 об/мин-330 Гц. Энкодер с таким дискретом работает? Я не использовал его никогда.
     
  5. MXXX

    MXXX Гик

    А при чем здесь энкодер? Я им просто обороты регулирую. Кручу ручку вправо обороты увеличиваются, влево уменьшаются. Вопрос же не про энкодер
     
  6. viudo

    viudo Нуб

    Один щелчок энкодера сколько оборотов прибавляет?
     
  7. Onkel

    Onkel Гуру

    функцию myStepper.setSpeed(NewPosition); ведь не вы писали? А что она там делает?
    или encoder - у него на выходе целое?
    когда я писал "свой код" - я и имел в виду свой код, конфигурируете таймер, по прерыванию таймера мк перещелкивает ноги, шд шагает.
     
  8. MXXX

    MXXX Гик

    Ну вот что-то оно там не то и делает скорее всего. Придется переделать на самодельную реализацию.

    Да с ним то все просто. На выходе целое. Опрашивать можно с любой частотой. Разрешение дает 60 на 360 градусов.

    В общем я пока решил не заморачиваться с шаговиком и подключиться к коллекторному двигателю, который там сейчас и стоит. Управлять буду через ШИМ. Попробую. Если точность не устроит попробую переделать логику на ручное управление, без stepper библиотеки.
     
  9. MXXX

    MXXX Гик

    Прибавляет 1 единицу. А сколько оборотов зависит от библиотеки. Если через stepper библиотеку, как в примере, то там setSpeed задает количество оборотов в минуту. Если через библиотеку AccelStepper, то там одноименная функция принимает количество шагов в сек.
    Но эффект у них одинаковый. Прибавляешь по 1 попугаю на оборот ничего не происходит, потом после 1 попугая резкий скачек оборотов
     
  10. Onkel

    Onkel Гуру

    Будет жутко нелинейно и гистерезис. А направление не нужно переключать? реле или H мост?
     
  11. Onkel

    Onkel Гуру

    Что за энкодер? Я в игрушках и модельках использую энкодеры от авторадио, а 60 имп/оборот не встречал, только корейские по три тыр. летних еще рублей. Ну для асутп 3 тыр (ныне видимо уже 6) не жалко, а вот для себя и экспериментов жаба не дает такой купить.
     
  12. Onkel

    Onkel Гуру

    там скорее всего один байт по регулировке (таймер 0 или 2) и переключение предделителя, так что точность 0.4% недостижима.
    Вам для достижения
    это 20 000 при степпере 200 ш/оборот - нужно или 2 байтный таймер 1 использовать, либо делать прерывания по таймеру 8,333 мс и там инкрементировать /декрементировать целый счетчик на кратное нужной скорости число шагов.
     
  13. viudo

    viudo Нуб

    Нет у меня библиотеки Stepper, да и не нужна она мне. А AccelStepper есть, специально попробовал задать скорости 57, 56, 59 об/мин. У меня полушаг стоит и менять его не хотелось. Таким образом для Асселя это скорости 380, 386.666, 393.333. Тахометра нет, но если туда сюда по 20 оборотов сделать, то разница по времени соответствует расчетной.
     
  14. viudo

    viudo Нуб

    Там опечатка в центре разумеется 58 об/мин.
     
  15. MXXX

    MXXX Гик

    Такой:
    http://iarduino.ru/shop/Sensory-Datchiki/enkoder.html
    Но у него 60 с натяжкой. За 1 щелчек он как правило выдает 2 импульса. Иногда получается повернуть плавно на 1 импульс, но это получается между щелчком нужно удерживать.

    Из-за возможной нелинейности и хотел сделать на шаговике. Хотя там сейчас уже стоит коллекторный мотор управляемый ручным ШИМ регулятором. Буду пробовать и смотреть уже по ходу дела. Направление переключать не нужно.
     
  16. MXXX

    MXXX Гик

    Там что-то другое. Что-то связанное со временем.
    Если крутить цикл без задержки, то регулировка будет плавная:
    Код (C++):
    void loop()
    {
      //Если ручка энкодера изменила положение, то устанавливаем обороты двигателя
      //равные положению ручки
      long NewPosition = InterfaceEncoder.read();
      if (NewPosition != EncoderPosition)
      {
        myStepper.setSpeed(NewPosition);
        EncoderPosition = NewPosition;
      }

      myStepper.step(1);
      delay(10); //Если эту задержку убрать, то регулировка будет плавная
    }
    Но мне процессор еще и для других целей нужен. По этому приходится выводить управление шагами в отдельный поток, через таймер. А поскольку все имеющиеся на борту Arduino таймеры заняты, работать с ними нужно осторожно. Слишком часто дергая таймер начинаются проблемы, например с аппаратными прерываниями.
     
  17. Onkel

    Onkel Гуру

    60? у меня такие штуки дают то ли 8, то ли около того. Они кстати офигенно дребезжат,может у вас 60 с дребезгом? Судя по цене - именно такие у меня и валяются пачками по 5 штук как расходники.
    У 8-битных таймеров есть два типа прерываний, ==А и ==B, может не всё занято? Кстати инкремент счетчика и передрыг ног занимает (вместе с поп апом стека при входе и выходе из прерывания) меньше 10 тактов, так у меня прерывание для обслуживания шд ничего практически не тормозит. Меньше микросекунды.
     
  18. Onkel

    Onkel Гуру

    если внешние прерывания не запрещать, то при выходе из прерывания по равенству таймера мк выполняет и аппаратное прерывание.
     
  19. MXXX

    MXXX Гик

    Значит не такие у Вас. Этот дает ровно 60 на 1 оборот и дребезг ни разу не фиксировал. Хотя на них рекомендуют ставить подтягивающий резистор на 10K. Снизу на плате есть место под него. Подписано как R1. Место есть, а сам резистор с завода почему-то не припаивают. Но я и без резистора дребезг ни разу не фиксировал. Возможно дребезг программно гасит библиотека Encoder, через которую я с ним работаю. Эта же библиотека сама считает импульсы. Можно хоть раз в час запрашивать сколько он импульсов накрутил за этот час.
    Я с ардуино третий день работаю. До этого 15 лет нормального программирования ) По этому даже не придал значения, что у меня оказывается крутой энкодер попался. Думал они все такие. Надеюсь те 10 шт. что я заказал из Китая не 8/1 окажутся ))
     
  20. MXXX

    MXXX Гик

    Я это утверждение видел в какой-то статье в интернете. Но может там про другой процессор речь шла. Изучу этот вопрос. Или может есть какие шилды с тактовым генератором.

    Так и у меня ничего не тормозит. Дело то не в этом. Просто нужно избавиться от странностей библиотек управления шаговиками о которых я писал выше. Думаю, если управлять напрямую без промежуточных библиотек, то можно подцепиться и к уже занятому таймеру. Ничего страшного в этом нет.