Опять шаговик

inspiritus
Offline
Зарегистрирован: 17.12.2012

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

видится запуск чего то типа Timerone, только вот как задать в куда внутрь на регистр число, при совпадении с которым таймер перестает выдавать импульсы.

такая вот хотелка, может кто то видел что либо подобное?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Можно и без Timerone. Точнее моя структура программы на millis это обеспечивает.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Суть хотелки в том, чтобы выставить необходимое количество шагов, запустить счетчик и забыть до следующей необходимости задать шаги.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Можно все организовать через delay(), программа будет простая, но пока двигатель не дойдет до конца,останется только бегать рядом и кричать "ДАФАЙ,ДАФАЙ". Вариант через millis(), но очень крученый код получится. То есть новичек видет код и нихрена не понимает. Так это и с обычным получается вообще-то.

inspiritus
Offline
Зарегистрирован: 17.12.2012

А возможно есть третий способ через аппаратные средства, о нем я и спрашиваю. Дэлэи и миллисы, извините, освоил лет так тридцать назад :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

inspiritus пишет:

А возможно есть третий способ через аппаратные средства, о нем я и спрашиваю. Дэлэи и миллисы, извините, освоил лет так тридцать назад :)

Спрашивать об аппаратных средствах в разделе программирования?  Ну а вы в канцтоварах не пытались покупать копченую рыбу или сыровяленую колбасу. 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Тут задан вопрос про возможности настройки встроенных таймеров-счетчиков кои являются аппаратными средствами.

Эти самые встроенные аппаратные средства надо настраивать программированием.

Если Вы не понимаете о чем вопрос темы проходите мимо не засоряйте тему оффтопиками.

Вы уже высказались. Большое спасибо. Ваш подробно описанный рецепт банален. Если бы все было так просто я бы вопроса здесь не задавал. 

MagicianT
Offline
Зарегистрирован: 03.10.2015

Адафрутовская лайбрари как раз то что вы ищете, задаётся сколько шагов открутить и не надо ждать:

/*
Adafruit Arduino - Lesson 16. Stepper
*/

#include <Stepper.h>

int in1Pin = 8;
//int in2Pin = 9;
int in2Pin = 10;
int in3Pin = 9;
int in4Pin = 11;

Stepper motor(768, in1Pin, in2Pin, in3Pin, in4Pin);  

void setup()
{
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);

  // this line is for Leonardo's, it delays the serial interface
  // until the terminal window is opened
  while (!Serial);
  
  Serial.begin(115200);
  motor.setSpeed(20);
}

void loop()
{
  if (Serial.available())
  {
    int steps = Serial.parseInt();
    motor.step(steps);
  }
}

 

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

Вы тут какой то пример странный дали. По вашему мотор будет шагать только если в порт постоянно будет приходить поток данных. Ибо, motor.steps(..) за одно обращение выполняет только ОДИН шаг ! Это вообще слабенькая библиотека, на ней сделать равномерное вращение можно только если нужно медленно вращать мотор, да и то сомнительно.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Спасибо. Я пробовал эту библиотеку. Пока motor.step-ы работаюь все остальное стоит. Если во время работы motor.step-ов произойдет прерывание, равномерность работы мотора нарушится. Есть и другие библиотеки для шаговиков. Это чисто программные средства.

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

еще раз суть вопроса: можно ли так настроить встроенный таймер (кроме нулевого), чтобы он выдавал серию импульсов с заданными количеством и частотой?

Кстати, если уважаемые модераторы сочтут, что данная тема будет к месту в "аппаратных средствах" прошу ея туда пререместить.

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

Вот кусок кода , где допиленая библиотека висит на прерываниях:

AccelStepper motor1(&mot1_forward, &mot1_backward); // первый мотор

#define MOTOR1_INIT           ...
#define MOTOR1_STEP_ON         ...
#define MOTOR1_STEP_OFF        ...
#define MOTOR1_DIR_BACKWARD    ...
#define MOTOR1_DIR_FORWARD     ...
#define MOTOR1_SET_ENABLED     ...


//////////////////////////////////ОБСЛУЖИВАНИЕ ПЕРВОГО МОТОРА реализовано на Таймере 4

ISR(TIMER4_COMPB_vect) {MOTOR1_STEP_OFF;} // прерывания для отпускания импульса шага

ISR(TIMER4_COMPA_vect) {motor1.run();} // прерывание обработки первого мотора

void motor1SetPeriod(unsigned int spd) { // установка периода первого мотора
     #define TIMER4_MODE _BV(WGM42)  // режим таймераCTC 
     volatile unsigned long cycles =(F_CPU/spd);
     // ВЫБОР прескалера 
     if(cycles < RESOLUTION)             TCCR4B = _BV(CS40) | TIMER4_MODE;  // нет прескаллера
     else if((cycles /= 8) < RESOLUTION) TCCR4B = _BV(CS41) | TIMER4_MODE;  // прескаллер на 8
     else if((cycles /= 8) < RESOLUTION) TCCR4B = _BV(CS41) | _BV(CS50) | TIMER4_MODE; //  прескаллер на 64
     else if((cycles /= 4) < RESOLUTION) TCCR4B = _BV(CS42) | TIMER4_MODE;  // прескаллер на 256
     else { cycles /= 4; TCCR4B = _BV(CS42) | _BV(CS40) | TIMER4_MODE; }   // прескаллер на 1024, для всего остального
     OCR4A = cycles; // количество циклов
     OCR4B=20; // сброс импульса шага через 20 тиков таймера
 }

void mot1_backward(){
   MOTOR1_DIR_BACKWARD;
   motor1SetPeriod(motor1.speed()); // рассчитать новый период
   MOTOR1_STEP_ON;
 }

void mot1_forward(){
   MOTOR1_DIR_FORWARD;
   motor1SetPeriod(motor1.speed()); // рассчитать новый период
   MOTOR1_STEP_ON;
 

void motor1InitTimer(long speed) {
  TCCR4A = 0; // очистить регистр контроля ног
  if (speed > 0) motor1SetPeriod(speed); // рассчитать период
  TIMSK4 = _BV(OCIE4A) | _BV(OCIE4B); // разрешить прерывания
}

void motor1StopTimer() { // запретить все прерывания по этому таймеру
  TIMSK4=0;
 }

Из самой библиотеки нужно исключить контроль таймингов, в процедуре AccelStepper::runSpeed() закоментировать три строчки:

  //unsigned long time = millis();
  //if (time > _lastStepTime + _stepInterval) { 
     ...
 //}

 

Удалось получить скорость до 8000 шагов в секунду :) Все с разгонами и торможением, красиво и равномерно, один косяк только, на каждый мотор нужен свой таймер. Можно и несколько моторов повесить на один таймер, но уже не будет той плавности и равномерности.

MagicianT
Offline
Зарегистрирован: 03.10.2015

brokly пишет:

Вы тут какой то пример странный дали. По вашему мотор будет шагать только если в порт постоянно будет приходить поток данных. Ибо, motor.steps(..) за одно обращение выполняет только ОДИН шаг ! Это вообще слабенькая библиотека, на ней сделать равномерное вращение можно только если нужно медленно вращать мотор, да и то сомнительно.

 Не понимаю что ты несёшь, сам пользуюсь - парсинг Инт там стоит чтоб из сериала получить число и передать в библиотеку ОДИН раз. Например, посылаем 2048 и степер совершает один оборот. 

MagicianT
Offline
Зарегистрирован: 03.10.2015

inspiritus пишет:
еще раз суть вопроса: можно ли так настроить встроенный таймер (кроме нулевого), чтобы он выдавал серию импульсов с заданными количеством и частотой?
Нельзя. Никак. Степеру надо 4 провода - вывода. Максимум, на аппаратном уровне, с использованием захвата по входу таймера-1 можно сгенерировать последовательность импульсов на 2 вывода, если на 4 -ре то только с использованием прерываний.

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

MagicianT пишет:

  Не понимаю что ты несёшь, сам пользуюсь - парсинг Инт там стоит чтоб из сериала получить число и передать в библиотеку ОДИН раз. Например, посылаем 2048 и степер совершает один оборот. 

Давайте , мы с вами будем повежливее , хорошо? Ну как то слово "несешь" не очень комильфо.

Смотрим в описание библиотеки:

    /// Called to execute a step. Only called when a new step is
    /// required. Subclasses may override to implement new stepping
    /// interfaces. The default calls step1(), step2() or step4() depending on the
    /// number of pins defined for the stepper.
    /// \param[in] step The current step phase number (0 to 3)
    virtual void   step(uint8_t step);

Там написано, что эта функция делает ОДИН ШАГ.

Смотрим в реализацию :

void AccelStepper::step(uint8_t step)
{
    switch (_pins)
    {
        case 0:
            step0();
            break;
	case 1:
	    step1(step);
	    break;
    
	case 2:
	    step2(step);
	    break;
    
	case 4:
	    step4(step);
	    break;  
    }
}

И правда - ОДИН шаг !

Еще раз в описание

   /// Constructor. You can have multiple simultaneous steppers, all moving
   /// at different speeds and accelerations, provided you call their run()

Конкретно написанно , что для работы необходимо регулярно вызывать метод run().

У вас в примере оно где ?

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

MagicianT пишет:

inspiritus пишет:
еще раз суть вопроса: можно ли так настроить встроенный таймер (кроме нулевого), чтобы он выдавал серию импульсов с заданными количеством и частотой?
Нельзя. Никак. Степеру надо 4 провода - вывода. Максимум, на аппаратном уровне, с использованием захвата по входу таймера-1 можно сгенерировать последовательность импульсов на 2 вывода, если на 4 -ре то только с использованием прерываний.

Вы в курсе, что бывают драйвера шаговиков, на которые просто подается импульс шага ?

MagicianT
Offline
Зарегистрирован: 03.10.2015

При чём тут аксел-степер? В примере кода который я запостил ясно написано чти инклудить - stepper.h

Библиотеки попутали? Я думаю что stepper тоже не одна такая, поэтому у кого есть мозги, он пойдёт в гугл и посмотрит урок 16 от адафрута, а гугл переведёт если англез не шибко знаком. Download наверно и без перевода найти не трудно

MagicianT
Offline
Зарегистрирован: 03.10.2015

brokly пишет:

MagicianT пишет:

inspiritus пишет:
еще раз суть вопроса: можно ли так настроить встроенный таймер (кроме нулевого), чтобы он выдавал серию импульсов с заданными количеством и частотой?
Нельзя. Никак. Степеру надо 4 провода - вывода. Максимум, на аппаратном уровне, с использованием захвата по входу таймера-1 можно сгенерировать последовательность импульсов на 2 вывода, если на 4 -ре то только с использованием прерываний.

Вы в курсе, что бывают драйвера шаговиков, на которые просто подается импульс шага ?

Если бы у него был драйвер, вопрос не стоял бы. Очевидно, что таймер-ы програмируют коогда драйвер на ULN2003. Что бывает в НАСА иди в другое место обсуждай.

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

Тяжелый случай. 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Оодаа у меня именно железный драйвер step/dir , которому скармливается напрвление и импульс шага, все остальное он делает сам.

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

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

inspiritus
Offline
Зарегистрирован: 17.12.2012

насколько я понял, Вы используетет библиотеку AccelStepper. но она же программно формирует импульсы управления мотором. у меня же железячный драйвер шаговика и он все это делает сам. ему надо только выставить направление и отсчитать нужное количество импульсов. послать и забыть всегда лучше, чем вести "за ручку". в принципе можт быть и хренбысним. мне надо просто отсчитать шаговиком 5-8 оборотов впрерд и столько же назад. просто, чисто на аппаратных счетчиках это красивее получится.

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

Datak
Offline
Зарегистрирован: 09.10.2014

Цитата:
Функция tone() генерирует на порту вход/выхода сигнал — прямоугольную "волну", заданной частоты и с 50% рабочим циклом. Длительность может быть задана параметром...

Не обещаю, что она подойдёт "как есть", но во всяком случае, можно влезть в исходники библиотеки и посмотреть, что и как там делается.

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

Аксел степпер работает с разными типами шаговиков, в том числе и через контролер. Смысл такой, что выдача команды на шаг в разных случаях разная . В вашем случае она самый простой - импульс на ноге. Где то это изменение уровней на 4 ногах, а может и на шести. Вплоть до того, что процедуру выдачи шага вы пишите сами и при инициализации навязываете ее. Посмотрите мой пример там все есть. Смысл этой ьиьлиотеки именно контрольускорений. Если вам этого не нужно, просто зарядите прерывание таймера, из прерывания выдавайте импульс на нужную ногу и считайте их количество, по достижении нужного количества импульсов, отключите прерывание.

Ну или  вам правильно посоветовали tone(pin, frequency, duration) , например для выдачи 10 импульсов за 1 секунду, на 5 ноге, по идее нужно сказать tone(5,10,1000), а для 20 импульсов за 0.1 секунду tone(5,200,100), Частота 200 герц, это 200 импульсов с секунду, 100 миллисекунд это 0.1 секунды. То есть формула выглядит так количество импульсов = duration/(frecuency*1000). И что самое приятное то, что функция не блокирующая.

Надеюсь я не ошибся :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Управляем мы ШД 4 пинами , по две на фазу, или двумя  ,направление и шаг, мы должны еще задавать скорость вращение ШД. А скорость вращения ШД величина конечная, ограничена скоростью при которой проскальзывают шаги, или же механикой на валу. Есть еще ньанс. Скорее всего надо управлять еще и 3-мя ШД одновременно. Как вариант 2 ШД (Х и Y).  То есть подавать импульсы индивидуально для каждого ШД.  Аппаратных драйверов ШД управляющих внешними драйверами ШД в Атмеле нет. И все подключаемые библиотеки это программный путь.  Конечно можно организовать работу нескольких паралельных программ (драйверов). Вот это и есть наметки на решение проблемы ТС.  Есть еще более простой путь - организовать на millis() работу нескольких программых драйверов ШД. Скорости процессору хватит. Но не думаю что ТС за это возьмется. По этому он и обратился на форум, что бы переложить свою проблему на чужие плечи.Хотя бы частично. 

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

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

inspiritus
Offline
Зарегистрирован: 17.12.2012

применяю ЭТО, нужно управлять одним ШД, за tone() СПАСИБО , буду пробовать. По результатам отпишусь.

попробовал, получилось, то, что надо :) еще раз спасибо.