Расчет оборотов ШД при управлении через таймер

User MTU
Offline
Зарегистрирован: 24.03.2012

Добрый день.

Имеется связка из шагового двигателя (2 обмотки, 4 вывода, 200 шагов на оборот) и драйвера. На драйвере скорее всего (потому что оказался кетай с неверными таблицами по выбору тока) выставлен режим 1/16 - но не суть важно (если выставить предполагаемый по таблице 1/32, то количество оборотов двигателя станет в 2 раза меньше, но в таблице у других кетайцев все по-другому).

Сигналы на драйвер в стиле STEP-DIR-EN. Код получился такой:

#define STEP_PIN  3

//volatile unsigned long pulses = 10000; //30 об мин
//volatile unsigned long pulses = 20000; //15 об мин
//volatile unsigned long pulses = 30000; // 10 об мин
//volatile unsigned long pulses = 60000; // 5 об мин 
//volatile unsigned long pulses = 5000; // 60 об мин = 1 об сек
volatile unsigned long pulses = 2500; // 120 об мин = 2 об сек

void setup()
{
  pinMode(STEP_PIN, OUTPUT);
  digitalWrite(STEP_PIN, LOW);
  cli ();                  
  TCCR1A = 0;              
  TCCR1B = 0;              
  OCR1A = pulses;          
  TCCR1B |= (1 << WGM12);   
  TCCR1B |= (1 << CS10);   
  TIMSK1 |= (1 << OCIE1A);  
  sei ();                   
}

ISR (TIMER1_COMPA_vect)         
{
  digitalWrite(STEP_PIN, HIGH); 
  OCR1A = pulses;
  digitalWrite(STEP_PIN, LOW);
}

void loop()
{
}

МК мега328, генератор кварцевый, 16 Мгц. Двигатель уверенно крутит где-то до 150-200 об/мин, потом срывается, но даже 120 об/мин достаточно выше крыши. Минимальные обороты от нуля работают без срыва.

Собственно сама физическая работа ШД устраивает - ток, нагрев, звук - все отлично, не заедает, не заикается.

Скорость двигателя задается переменной pulses, путем записи в OCR1A. Тоже работает, но с одним но.

Удобочитаемее было-б указывать человеческие обороты в минуту. Но, не могу понять как собрать формулу для перерасчета. Единственное что закономерно - если надо в 2 раза уменьшить обороты, то переменная должна быть увеличена в 2 раза. И тут затык... Голова отключилась...Может кто знает как выглядит заветный перевод оборотов в минуту?

-NMi-
Offline
Зарегистрирован: 20.08.2018

Дык у тя щоччик щитат до 65535 а сравниваццо с 0CR1A...

И нахера в векторе 0CR1A присваивать обратно к счёту? Нипанятна.

Тыуш тагда в векторе флаг кванта выставляй а уже в майне флаг обрабатывай...

rkit
Offline
Зарегистрирован: 23.11.2016

f = f_cpu / period

Осилишь перестановку, которую  пятиклассник осилит?

User MTU
Offline
Зарегистрирован: 24.03.2012

rkit пишет:

f = f_cpu / period

По такой формуле двигатель делает лишний поворот на некоторый угол...

-NMi- пишет:

Дык у тя щоччик щитат до 65535 а сравниваццо с 0CR1A...

И нахера в векторе 0CR1A присваивать обратно к счёту? Нипанятна.

Тыуш тагда в векторе флаг кванта выставляй а уже в майне флаг обрабатывай...

В перспективе плавный старт-стоп ШД. Тем не мненее присваивание или нет, в данном примере не влияет ни на что.

-NMi-
Offline
Зарегистрирован: 20.08.2018

User MTU пишет:

Тем не мненее присваивание или нет, в данном примере не влияет ни на что.

Мошт всё-таки пачитать пра Timer1 , его режимы и тд? Ну шоп пабыстрее палучилось?

Гриша
Offline
Зарегистрирован: 27.04.2014

а мона вопрос от дилетанта?! на хрена для 16 битного регистра использовать unsigned long??? в этом есть что-то сакральное?  

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Может л чше ещё раз даташит перечитать и въехать, как правильно работать с таймером ?

User MTU
Offline
Зарегистрирован: 24.03.2012

Хорошо, как видится работа таймера, на моем примере:

TCCR1A и TCCR1B обнуляем потому что arduino IDE.
В TCCR1B бит WGM12 ставим в 1 чтобы сброс таймера был по совпадению. То есть что-то будет делаться в ISR (TIMER1_COMPA_vect){}
В TCCR1B бит CS10 ставим в 1, то есть делитель тактовой частоты 1, то есть работаем на частоте генератора атмеги, то есть 16 МГц.
В TIMSK1 бит OCIE1A ставим в 1, то есть при совпадении содержимого регистра OCR1A и счетного регистра TCNT1 будет сгенерировано прерывание.
Если никуда не лезем, переполнение происходит в общем случае 65535 тактов, на частоте в 16 МГц это каждые 0,0041 сек.
Применительно к переменной pulses, тип поменял на volatile unsigned int (16 бит, без знака, как OCR1A).
 
Направление понимания работы таймера верное?
-NMi-
Offline
Зарегистрирован: 20.08.2018

Таймер то зачем применяется? Для задания кванта времени или как?

User MTU
Offline
Зарегистрирован: 24.03.2012

Меандр генерируется для вращения ШД - это мжно считать приоритетной задачей. Также будет обработка кнопок и вывод на LCD - менее приоритетно, но на вращение ШД оказывать влияние не должно. Поэтому задумка с таймером...

-NMi-
Offline
Зарегистрирован: 20.08.2018

Эту задачу можно на миллисах запросто сделать без таймера.

User MTU
Offline
Зарегистрирован: 24.03.2012

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

Мелкое ковыряние привело к некоей формуле, которая по всей видимости работоспособна. Но есть сомнения в набегающей погрешности оборотов ШД, потому чтообороты в оборотах в секунду, и не всегда целые.

Скорость двигателя получается установить так: 

pulses = (F_CPU / 3200 / 1.6)

3200 - это количество импульсов драйвера, когда выбран микрошаг 1/16, по всей видимости следует считать 200 импульсов на один оборот двигателя, умноженные на 16. В некоторую логику это вписывается

1.6 в данном случае количество оборотов в секунду.

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

Однако осмысление что к чему так и не пришло....

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Печаль