Подключение шагового двигателя 28BYJ-48 через ULN2003

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем d00m, 19 фев 2013.

  1. uussh

    uussh Нерд

    код делает:
    повернули резистор повернулся вал мотора.
     
  2. d00m

    d00m Гик

    дада понял.. я поправил чуть. в loop сделал только

    myStepper.step(2048);
    delay(500);

    оно и правда через 2048 шага прокручивается на полный оборот. чтож тогда я высчитывал выше ?
    вроде и там логика была..
    правда вот вижу что круг всегда заканчивается с каким то смещением - за 10 кругов точка останова уже сместилась градусов на 30..
     
  3. pyro

    pyro Гик

    Есть шаг это когда напряжение подается поочереди на обмотки, а есть полу-шаг это когда напряжение подается на следующую обмотку не выключая предидущую, вал поворачивается на пол шага. Библиотека с полу-шагами работать не может, а в даташите за шаг подразумевался полу-шаг.
     
  4. d00m

    d00m Гик

    то есть все таки 4096 полных шагов нужно ?
    сударь, вы можете показать код ? или какую библиотеку использовать ?
     
  5. d00m

    d00m Гик

    когда я указываю
    const int stepsPerRevolution = 4096;
    мотор не крутится, просто вибрирует. чтото ему не нравится
     
  6. pyro

    pyro Гик

    В описании библиотеки на сайте написано:
    steps: the number of steps in one revolution of your motor.
    Перевод:
    число шагов на один оборот вашего двигателя.
    У двигателя 64 шага на оборот, это с реуктором 4096, может надо указывать 64.
     
  7. hibiki

    hibiki Гик

    не может, а точно. у вас даже не микрошаг, а непонятно что получается с 4096

    и без концевиков/энкодера все равно не обойдется - нужно или определять текущее положение при включении, или приводить его к какому-то известному - нулю или максимуму, например.
     
  8. uussh

    uussh Нерд

    просто когда вы меняете эту константу библиотека рассчитывает каким то обозом скорость
    снизьте скорость в два раза
    // set the speed at max 14 rpm:
    myStepper.setSpeed(5);
    должно работать.
    по моему stepsPerRevolution только и влияет на скорость.
     
  9. d00m

    d00m Гик

    итак снова начинаю расчеты.
    • Reduction Ratio: 1/64
    • Step Torque Angle: 5.625/64

    угол поворота внутреннего вала мотора 5.625 градусов за один шаг.
    угол поворота внешнего вала редуктора - уже 5.625/64 = 0.087890625 градусов.
    таким образом редуктор у нас понижающий, и за этот счет сам шаговик становится более тяговитым, то есть мощнее.

    пока все правильно ?
    едем дальше.
    чтобы использовать либу Stepper, которая вроде как не приспособлена к шаговикам с редуктором, нам надо сделать какието поправки в коде.
    есть мнение, что надо менять порядок пинов, а другое мнение- что нужно менять переменную steps, передаваемую в экземпляр класса Stepper.
    надеюсь и тут пока правильно.
    вот что у меня получается:

    и вот такой вариант кода:
    Код (Text):
    #include <Stepper.h>
     
    const int stepsPerRevolution = 64;  //кол-во шагов на оборот
     
    //Stepper myStepper(stepsPerRevolution, 8,10,9,11);      
    Stepper myStepper(stepsPerRevolution, 8,9,10,11);
     
    void setup() {
      // set the speed at max 14 rpm:
      myStepper.setSpeed(5);
      // initialize the serial port:
      Serial.begin(9600);
     
    }
     
    void loop()
    {
    myStepper.step(64);
    // myStepper.step(-2025);
    delay(2000);
    }
    крутит внешний вал мотора на 32 шага ! и замирает на 2 сек. и так далее..
    32 считал сам - по щелчкам из мотора.
    причем крутит ОЧЕНЬ медленно, примерно пару шагов в секунду !

    если я меняю
    const int stepsPerRevolution = 2048;
    прокручивает гораздо быстрее, но на такой же угол как и до этого - то есть делает всего 32 шага !

    чето я не пойму откуда 32 взялось.
     
  10. d00m

    d00m Гик

    да, кстати - порядок пинов тоже менял, как видно из кода - ничего не меняется.
     
  11. uussh

    uussh Нерд

    Скажите когда пины по порядку мотор у вас крутиться в обратном направлении?
     
  12. d00m

    d00m Гик

    нет.
    только так крутится обратно:
    Код (Text):
    #include <Stepper.h>
     
    const int stepsPerRevolution = 64;  //кол-во шагов на оборот
     
    Stepper myStepper(stepsPerRevolution, 8,10,9,11);        
    //Stepper myStepper(stepsPerRevolution, 8,9,10,11);
     
    void setup() {
      // set the speed at max 14 rpm:
      myStepper.setSpeed(10);
      // initialize the serial port:
      Serial.begin(9600);
     
    }
     
    void loop()
    {
     
    myStepper.step(64);
    myStepper.step(-64);
    delay(2000);
    }
    просто у меня три таких мотора и все ведут себя одинаково.
    я не пойму куда копать дальше..
     
  13. d00m

    d00m Гик

    кстати ситуация с пинами - это баг или фича ?
     
  14. uussh

    uussh Нерд

    просто мне кажется особенность данного двигателя (такое расположение выводов обмоток) stepper motor 28byj.jpg

    теперь надо заставить чтобы проходила инициализация т.е. мотор должен докрутится до концевика
    (не важно что это будет : кнопка опто датчик или холла )
    и остановится это будет начальная точка. но загвоздка в том, что это должно происходить только один раз при подачи питания или при сброссе.
     
  15. d00m

    d00m Гик

    погодите-погодите, про датчики еще рановато )

    я хочу уже зафиксировать насчет шагов и углов.
    то есть вы предлагаете все таки использовать перемешанную нумерацию пинов ?
    ok, можно пока для ясности замять этот вопрос..
    но откуда 32 шага взялось ?
    и стоит ли использовать либу Stepper ?
    я так и не понял какой мне код лучше использовать..
    а еще ведь остались вопросы про микрошаг - говорят, что при его использовании можно увеличить скорость и точность движения. а как его получить я пока не знаю..

    и еще - все таки смещается положение вала, я уже говорил выше - есть какаято ошибка в шагах.
    то есть если прикрепить стрелку к нему и запустить крутить обороты и после каждого полного оборота делать паузу, то стрелка НЕ будет показывать на одну и ту же точку. она будет смещаться постоянно на какойто градус..
     
  16. uussh

    uussh Нерд

    да Вы правы действительно набегает погрешность значит полный оборот не 2048 а меньше
    как посчитать не знаю думаю только подобрать.
     
  17. d00m

    d00m Гик

    есть вариант использовать либу AccelStepper.h
    http://www.open.com.au/mikem/arduino/AccelStepper/index.html

    или вот еще есть тред:
    http://arduino.cc/forum/index.php?topic=135032.0

    а вобще вот что есть на второй странице нашего треда:
    http://forum.amperka.ru/threads/Под...-28byj-48-через-uln2003.1264/page-2#post-9235

    и действительно - число 2038 оборотов дает ровно один круг, без погрешностей !

    я так же нашел упоминае об этом числе вот тут
    http://arduino.cc/forum/index.php?topic=108983.0
    но там тоже не могу объяснить откуда оно взялось..
    и каким образом можно связать число зубцов 32 на ведущем вале с передаточным числом 1/64 ??
    а их там действительно ровно 32, помните я выше говорил что мотор крутил 32 шага на ведомом валу, то есть на редукторе уже, при полном обороте ведущего вала в 64 шага.
    вобщем какаято нумерология началась..
     
  18. uussh

    uussh Нерд

    Кажется понял в чем проблема:
    вот логика управления данным двигателем,

    28byj48_02.jpg

    а вот код библиотеки Stepper,
    Код (Text):
    /*
      Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.4
     
      Original library  (0.1) by Tom Igoe.
      Two-wire modifications  (0.2) by Sebastian Gassner
      Combination version  (0.3) by Tom Igoe and David Mellis
      Bug fix for four-wire  (0.4) by Tom Igoe, bug fix from Noah Shibley
     
      Drives a unipolar or bipolar stepper motor using  2 wires or 4 wires
     
      When wiring multiple stepper motors to a microcontroller,
      you quickly run out of output pins, with each motor requiring 4 connections.
     
      By making use of the fact that at any time two of the four motor
      coils are the inverse  of the other two, the number of
      control connections can be reduced from 4 to 2.
     
      A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
      connects to only 2 microcontroler pins, inverts the signals received,
      and delivers the 4 (2 plus 2 inverted ones) output signals required
      for driving a stepper motor.
     
      The sequence of control signals for 4 control wires is as follows:
     
      Step C0 C1 C2 C3
        1  1  0  1  0
        2  0  1  1  0
        3  0  1  0  1
        4  1  0  0  1
     
      The sequence of controls signals for 2 control wires is as follows
      (columns C1 and C2 from above):
     
      Step C0 C1
        1  0  1
        2  1  1
        3  1  0
        4  0  0
     
      The circuits can be found at
     
    http://www.arduino.cc/en/Tutorial/Stepper
     
     
    */
     
     
    #include "Arduino.h"
    #include "Stepper.h"
     
    /*
    * two-wire constructor.
    * Sets which wires should control the motor.
    */
    Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2)
    {
      this->step_number = 0;      // which step the motor is on
      this->speed = 0;      // the motor speed, in revolutions per minute
      this->direction = 0;    // motor direction
      this->last_step_time = 0; // time stamp in ms of the last step taken
      this->number_of_steps = number_of_steps;  // total number of steps for this motor
     
      // Arduino pins for the motor control connection:
      this->motor_pin_1 = motor_pin_1;
      this->motor_pin_2 = motor_pin_2;
     
      // setup the pins on the microcontroller:
      pinMode(this->motor_pin_1, OUTPUT);
      pinMode(this->motor_pin_2, OUTPUT);
     
      // When there are only 2 pins, set the other two to 0:
      this->motor_pin_3 = 0;
      this->motor_pin_4 = 0;
     
      // pin_count is used by the stepMotor() method:
      this->pin_count = 2;
    }
     
     
    /*
    *  constructor for four-pin version
    *  Sets which wires should control the motor.
    */
     
    Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4)
    {
      this->step_number = 0;      // which step the motor is on
      this->speed = 0;      // the motor speed, in revolutions per minute
      this->direction = 0;    // motor direction
      this->last_step_time = 0; // time stamp in ms of the last step taken
      this->number_of_steps = number_of_steps;  // total number of steps for this motor
     
      // Arduino pins for the motor control connection:
      this->motor_pin_1 = motor_pin_1;
      this->motor_pin_2 = motor_pin_2;
      this->motor_pin_3 = motor_pin_3;
      this->motor_pin_4 = motor_pin_4;
     
      // setup the pins on the microcontroller:
      pinMode(this->motor_pin_1, OUTPUT);
      pinMode(this->motor_pin_2, OUTPUT);
      pinMode(this->motor_pin_3, OUTPUT);
      pinMode(this->motor_pin_4, OUTPUT);
     
      // pin_count is used by the stepMotor() method:
      this->pin_count = 4;
    }
     
    /*
      Sets the speed in revs per minute
     
    */
    void Stepper::setSpeed(long whatSpeed)
    {
      this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
    }
     
    /*
      Moves the motor steps_to_move steps.  If the number is negative,
      the motor moves in the reverse direction.
    */
    void Stepper::step(int steps_to_move)
    {
      int steps_left = abs(steps_to_move);  // how many steps to take
     
      // determine direction based on whether steps_to_mode is + or -:
      if (steps_to_move > 0) {this->direction = 1;}
      if (steps_to_move < 0) {this->direction = 0;}
       
       
      // decrement the number of steps, moving one step each time:
      while(steps_left > 0) {
      // move only if the appropriate delay has passed:
      if (millis() - this->last_step_time >= this->step_delay) {
          // get the timeStamp of when you stepped:
          this->last_step_time = millis();
          // increment or decrement the step number,
          // depending on direction:
          if (this->direction == 1) {
            this->step_number++;
            if (this->step_number == this->number_of_steps) {
              this->step_number = 0;
            }
          }
          else {
            if (this->step_number == 0) {
              this->step_number = this->number_of_steps;
            }
            this->step_number--;
          }
          // decrement the steps left:
          steps_left--;
          // step the motor to step number 0, 1, 2, or 3:
          stepMotor(this->step_number % 4);
        }
      }
    }
     
    /*
    * Moves the motor forward or backwards.
    */
    void Stepper::stepMotor(int thisStep)
    {
      if (this->pin_count == 2) {
        switch (thisStep) {
          case 0: /* 01 */
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, HIGH);
          break;
          case 1: /* 11 */
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, HIGH);
          break;
          case 2: /* 10 */
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, LOW);
          break;
          case 3: /* 00 */
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, LOW);
          break;
        }
      }
      if (this->pin_count == 4) {
        switch (thisStep) {
          case 0:   // 1010
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, LOW);
          digitalWrite(motor_pin_3, HIGH);
          digitalWrite(motor_pin_4, LOW);
          break;
          case 1:   // 0110
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, HIGH);
          digitalWrite(motor_pin_3, HIGH);
          digitalWrite(motor_pin_4, LOW);
          break;
          case 2:   //0101
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, HIGH);
          digitalWrite(motor_pin_3, LOW);
          digitalWrite(motor_pin_4, HIGH);
          break;
          case 3:   //1001
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, LOW);
          digitalWrite(motor_pin_3, LOW);
          digitalWrite(motor_pin_4, HIGH);
          break;
        }
      }
    }
     
    /*
      version() returns the version of the library:
    */
    int Stepper::version(void)
    {
      return 4;
    }

    Как видно в не восемь шагов, а всего четыре.
    Значит данная библиотека не подходит для данного мотора и управляет им как попало,
    Решение проблемы управлением 28byj48 на мой взгляд переписать данную библиотеку под алгоритм этого двигателя.
     
  19. d00m

    d00m Гик

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

    но все таки -
    я понимаю все слова по отдельности, но не в таком порядке :(
    можете объяснить подробнее ?
    наш мотор должен "в 8 шагов" управляться ?
     
  20. uussh

    uussh Нерд

    в данной библиотеке выходы меняются так
    Step C0 C1 C2 C3
    1 __ 1 _0_ 1 _0
    2 __0_ 1 _1_ 0
    3 __0 _1_ 0_ 1
    4 __1_ 0_ 0 _ 1
    Код (Text):
    if (this->pin_count == 4) {
        switch (thisStep) {
          case 0:   // 1010
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, LOW);
          digitalWrite(motor_pin_3, HIGH);
          digitalWrite(motor_pin_4, LOW);
          break;
          case 1:   // 0110
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, HIGH);
          digitalWrite(motor_pin_3, HIGH);
          digitalWrite(motor_pin_4, LOW);
          break;
          case 2:   //0101
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, HIGH);
          digitalWrite(motor_pin_3, LOW);
          digitalWrite(motor_pin_4, HIGH);
          break;
          case 3:   //1001
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, LOW);
          digitalWrite(motor_pin_3, LOW);
          digitalWrite(motor_pin_4, HIGH);
          break;
    А нам надо так:
    Step C0 C1 C2 C3 C4 C5 C6 C7
    1 __ 1 _ 1_ 0_ 0 _0 _0_ 0_ 1
    2 __ 0_ 1_ 1 _ 1_ 0_ 0_ 0_ 0
    3 __0_ 0 _0_ 1_ 1 _1 _ 0_ 0
    4 __0_ 0_ 0 _ 0_ 0_ 1 _ 1_ 1