Скорость шагового двигателя

saffon88
Offline
Зарегистрирован: 25.08.2022

Всем привет. Знатоки, в силу своей неопытности и малого периода посвященного робототехники столкнулся с такой проблемой. Использую библиотеку шагового двигателя алекса гавера, суть в том что перебрал все драйвера TB6600, DRV, A4988 нужна плавность хода и высокая скорость при полном шаге есть закусывания при разгоне и остановке шд, но при деления шага для более точной и плавной работы, закусывания вроде уходят, но скорость шд логично становится маленькой. Как увеличить скорость шд???( в библиотеке выставил значения максимальной скорости 37000, но она все равно очень мала). Скидываю на всякий случай код( суть кода, что координаты на шд должны приходить в реальном времени на монитор порта с питона и уже потом шд должен по ним перемещаться). Заранее благодарю за содействие, очень подсобите.

#define DRIVER_STEP_TIME 4
#include <GyverPlanner2.h>
#include <GyverStepper2.h>


//int md_speed = 6400;
int path[2]= {10, 10};
// количество точек (пусть компилятор сам считает)
// как вес всего массива / (2+2) байта
int nodeAmount = sizeof(path) / 4;
#include "GyverPlanner2.h"
Stepper< STEPPER2WIRE > stepper1(2, 5);
Stepper< STEPPER2WIRE > stepper2(3, 6);
GPlanner2< STEPPER2WIRE, 2 > planner;
void setup() {
  Serial.begin(115200);
  Serial.setTimeout(50);
  planner.addStepper(0, stepper1);  // ось 0
  planner.addStepper(1, stepper2);  // ось 1
  planner.setAcceleration(7000);
  planner.setMaxSpeed(20000);
  //planner.setDtA(0.9);
  planner.setCurrent(path);
  planner.start();
}


void loop() {
  planner.tick();

  if (Serial.available()) {
    long coordinate = Serial.parseInt();
    if (coordinate != 0) {
      Serial.println(coordinate);
      path[1] = coordinate % 1000;
      path[0] = coordinate / 1000;
      path[0] = path[0] * 10;
      path[1] = path[1] * 10;
      }  
  }
  
  Serial.print(path[0]);
  Serial.print('_');
  Serial.print(path[1]);
  Serial.println();
  
  if (planner.available()) {
    planner.addTarget(path, 0);
  }
   
}

 

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

О каких 37000 может идти речь , если каждый цикл идёт работа с Serial ?
Как чтение так и вывод...

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

Проверил время вывода в порт 264-268 микросекунд.
Время переключения портов , при самом оптимальном коде, будет всяко больше 1мкс, ~4мкс
Ну в итоге получается:
1000000/272=3676 шагов/сек
Вот максимальная скорость, без учёта того, что там у гивера в библиотеке нахуеверчено.

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

Взять проц побыстрее, очевидно.

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

rkit пишет:

Взять проц побыстрее, очевидно.

Ну можно просто отказаться от вывода в порт и сделать блокирующие функции перемещения.

Как то так:

void setup(){
    DDRD=(1<<PD5);
    Serial.begin(115200);
}

void StepperRun(long val){
    while(val){
    PORTD|=1<<PD5;
    PORTD&=~(1<<PD5);
        val--;
        }
}

void loop(){   
    long nStep=0;
    if(в сериал чо то пришло)читаем считаем;
    nStep=то что насчитали;
            StepperRun(nStep);
}

 

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

ПРОСТО - взять проц побыстрее. А если хочется выпендриться, то это делается на шим-выходах.

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

rkit пишет:

ПРОСТО - взять проц побыстрее. А если хочется выпендриться, то это делается на шим-выходах.

Ну тогда уж не шим-выходах, а на выходах подключенным к регистрам таймеров.
Но тогда возникает вопрос, как считать шаги. Каждый раз в прерывание нырять и смотреть ?
Атмега328 нифига не stm32 , у нее аппаратного счётчика событий нет.

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

Усть и не один. Они просто не подключены к событиям таймера, но это решается паяльником.

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

rkit пишет:

Усть и не один. Они просто не подключены к событиям таймера, но это решается паяльником.

Заинтриговал.
Можно подробности ?

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

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

saffon88
Offline
Зарегистрирован: 25.08.2022

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

saffon88
Offline
Зарегистрирован: 25.08.2022

Kakmyc пишет:

rkit пишет:

Взять проц побыстрее, очевидно.

Ну можно просто отказаться от вывода в порт и сделать блокирующие функции перемещения.

Как то так:

void setup(){
    DDRD=(1<<PD5);
    Serial.begin(115200);
}

void StepperRun(long val){
    while(val){
    PORTD|=1<<PD5;
    PORTD&=~(1<<PD5);
        val--;
        }
}

void loop(){   
    long nStep=0;
    if(в сериал чо то пришло)читаем считаем;
    nStep=то что насчитали;
            StepperRun(nStep);
}

 

 

Шаговик движется по рейке, движение происходит за счет передачи координат объекта. Шаговик обязательно должен ехать по координатам. ТВой код не совсем понял, т.к как я камень, который ток разбирается

 

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

saffon88 пишет:

Kakmyc пишет:

rkit пишет:

Взять проц побыстрее, очевидно.

Ну можно просто отказаться от вывода в порт и сделать блокирующие функции перемещения.

Как то так:

void setup(){
    DDRD=(1<<PD5);
    Serial.begin(115200);
}

void StepperRun(long val){
    while(val){
    PORTD|=1<<PD5;
    PORTD&=~(1<<PD5);
        val--;
        }
}

void loop(){   
    long nStep=0;
    if(в сериал чо то пришло)читаем считаем;
    nStep=то что насчитали;
            StepperRun(nStep);
}

 

 

Шаговик движется по рейке, движение происходит за счет передачи координат объекта. Шаговик обязательно должен ехать по координатам. ТВой код не совсем понял, т.к как я камень, который ток разбирается

 

Тогда тебе нужна реализация через ПИД.
Кури интернеты.
Про библиотеки гивера забудь

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

Какой ПИД для системы без обратной связи? Че ты порешь?

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

rkit пишет:

Какой ПИД для системы без обратной связи? Че ты порешь?

Ну ты хоть почитай , что ТС пишет

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

Для общего развития набросал вариант управления скоростью и количеством шагов, через таймеры/счётчики.

//управление шаговым двигателем с аппартаным подсчетом шагов
// минимальная скорость 30шаг/сек максимальная 39000шаг/сек
//минимальное количество шагов 1, максимальное 65635
//Вывод D5(T1/PB5), следует подтянуть к земле резистором 5-10 ком
//И подключить к пину step(d11)

#include <kakmyc_btn.h>
#define Start_BTN 3
kakmyc_btn startBtn(Start_BTN, INPUT_PULLUP, 1);
int motorSpeed = 255;
int motorStep = 10;

void SetTimer2() {
    cli();
    TCCR2A = 0;
    TCCR2B = 0;
    TCCR2B |= (1<<CS20)|(1<<CS21)|(1<<CS22);
    TCCR2A |= (1<<COM2A0);
    TIMSK2 |= (1<<OCIE2A);
    OCR2A = motorSpeed;
    sei();
}

void SetTimer1(int step) {
    cli();
    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1B |= (1<<CS10)|(1<<CS11)|(1<<CS12); //extclock
    TCCR1B |= (1<<WGM12)|(1<<WGM13);
    OCR1A = motorStep;
    TIMSK1 |= (1<<OCIE1A);
    ICR1 = motorStep;
    TCNT1 = 0;
    sei();
}

void StopTimer2() {
    TCCR2B = 0;
}

void SetMotorSpeed() {
    OCR2A = motorSpeed;
}

void MotorRun() {
    SetTimer1(motorStep);
    SetTimer2();
}

ISR(TIMER2_COMPA_vect) {
    TCNT2 = 0;
}

ISR(TIMER1_COMPA_vect) {
    StopTimer2();
}

void setup() {
    Serial.begin(9600);
    pinMode(11, 1);
}

void loop() {
    if(startBtn.read() == 1) {
        MotorRun();
    }
}