Библиотека AccelStepper

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

Прдключил шаговик через драйвер L293D.  Пример ProportionalControl - работает.  Подключаю через EASYDRIVER ( хочу использовать микрошаг) - не работает.



#include <AccelStepper.h>
AccelStepper stepper(1, 3, 2); 
#define pot A0

void setup()
{  
  stepper.setMaxSpeed(1000);
}
void loop()
{
  int val = analogRead(pot);
  stepper.moveTo(val);
  stepper.setSpeed(300);
  stepper.runSpeedToPosition();
}

Загружаю примеры для EASYDRIVER - всё нормально. Может кто то сталкивался с таким драйвером?

Нужно поворачивать шаговик в соответствии с положением потенциометра.

maksim
Offline
Зарегистрирован: 12.02.2012

А у вашего драйвера, случайно нет вывода ENABLE ?

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

Есть, но его ни в одном примере не используют. На нём по умолчанию 5v.-драйвер вкл.

maksim
Offline
Зарегистрирован: 12.02.2012

Этот вывод инвертирован, то есть когда на нем земля драйвер работает, когда +5 вольт драйвер отключен. Так же он подтянут резистором к земле на плате ,так что если не собираетесь программно отключать драйвер, не используйте этот вывод и ничего к нему не подключайте.

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

ENABLE не использую. 

maksim
Offline
Зарегистрирован: 12.02.2012

Как остальное подключаете описать можете?

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

Почему на схеме подключено к 8 и 9 выводу, а в примере проинициализированы 3 и 2 ?

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

я все примеры делал 3-2

maksim
Offline
Зарегистрирован: 12.02.2012

Что это значит? не понимаю... всегда подключали к 3 и 2 выводам?

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

ДА. Я все скетчи прописывал step 3, dir 2.

maksim
Offline
Зарегистрирован: 12.02.2012

Ну а этот пример работает?

void setup()
 {                
  pinMode(2, OUTPUT);     
  pinMode(3, OUTPUT);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
}

void loop()
 {
  digitalWrite(3, HIGH);
  delay(1);          
  digitalWrite(3, LOW); 
  delay(1);          
}

 

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

работает

maksim
Offline
Зарегистрирован: 12.02.2012

Как вообще проявляется "не работает"? не крутится? дергается? или что?
А этот?

// Blocking.pde
// -*- mode: C++ -*-
//
// Shows how to use the blocking call runToNewPosition
// Which sets a new target position and then waits until the stepper has 
// achieved it.
//
// Copyright (C) 2009 Mike McCauley
// $Id: Blocking.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(1, 3, 2); 

void setup()
{  
    stepper.setMaxSpeed(200.0);
    stepper.setAcceleration(100.0);
}

void loop()
{    
    stepper.runToNewPosition(0);
    stepper.runToNewPosition(500);
    stepper.runToNewPosition(100);
    stepper.runToNewPosition(120);
}

 

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

И Blocking работает. Драйвер по умолчанию установлен на 1/8 шага. Заливаю пример из библиотеки ProportionalControl - мотор вращается постоянно, потенциометр незначительно изменяет скорость, в крайних положениях останавливается. 



val = map(val, 0, 1024, 0, 1600);

Дописал мапирование - никаких изменений.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Вы бы лучше залили бы скетч от maksimа и попробовали.

Ваша ошибка в том, что Вы используете неблокирующую функцию runSpeedToPosition(). В этом случае после нее следует дописать строчку

while (!stepper.run());

Или следует применить блокирующую функцию runToNewPosition();

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

AlexFisher пишет:

Вы бы лучше залили бы скетч от maksimа и попробовали.

Ваша ошибка в том, что Вы используете неблокирующую функцию runSpeedToPosition(). В этом случае после нее следует дописать строчку



while (!stepper.run());

Или следует применить блокирующую функцию runToNewPosition();

Скетч от maksimа я заливал и он работает. Попробую доработать скетч , как вы советуете,  отпишусь.

Не могу понять, почему с драйвером L293D отлично работает (только нет микрошага), а подключаю easydriver - ерунда какая то.

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

Дописал

while (!stepper.run());

никаких изменений. А на runToNewPosition(); ругается, что в библиотеке такого нет.

 

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Как же он может ругаться? У maksimа же именно эта функция используется!

Условие можете попробовать заменить на "стандартное":

while(stepper.distanceToGo()>0) stepper.run();

Или даже так:



#include <AccelStepper.h>
AccelStepper stepper(1, 3, 2); 
#define pot A0

void setup()
{  
  stepper.setMaxSpeed(1000);
}
void loop()
{
  int val = analogRead(pot);
  stepper.moveTo(val);
  stepper.setSpeed(300);
  stepper.runSpeedToPosition();

  while (stepper.distanceToGo()>0) stepper.runSpeed();
  
}

 

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

AlexFisher пишет:

 

Ваша ошибка в том, что Вы используете неблокирующую функцию runSpeedToPosition(). 

Но я же использую стандартный пример ProportionalControl   из библиотеки AccelStepper.h. и ничего не переделываю. С драйвером L293D отлично работает (только нет микрошага), а подключаю easydriver - ерунда какая то. 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Посмотрите, не перепутали ли сигналы step и dir

Попробуйте добавить в setup

stepper.setAcceleration(100.0);

 

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

Нет, правильно подключаю.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Попробуйте так:



#include <AccelStepper.h>
AccelStepper stepper(1, 3, 2); 
#define pot A0

void setup()
{  
  stepper.setMaxSpeed(1000);
  stepper.setAcceleration(200);
}
void loop()
{
  int val = analogRead(pot);
  stepper.moveTo(val);
  stepper.setSpeed(300);
//  stepper.runSpeedToPosition();
  while (stepper.runSpeedToPosition());
  
}

Я когда спрашивал про скетч maximа, имел в виду скетч #13

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Еще возможно для Вашего драйвера длина степа (импульса) слишком коротка (по умолчанию она 1 мкс).  Добавте в сетуп:

stepper.setMinPulseWidth(10);

 

maksim
Offline
Зарегистрирован: 12.02.2012

А потенциометр вы как подключаете?

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Ну если с другим драйвером работало, то можно считать подключение резистора нормальным.

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

После четырёх дней разбирательств и задавания вопросов на форуме предположил, что в библиотеке какой-то глюк. Связался с автором и задал вопрос - оказалось так и есть. Он откорректировал библиотеку ( ВЕРСИЯ 1.29) и всё заработало. Правда есть джиттер в фиксированном положении. 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Чтобы не было джиттера, нужно вводить гистерезис. Например, так:



#define GISTEREZIS 5

...

void loop()
{
  int val = analogRead(pot);
  if (abs(val-stepper.currentPosition()) > GISTEREZIS)
  {
  stepper.moveTo(val);
  ... - поворот шаговика  
  }  
}

 

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

Спасибо AlexFisher.  Попробовал - классно получилось. Джиттер пропал. Про гистерезис ничего не знал ( в голове крутится какая то петля гистерезиса .....)

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

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

Другое название - порог чувствительности или зона нечувствительности.

Экспериментально подбери минимальное значение. 5 - это я с потолка взял.

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

Ну хотя и с потолка, зато сразу в точку!!!!!!!!!!!!!

Спасибо.

step64
Offline
Зарегистрирован: 01.04.2013

Добрый день, интересует микрошаговый режим управления униполярного шаговика. Есть ли или существуют ли вообще библиотеки для микрошага под ардуино? Стоит задача получить микрошаг только силами контроллера (Uno) через ШИМ, не используя сторонние драйвера. Может есть у кого - нибудь подобный пример ? 

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

А зачем, если всё равно прийдётся использовать драйвер. Библиотека не создаёт, а поддерживает режим микрошага, задаваемый драйвером.

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

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

А! нет! оib,cz! Это AFMotor поддерживает. Кстати, может работать в паре с акселстеппер. Но для AFMotor нужен будет соответствующий шилд, или собирать самому, или допиливать библиотеку...

leshak
Offline
Зарегистрирован: 29.09.2011

AlexFisher пишет:

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

А! нет! оib,cz! Это AFMotor поддерживает. Кстати, может работать в паре с акселстеппер. Но для AFMotor нужен будет соответствующий шилд, или собирать самому, или допиливать библиотеку...

Кстати если нужен был полу-шаг, а не микро-шаг (часто путают их), то поддерживает и acel.

AccelStepper stepper(AccelStepper::HALF4WIRE, 8,10,9,11);

step64
Offline
Зарегистрирован: 01.04.2013

Может кто-нибудь помочь новичку в программировании? Есть програмка заставляющая вращаться шаговик на 360, 180, 45 градусов в разные стороны. Программка устраивает, НО необходимо использование полушага. Подскажите как эту програмку переделать под аксельстеппер?




#include <Stepper.h>
#define STEPS 200
Stepper stepper(STEPS, 2, 3, 4, 5);
void setup(){
stepper.setSpeed(50);
}
void loop()
{
  stepper.step(1*STEPS);
  delay(1000);
  stepper.step(-1*STEPS);
  delay(1000);
  stepper.step(0.5*STEPS);
  delay(1000);
  stepper.step(-0.5*STEPS);
  delay(1000);
  stepper.step(0.25*STEPS);
  delay(1000);
  stepper.step(-0.25*STEPS);
  delay(1000);
}

 

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

В библиотеке AccelStepper есть примеры и работа с полушагом. Посмотрите библиотеку, там всё понятно.

step64
Offline
Зарегистрирован: 01.04.2013

Всё таки подскажите как вращать шаговик в одну сторону на 90 градусов, потом в другую на 90 ?

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

Посмотрите библиотеку, примеры из неё, напишите код, попробуйте запустить. Если будут проблемы, тогда покажите код и задайте конкретный вопрос - тогда вам помогут. А ковырятся и писать код за вас никто не будет.

step64
Offline
Зарегистрирован: 01.04.2013

Повернул шаговик на 90 градусов, как обратно его вернуть в исходное положение?

void loop()
{
stepper.setMaxSpeed(1000);
  stepper.moveTo(90);
  stepper.setSpeed(200);
  stepper.runSpeedToPosition();
  
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

А какое у вас исходное положение? Сколько градусов?

step64
Offline
Зарегистрирован: 01.04.2013

Исходное 0 градусов

leshak
Offline
Зарегистрирован: 29.09.2011

Ну так если вы для того что-бы повернутся в 90 делали  stepper.moveTo(90);

То что-бы повернутся в 0 нужно сделать  stepper.moveTo(?);

leshak
Offline
Зарегистрирован: 29.09.2011

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

В ArduinoIDE идете File/Examples/AccelStepper/Blocking и смотрите. Или пример Random() если нужен не блокирующий вариант.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

можно ли в этой библиотеке отследить срабатывание концевика? Другими словами, как прервать движение, начатое по команде stepper.runToNewPosition(xxx);

maksim
Offline
Зарегистрирован: 12.02.2012
stepper.runToNewPosition(stepper.currentPosition());

или

stepper.stop();

заваичит от задачи

nam
Offline
Зарегистрирован: 17.02.2016

Доброго времени суток!

Появился вопрос по этой библиотеке, прошу Вашей помощи.

Задача следующая: заставить два шаговых мотора крутиться на заданное количество шагов за заданный период времени. У каждого мотора своё количество шагов, но время прохождения одно. Шаги и время задаются кнопками, с этим проблем никаких нет.

Предполагаю, что лучше моторы крутить рассчитав скорость (шаги делённые на время). Тут и возникает проблема.

Если сделать так:

speed1 = steps1 / runtime;

speed2 = steps2 / runtime;

stepper1.setSpeed(speed1);

stepper1.moveTo(steps1);

stepper2.setSpeed(speed2);

stepper2.moveTo(steps2);

Моторы слабо вибрируют, но не двигаются. Если вместо speed1 и speed2 ставить конкретное число - все работает без нареканий.

В какую сторону копать? Заранее Спасибо за помощь.

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

а если так?

const float steps1 = 600.0; 
const float steps2 = 480.0; 
const float runtime = 20000.0;    // 20 сек
const float speed1 = steps1 / runtime;
const float speed2 = steps2 / runtime;

... 

stepper1.setSpeed(speed1);
stepper1.moveTo(steps1);

stepper2.setSpeed(speed2);
stepper2.moveTo(steps2);

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Определитесь уже с единицами измерения! Скорость нужно задавать в шагах в секунду, а не в шагах в миллисекунду! И не стоит применять float, нужно использовать long.

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

long Speed = moveTo * 1000L / TimeSlot;

 

nam
Offline
Зарегистрирован: 17.02.2016

Естественно, в моем проекте скорость в секундах,  скорость float speed (значения небольшие, не более 100 - 150 шагов в сек.) 

nam
Offline
Зарегистрирован: 17.02.2016

Tomasina пишет:

а если так?

const float steps1 = 600.0; 
const float steps2 = 480.0; 
const float runtime = 20000.0;    // 20 сек
const float speed1 = steps1 / runtime;
const float speed2 = steps2 / runtime;

... 

stepper1.setSpeed(speed1);
stepper1.moveTo(steps1);

stepper2.setSpeed(speed2);
stepper2.moveTo(steps2);

 

А в чем принципиальная разница? Через час окажусь рядом с ардуинкой, попробую.