• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
AccelStepper problem ze zmianą szybkości silnika.
#11
Ze stykami można poradzić sobie pozaprogramowo. Niestety zmieniony programik nie działa właściwie. Po podaniu napięcia na sterownik rusza z kopyta i nie ma ochoty się zatrzymać. Po wciśnięciu guzika 13 nie tyle co się zatrzymuje, ale cyka po jednym kroku... i tu robi się ciekawie: po każdym następnym kliknięciu mamy efekt zwiększania szybkości.
 
Odpowiedź
#12
(26-06-2024, 19:28)anszun napisał(a): Ze stykami można poradzić sobie pozaprogramowo. Niestety zmieniony programik nie działa właściwie. Po podaniu napięcia na sterownik rusza z kopyta i nie ma ochoty się zatrzymać. Po wciśnięciu guzika 13 nie tyle co się zatrzymuje, ale cyka po jednym kroku... i tu robi się ciekawie: po każdym następnym kliknięciu mamy efekt zwiększania szybkości.

Może podaj cały kod, bo zachowanie, które podałeś wygląda dziwnie. Podejrzewałem, że w sytuacje, gdy silnik nie dostał jeszcze żadnego polecenia, metoda runSpeed() od razu zwraca false i moveTo(0) coś robi, ale sprawdziłem u siebie (jednak używam run()) - nic się nie robi, wypisuje się tylko komunikat, ale silnik ani drgnie. Ja mam silnik podłączony prosto do pinów procka przez ULN200x, który robi za driver, więc mam inaczej zainicjowany obiekt AccelStepper.  Płytka Pro Micro 16MHz/5V.

Mój kod:
Kod:
AccelStepper motX( AccelStepper::HALF4WIRE, .... );

void setup() {
  Serial.begin(9600);     // szybkość nieistotna - to USB
  motX.setMaxSpeed(400);
  motX.setSpeed(200);
  motX.setAcceleration(100);
  //motX.moveTo(0);
}

void loop() {
  if (motX.run() == false)
  {
    Serial.println("Koniec");
    motX.moveTo(0);
  }
}

Natomiast taki kod dale "wahadłowy" ruch silnika - raz w lewo 30000 kroków, raz w prawo.

Kod:
AccelStepper motX(AccelStepper::HALF4WIRE, .... );

long pox = 0;

void setup() {
  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  motX.setMaxSpeed(1800);
  motX.setSpeed(200);
  motX.setAcceleration(200);
  motX.moveTo(pox);
}

void loop() {
  if (motX.run() == false)
  {
    pox = 30000 - pox;
    Serial.print("Koniec ");
    Serial.println(motX.currentPosition());
    motX.moveTo(pox);
  }
}


Wykorzystuje metodę run() - która daje płynne przyspieszanie do prędkości roboczej i zwalnianie, metoda runSpeed() daje dziwny efekt - tak jakby ciągle zwracała false. Trochę to wygląda tak, jak opisałeś, pewnie w tym jest problem. Trzeba to jeszcze sprawdzić.
Tak ogólnie to silniki krokowe mają prędkość graniczną, przy które mogą wystartować i zatrzymać się od razu w jednym kroku. Zależy ona nie tylko od silnika, ale też tego co napędza - liczy się łączny moment bezwładności. Płynne/stopniowe przyspieszanie/hamowanie umożliwia osiągnięcie większej prędkości. U mnie doszło do 1800 kroków/sec.
Z tym, że MultiStepper umożliwia tylko ruch ze stałą prędkością (robi runSpeed() na silnikach) więc tak czy inaczej problem trzeba rozwiązać.
 
Odpowiedź
#13
Chyba mam jak należy fajnie używać silnika ze stałą prędkością.
Wynik runSpeed() jest inny niż run(). Po pierwsze ta funkcja nie przejmuje się pozycją, tylko napędza silnik ze stała szybkościa. Owszem, może być użyteczne, ale silnik krokowy lepiej jest sterować wskazując pozycje do której ma się obrócić.
To coś realizuje runSpeedToPosition(). Ta metoda, wołana ciągle w loop(), powoduje, że silnik kręci się do wskazanej pozycji i zatrzymuje się. Niestety wynik tej funkcji jest nieużyteczny, trzeba sprawdzać currentPosition() lub distanceToGo();
Kolejny problem to uboczne działania niektórych metod, które poza swoim właściwym działanie coś zmieniają dodatkowo. Z tego powodu ważna jest kolejność ustawiania niektórych parametrów i tak move() i moveTo() zerują szybkość. Trzeba zawsze po ustawieniu punktu docelowego ustawić szybkość.
Kod:
mot.moveTo(pos);
mot.setSpeed(v);

Co jakby oznacza przesun się do punktu pos z prędkością v. To raczej powinna być jedna metoda.

Następujący kod daje ruch silnika o 30000 kroków tak i z powrotem ze stała prędkością.
Kod:
long pox = 0;
long divider = 0;


void setup() {
  motX.setMaxSpeed(1800);
  motX.moveTo(0);
  motX.setSpeed(500);
}

void loop() {
  motX.runSpeedToPosition();
  // ten blok to taki podgląd co jakiś czas
  if (divider++ > 100000)
  {
      divider = 0;
      Serial.print("Stamp ");
      Serial.print(motX.currentPosition());
      Serial.print("  ");
      Serial.print(motX.targetPosition());
      Serial.print("  ");
      Serial.println(motX.distanceToGo());
  }
  if (motX.distanceToGo() == 0)
  {
      pox = 30000 - pox;
      Serial.print("Turn back ");
      Serial.println(motX.currentPosition());
      motX.moveTo(pox);
      motX.setSpeed(500);
  }
}

Wychodzi coś następującego:

Cytat:22:40:53.339 -> Stamp 1542  0  -1542
22:40:54.497 -> Stamp 974  0  -974
22:40:55.623 -> Stamp 405  0  -405
22:40:56.451 -> Turn back 0
22:40:56.782 -> Stamp 164  30000  29836
22:40:57.908 -> Stamp 736  30000  29264
22:40:59.067 -> Stamp 1308  30000  28692
22:41:00.194 -> Stamp 1880  30000  28120
22:41:01.353 -> Stamp 2451  30000  27549

Teraz trzeba zająć się sterowaniem dwoma silnikami naraz.

PS. Wrzuciłem na YT filmiki jak wychodzi sterowanie silnikiem w trybie stałej prędkości i w trybie z przyspieszaniem i hamowaniem. Ponieważ można tylko jeden w jednej wiadomości, drugi będzie w kolejnej...

 
Odpowiedź
#14
Wspomniany drugi filmik:

 
Odpowiedź
#15
Ten ostatni kod ( ze zmianą: AccelStepper motX(1,3,6); bo korzystam z TB6600, powoduje u mnie jednostajny, nieprzerwany ruch w jednym kierunku, w którego tle przebija słyszalne regularne "pyknięcie" jakby program usiłował coś zmienić.
 
Odpowiedź
#16
(30-06-2024, 13:59)anszun napisał(a): Ten ostatni kod ( ze zmianą: AccelStepper motX(1,3,6); bo korzystam z TB6600, powoduje u mnie jednostajny, nieprzerwany ruch w jednym kierunku, w którego tle przebija słyszalne regularne "pyknięcie" jakby program usiłował coś zmienić.

Może coś jest nie tak z pinem DIR - określającym kierunek obrotów. Możesz jakoś sprawdzić napięcie na tym pinie (multimetr, jakiś led itp). Można też użyć funkcji setOutputPins() do podejrzenia co robi biblioteka, tyle że ona jest virtual protecte, czyli trzeba by użyć dziedziczenia i napisać własną wersje, np. z podglądem sytuacji.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości