Помогите с шаговым мотором

Тема в разделе "Arduino & Shields", создана пользователем alexzlo, 24 апр 2016.

  1. alexzlo

    alexzlo Нерд

    Имеем Uno, LCD keypad shield, внешний драйвер и шаговый мотор. Делаю дозатор.
    Всё работает кроме одного. Если выставить до 100 мл то ардуино правильно расчитывает количество оборотов, если больше то логика вся сбивается и мне обсолютсно не понятно почему.
    Допустим за один оборот насос прокачивает 5мл. то есть что бы накачать 100мл нужно сделать 20 оборотов, ардуино прекрасно отрабатывает. А если выставить 200мл, то ардуино делает четверть оборота, а если выставить 300мл, то 18 оборотов. Всю голову сломал.
    Скетч:

    Код (C++):

    #include <LiquidCrystal.h>
    #include <AccelStepper.h>
    // select the pins used on the LCD panel
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

    int stp = 4;  //подключите 13 пин к step
    int dir = 7;  //подключите 12 пин к dir
    int en = 2;
    AccelStepper stepper(1, stp, dir);
    // define some values used by the panel and buttons
    int lcd_key     = 0;
    int adc_key_in  = 0;
    #define btnRIGHT  0
    #define btnUP     1
    #define btnDOWN   2
    #define btnLEFT   3
    #define btnSELECT 4
    #define btnNONE   5
    int vol = 0;
    int done = 0;
    float mlsteps = 5;// милилтров за 1 оборот
    int rot = 1600; //шагов за оборот
    boolean start = false;
    // read the buttons
    int read_LCD_buttons()
    {
    adc_key_in = analogRead(0);    
    if (adc_key_in > 1000) return btnNONE;

    if (adc_key_in < 50)   return btnRIGHT;
    if (adc_key_in < 195)  return btnUP;
    if (adc_key_in < 380)  return btnDOWN;
    if (adc_key_in < 555)  return btnLEFT;
    if (adc_key_in < 790)  return btnSELECT;  


    return btnNONE;  // when all others fail, return this...
    }

    void setup()
    {
       
       lcd.begin(16, 2);              // start the library
       lcd.setCursor(0,0);
       lcd.print("Volume:");
       lcd.setCursor(8,0);
       lcd.print(vol);
       lcd.setCursor(14,0);
       lcd.print("ml");
     
       lcd.setCursor(0,1);
       lcd.print("Done:"); // выполненный объем
       lcd.setCursor(8,1);
       lcd.print(done);
       lcd.setCursor(14,1);
       lcd.print("ml");
       stepper.setMinPulseWidth(10);
       stepper.setMaxSpeed(6000);
      stepper.setAcceleration(6000);
    }
    void loop()
    {
       if(start){
        int allsteps = vol/mlsteps*rot;// расчитываем количество шагов: общий объем делим на объем за оборот и умножаем на кол-во шагов за оборот
          if(stepper.currentPosition() == allsteps){ // если готово
          int allrot = allsteps/rot;
          lcd.setCursor(8,1);
          lcd.print(allrot);
          stepper.setCurrentPosition(0);
          start = false;
          allsteps = 0;
          vol = 0;
          }
         
          stepper.runToNewPosition(allsteps);
         // stepper.moveTo(allsteps); // почему то медоенно вращается мотор, при использовании     runToNewPosition куртит как бешаный
          //stepper.run();
         
       }
       
     
       lcd.setCursor(0,1);            // move to the begining of the second line
       lcd_key = read_LCD_buttons();  // read the buttons
     
       switch (lcd_key)               // depending on which button was pushed, we perform an action
       {
         case btnRIGHT:
           {
            start = true;
            break;
           }
         case btnLEFT:
           {
          // lcd.print("LEFT   ");
           vol = vol +10;
           lcd.setCursor(8,0);
           lcd.print(vol);
           delay(500);
           break;
           }
         case btnUP:
           {
          // lcd.print("UP    ");
           vol = vol +1;
           lcd.setCursor(8,0);
           lcd.print(vol);
           delay(500);
           break;
           }
         case btnDOWN:
           {
          // lcd.print("DOWN  ");
           vol = vol -1;
           lcd.setCursor(8,0);
           lcd.print(vol);
           delay(500);
           break;
           }
         case btnSELECT:
           {
          // lcd.print("SELECT");
           vol = vol +100;
           lcd.setCursor(8,0);
           lcd.print(vol);
           delay(500);
           break;
           }
           case btnNONE:
           {
          // lcd.print("NONE  ");
           break;
           }
       }

    }
     
     
  2. alexzlo

    alexzlo Нерд

    Видео

     
    9xA59kK нравится это.
  3. 9xA59kK

    9xA59kK Гик

    Интересный дозатор.
    Пользуйся шпаргалкой. Размерность "INT" - переменная обозначающая количество шагов на оборот, больше 20 оборотов что произойдет?
    diapazon.gif
     
    Последнее редактирование: 24 апр 2016
  4. Rapidshe

    Rapidshe Нуб

    я тоже намучался с этим) пока долго думал почему же при преодолении определенного значения переменной скетч начинает глючить. зато пришло понимание что
    если нужно фиксировать 0или1, можно использовать boolean (1бит-верно?)
    если 0..255, то используешь byte (1байт)
    если -32 768 до 32 767, то int (или 0 до 65535, unsigned int) (2байта)
    если от -2,147,483,648 до 2,147,483,647, то long (0 до 4,294,967,295, Unsigned long) (4байта)

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