Arduino UNO + шаговый двигатель

everlast
Offline
Зарегистрирован: 29.10.2015

Здравствуйте!

Подскажите, пожалуйста. Есть задача: нужно крутить шаговым мотором, посылая команды (сколько сделать шагов), через COM порт. Потом, как только мы нажали на концевик - мотор остановился. Как только отпустили концевик мотор прошёл еще сколько-то заданных шагов через COM порт.

Получилось закрутить мотор, но он проезжает 2,5 оборота максимум. Посылаю через COM порт 12800 шагов (один оборот) - делает. Посылаю 38400(3 оборота) - делает только 2,5. Больше не делает.

1)Это первая проблема. 

2)Вторая - как останвить мотор?

Я подсоеденил концевик и провери работу на светодиоде - всё работает. Нажимаешь - горит. Отпускаешь - тухнет.

А с мотором не получается. Может есть команда которая останавливает мотор?

renoshnik
Offline
Зарегистрирован: 11.04.2013

Через полчаса группа ЭКСТРАСЕНСОВ займется вашей проблемой...

Araris
Offline
Зарегистрирован: 09.11.2012

Может и есть такая команда, да никто пока не знает, как (программно) Вы управляете мотором. Есть еще вариант: послали команду сделать 1/5/10/100 шагов - проверили состояние концевика - опять послали - опять проверили - опять послали, или не послали - мотор остановился.

everlast
Offline
Зарегистрирован: 29.10.2015
#include <Stepper.h>
#define STEPS 12800           //800 шагов на оборот (но установили микрошаг получилось 12800)
int steps;
int btnPin = 7;                // pin кнопки
int dirPin = 8;                // pin вкл мотора
int btnval=0;
Stepper stepper(STEPS, 2, 5);   //pin которые через плату работают

void setup(){
stepper.setSpeed(10);          // установили скорость
pinMode(dirPin, OUTPUT);
pinMode(btnPin, INPUT);       // а это вход - кнопка
Serial.begin(9600); 
}

void loop()
{
    stepper.step(34000);       // шагов должен сделать
//    delay(1000);
  
//  if (Serial.available()){           
//   steps = Serial.parseInt();               
//      stepper.step(steps);         //через монитор com порта задаем сколько шагов должен сделать
//    }

  btnval = digitalRead(btnPin);    // узнаём состояние кнопки
   if(btnval == HIGH)                 // кнопка нажата
  {
    stepper.setSpeed(0);            // мотор остановился, и вот проблема что же делать когда отпустили кнопку, скорость в 0
    
  }  

 

//    else                          // кнопка не нажата
//  {
//    if (Serial.available()){        
//   steps = Serial.parseInt();               
//      stepper.step(steps);      
//    }
  }

 

nevkon
Offline
Зарегистрирован: 20.01.2015

Если хотите управлять шаговым двигателем в реальном времени - забудьте про библиотеки. Особенно stepper.

everlast
Offline
Зарегистрирован: 29.10.2015

И каким образом управлять? Писать на C? Я новичок в этом деле.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Первое что насторожило: "12800 шагов один оборот".

32767 шагов - 2,559921875 оборота, что очень близко к указанным Вами 2.5.

Так что при таких запросах вместо int нужно пользоваться long.

Но, в принципе, правильно подсказываю: нужно крутить маленикими порциями и проверять, не пора ли останавливать. Возможно, так и int будет достаточно.

vvadim
Offline
Зарегистрирован: 23.05.2012

12800 шагов (один оборот) - а что это за дробление шага?

everlast
Offline
Зарегистрирован: 29.10.2015

800 шагов на оборот- это без дробления. Поставил дробление 16, поэтому и 12800.

everlast
Offline
Зарегистрирован: 29.10.2015

Но, в принципе, правильно подсказываю: нужно крутить маленикими порциями и проверять, не пора ли останавливать. Возможно, так и int будет достаточно.

А как опрашивать не подскажите?

nevkon
Offline
Зарегистрирован: 20.01.2015

Смотря какой драйвер шаговый используется. Бывают импульсами управляются. Если не секрет зачем такая точность? Управление оптикой?

Алгоритм такой:

1. сделал шаг

2. проверил сигнал стоп

3. Если сигнала стоп нет, вернуться к пункту 1

Команду на вращение вы тоже на С пишете. Здесь будет на пару команд больше.

everlast
Offline
Зарегистрирован: 29.10.2015

То есть можно в sketch писать на  С или С++ и ардуиновскими библиотеками? И всё в перемешку?  

Да для оптики. Вот такая штуковина http://ru.aliexpress.com/item/New-UNO-R3-Board-CNC-Shield-Expansion-Board-4-x-A4988-Stepper-Motor-Driver-with-Heat/32467589482.html?spm=2114.031020208.3.1.87379Q&ws_ab_test=searchweb201556_2_79_78_77_91_80,searchweb201644_5,searchweb201560_9

Мне просто нужно остановить шаговый мотор при нажатии на концевик. Не понятно почему в стандартной библиотеке нет остановки мотора.

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

(Получилось закрутить мотор, но он проезжает 2,5 оборота максимум. Посылаю через COM порт 12800 шагов (один оборот) - делает. Посылаю 38400(3 оборота) - делает только 2,5. Больше не делает.)

Может проблема в - int steps; Данная переменная больше 32767 не примет а у Вас на один оборот 12800, отсюда имеем 2,5 оборота

everlast
Offline
Зарегистрирован: 29.10.2015

Попробовал поставить long steps вместо int. Не помогло.

vvadim
Offline
Зарегистрирован: 23.05.2012

everlast пишет:

800 шагов на оборот- это без дробления. Поставил дробление 16, поэтому и 12800.

а что за двигатель с  таким разрешением - 800 на оборот

everlast
Offline
Зарегистрирован: 29.10.2015

Мне сложно сказать. Это китайский. http://kapanadze.zipkatalog.ru/bedini-iz-shagovogo-dvigatelya.html В разрезе типа такого.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

(Потом, как только мы нажали на концевик - мотор остановился. Как только отпустили концевик мотор прошёл еще сколько-то заданных шагов через COM порт.)

Можно попробовать сделать "обманку", алгоритм такой:

1) Достигли концевика и он тупо отрубил питание от шаговика подав сигнал на контролер

2) В порт Вы ввели нужное количество шагов нажали ЕНТЕР сработало реле, заблокировало концевик и шаговик отработал, реле-of

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

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

nevkon
Offline
Зарегистрирован: 20.01.2015

http://roboforum.ru/forum86/topic14992.html

Первая же ссылка в яндексе. Там пример прямого управления этим драйвером напрямую.

everlast
Offline
Зарегистрирован: 29.10.2015

Мне и нужен концевик для "0" пункта(калибровка). Т.е. мотор едет, например, 500 шагов, потом касается концевика и останавливается. Для мотора это и будет "0" пункт. А потом от него сколько нужно уже столько и движемся.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Програмно нужно делать через прерывание. Ваш код на правильность я не проверял но в нево вставил алгоритм прерывания, как я его вижу. Посмотрите може Вам подойдет. Переключите с 2 на 3 Stepper stepper(STEPS, 3, 5); //pin которые через плату работают

#include <Stepper.h>
#define STEPS 12800           //800 шагов на оборот (но установили микрошаг получилось 12800)
uint16_t steps;
int btnPin = 2;                // pin кнопки
int dirPin = 8;                // pin вкл мотора
int btnval = 0;
bool stop = 0; //Флаг что достигли концевика
Stepper stepper(STEPS, 3, 5);   //pin которые через плату работают

void setup() {
  stepper.setSpeed(10);          // установили скорость
  pinMode(dirPin, OUTPUT);
  pinMode(btnPin, INPUT);       // а это вход - кнопка
  attachInterrupt (0, pinChange, CHANGE);  // подключаем обработчик прерывания
  Serial.begin(9600);
}

// Функция обработки прерывания (ISR)
void pinChange ()
{
  stop = 1; //Достигли концевика сработало прерывание
}

void loop()
{
  if (Serial.available()) {  //через монитор com порта задаем сколько шагов должен сделать
    steps = Serial.parseInt();
    stop = 0;

    for (uint16_t i; i < steps ; ++i)// Переменой  задаем cчитаное из com количество шагов для движения
    {
      stepper.step(1);// Делаем один шаг
      if (stop) //Проверяем есть ли прерывание если да выходим из цыкла
      {
        stop = 0;
        break;
      }
    }
  }

}

 

everlast
Offline
Зарегистрирован: 29.10.2015

Спасибо! Буду пробовать! У меня получилось без библиотеки stepper, посмотрев на драйвера A4988 Stepper Motor Driver Carrier Board

paf
Offline
Зарегистрирован: 25.01.2013

Нашел такой скетч.

#include <AccelStepper.h>  
  
#define HALFSTEP 8  
  
#define motorPin1  8     // IN1 on ULN2003 ==> Blue   on 28BYJ-48  
#define motorPin2  9     // IN2 on ULN2004 ==> Pink   on 28BYJ-48  
#define motorPin3  10    // IN3 on ULN2003 ==> Yellow on 28BYJ-48  
#define motorPin4  11    // IN4 on ULN2003 ==> Orange on 28BYJ-48  
  
int endPoint = 1024;     // Move this many steps; 1024 = approx 1/4 turn  
  
// NOTE: The sequence 1-3-2-4 is required for proper sequencing of 28BYJ-48  
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);  
  
volatile boolean stopNow = false;    // flag for Interrupt Service routine  
int cycleCount = 0;                  // counter for endpoint cycles  
boolean homed = false;               // flag to indicate when motor is homed  
  
void setup()  
{  
  attachInterrupt(0, intService, LOW);           // Enable interrupt 0, switch pulled low  
  Serial.begin(9600);  
  Serial.println(stepper1.currentPosition());  
  delay(5000);  
  
  stepper1.setMaxSpeed(1000.0);  
  stepper1.setAcceleration(100.0);  
  stepper1.setSpeed(200);  
  stepper1.moveTo(endPoint);  
}  
  
void loop()  
{  
  if (stopNow)  
   {  
     detachInterrupt(0);                          // Interrupt not needed again (for the moment)  
     Serial.print("Interrupted at ");  
     Serial.println(stepper1.currentPosition());  
     stepper1.stop();  
     stepper1.setCurrentPosition(0);  
     Serial.print("position established at home...");  
     Serial.println(stepper1.currentPosition());  
     stopNow = false;                            // Prevents repeated execution of the above code  
     homed = true;  
   }  
  else  
  if (stepper1.distanceToGo() == 0 && !homed)     //executed repeatedly until we hit the limitswitch  
   {  
     Serial.println(stepper1.currentPosition());  
     stepper1.setCurrentPosition(0);  
     stepper1.moveTo(endPoint);  
     cycleCount ++;  
     Serial.print("cycle count = ");  
     Serial.println(cycleCount);  
     Serial.println(stepper1.currentPosition());  
   }  
  stepper1.run();  
  if(homed)  
   {  
     Serial.println("I am homed");   //Prints continually once homed  
   }  
}  
//  
// Interrupt service routine for INT 0  
//  
void intService()  
{  
  stopNow = true; // Set flag to show Interrupt recognised and then stop the motor  
}  

Набор: Уно, драйвер L298n, двиг 28BYJ-48 в биполярном режиме (перезанная дорожка) включен по схеме из скетча. 

То есть    -   При включении питания пришел к концевику... стоп.   Ок.  А что дальше?

Теперь "сынок, иди работать..."  А мне всего то нужно:

Если  на пин12 - 0 то стоять никуда не ходить! Если там вдруг объявится -1 то шагать 2000 и там стоять пока пин12 не станет в 0. Продолжать.

Помогите разобраться?

 

paf
Offline
Зарегистрирован: 25.01.2013

И еще бы заставить с любого положения пройти половину...