Плавный разгон шагового двигателя

Legion_chaoz
Offline
Зарегистрирован: 05.03.2017

Всем привет! Уже который день не могу понять как можно плавно разогнать мой шаговый двигатель(nema 17 +drv4899), управляется он джойстиком, скорость на прямую регулируется потенциометром(скетч ниже)

Задача такая стоит: число выдаваемое потенциометром это число Х, мне нужно что бы за 1сек значение от 0 дошло до этого числа Х.

 

а вот и скетч) не судите строго потому что ардуинщик без малого 5 дней)))

#define step_pin 11  // Pin 3 connected to Steps pin on EasyDriver
#define dir_pin 12   // Pin 2 connected to Direction pin
#define MS1 3       // Pin 5 connected to MS1 pin
#define MS2 4       // Pin 4 connected to MS2 pin
#define MS3 5       // Pin 5 connected to MS3 pin
#define SLEEP 7     // Pin 7 connected to SLEEP pin
#define X_pin A0    // Pin A0 connected to joystick x axis
#define pot A3      //Potenc
 
int direction;    
int Index;
int x;
 
void setup() {
   Serial.begin(9600);
   pinMode(MS1, OUTPUT);
   pinMode(MS2, OUTPUT);
   pinMode(MS3, OUTPUT);
   pinMode(dir_pin, OUTPUT);
   pinMode(step_pin, OUTPUT);
   pinMode(SLEEP, OUTPUT);
   pinMode(pot, INPUT);
   
   digitalWrite(SLEEP, HIGH);  // Wake up EasyDriver
   delay(5);  // Wait for EasyDriver wake up
   
 
/* Configure type of Steps on EasyDriver:
// MS1 MS2
//
// LOW LOW = Full Step //
// HIGH LOW = Half Step //
// LOW HIGH = A quarter of Step //
// HIGH HIGH = An eighth of Step //
*/
 
   digitalWrite(MS1, HIGH);  
   digitalWrite(MS2, HIGH); 
   digitalWrite(MS3, HIGH);
}
 
void loop(){
    while (analogRead(X_pin) >= 0 && analogRead(X_pin) <= 500) {
    for(int i=0; i<5; i++) {       //  for(int i=0; i<6; i++) {
    digitalWrite(dir_pin,HIGH);
    digitalWrite(step_pin,HIGH);
    delayMicroseconds(analogRead(pot));
    digitalWrite(step_pin,LOW);
    delayMicroseconds(analogRead(pot));
    }      
  }
 
    while (analogRead(X_pin) > 550 && analogRead(X_pin) <= 1024) {
    for(int i=0; i<5; i++) {       //  for(int i=0; i<6; i++) {
    {
    digitalWrite(dir_pin,LOW);
    digitalWrite(step_pin,LOW);
    delayMicroseconds(analogRead(pot));
    digitalWrite(step_pin,HIGH);
    delayMicroseconds(analogRead(pot));
      }
    }
}
}
    
Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

Как я понимаю, двигатель не крутится если джой больше 500 но меньше 550 (типа посередине). Тогда в момент когда он вышел за эти рамки - сохраняем время, отмеряем секунду, делим на некоторые периоды (кадры), в каждом из которых к скорости 0 прибавляем максимум деленый на количество периодов. Допустим скорость 500, периодов 50 (1/20 секунды). Значит прибавляется по 500/50=10. Скорость это единица делёная на то что стоит в delayMicroseconds() и видимо ещё на 2, т. к. там две инструкции, на HIGH и на LOW.

Мои замечания:

1. int в счётчиках. Достаточно byte.

2. в цикле направо шаг делается с 1, а налево с нуля. У драйвера што, тип входа меняется на активный ноль? По-идее такой код приведёт к неодинаковому количеству шагов направо и налево.

3. analogRead() выполняется аж 8 раз. Читайте в переменную, работайте затем с ней.

4. Зачем for? Явно не для шага на полный оборот, потому что повторяется не 4 раза а 5 (0,1,2,3,4).