• 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.
#1
Mój internetowy Przyjaciel stworzył mały programik pozwalający na uruchamianie silnika - pracującego na stałych obrotach -przyciskiem. Potem silnik wykonuje zadaną liczbę obrotów .....i to działa. Problem polega na tym silnik pracuje bardzo wolno i nie można przestawić jego szybkości bez względu na to jaką wartość wpiszemy w    stepper.setSpeed (....). Co ciekawe, przy odznaczeniu wszstkiego w void loop() , z wyjątkiem   stepper.runSpeed(); daje się łatwo zmieniać prędkość. Program wygląda na logiczny, jednak diabełek siedzi w sekcji void loop() Próbowaliśmy już różnych sposobów i nic ! Poratujcie !

#include <AccelStepper.h>

// Definicje pinów dla silnika i przycisku
#define X_STEP_PIN 3
#define X_DIR_PIN 6
#define BUTTON_PIN 13

AccelStepper stepper(AccelStepper:Big GrinRIVER, X_STEP_PIN, X_DIR_PIN);

int targetSteps = 2000; // Liczba kroków do wykonania (np. 10 obrotów przy 200 krokach na obrót)
int stepCount = 0;
bool running = false; // Flaga do kontroli stanu silnika
bool buttonStatePrevious = HIGH; // Poprzedni stan przycisku

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP); // Ustawienie pinu przycisku
  stepper.setMaxSpeed(1000); // Ustaw maksymalną prędkość w krokach na sekundę
  stepper.setSpeed(500); // Ustaw prędkość w krokach na sekundę
}

void loop() {
  int buttonState = digitalRead(BUTTON_PIN);
  delay(50);

  // Sprawdź, czy przycisk został wciśnięty (zbocze narastające)
  if (buttonState == LOW && buttonStatePrevious == HIGH) {
    buttonStatePrevious = buttonState; // Aktualizacja poprzedniego stanu przycisku
    running = !running; // Przełącz stan silnika (start/stop)
    stepCount = 0; // Reset liczby kroków przy starcie
  } else {
    buttonStatePrevious = buttonState; // Aktualizacja poprzedniego stanu przycisku
  }

  // Uruchom lub zatrzymaj silnik w zależności od stanu
  if (running) {
    stepper.runSpeed(); // Utrzymywanie stałej prędkości
    stepCount++;
    if (stepCount >= targetSteps) {
      running = false; // Zatrzymaj silnik po osiągnięciu liczby kroków
    }
  }
}
 
Odpowiedź
#2
(24-06-2024, 20:12)anszun napisał(a): Mój internetowy Przyjaciel stworzył mały programik pozwalający na uruchamianie silnika - pracującego na stałych obrotach -przyciskiem. Potem silnik wykonuje zadaną liczbę obrotów .....i to działa. Problem polega na tym silnik pracuje bardzo wolno i nie można przestawić jego szybkości bez względu na to jaką wartość wpiszemy w    stepper.setSpeed (....). Co ciekawe, przy odznaczeniu wszstkiego w void loop() , z wyjątkiem   stepper.runSpeed(); daje się łatwo zmieniać prędkość. Program wygląda na logiczny, jednak diabełek siedzi w sekcji void loop() Próbowaliśmy już różnych sposobów i nic ! Poratujcie !

void loop() {
  int buttonState = digitalRead(BUTTON_PIN);
  delay(50);
    ...

}

Przecież masz delay wewnątrz loop() - jak ma chodzić bardzo szybko?
 
Odpowiedź
#3
Tylko delaya nie może się pozbyć bo będzie problem z przyciskiem Smile
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#4
Zmniejszyłem delay do 1. Rzeczywiście teraz kręci dobrze i przycisk działa. Podpowiedzcie mi jednak czy nawet ten mały delay nie zaszkodzi przy uruchomieniu drugiego silnika np. z inną szybkością.
 
Odpowiedź
#5
A kto ma wiedzieć co napiszesz dalej jak nie ty? W tej chwili masz prędkość 500 kroków na sekundę więc de fakto z tym delay wychodzi 375 krokow na sekundę.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#6
(25-06-2024, 12:12)anszun napisał(a): Zmniejszyłem delay do  1.  Rzeczywiście teraz kręci dobrze i przycisk działa. Podpowiedzcie mi jednak czy nawet ten mały delay nie zaszkodzi przy uruchomieniu drugiego silnika np. z inną szybkością.

Nie znam działania użytej biblioteki, ale zgaduje, że ta funkcje runSpeed może być wołana dowolnie często, im częściej tym lepiej. Ona sama pewnie jest szybka - tj. liczy co musi i jeśli potrzebuje to zmienia coś w sterowaniu silnikiem. Na nic nie czeka, nie robi delay-ów. W takim układzie możesz wołać tą funkcje na kilku niezależnych obiektach (silnikach) i każdy będzie działał niezależnie. Wtedy też nie będzie zależności, że jedno wywołanie to 1 krok silnika. Aktualną pozycje silnika/liczbę wykonanych kroków musisz odczytać z obiektu sterującego.

Kod:
void loop()
{
   silnik1.runSpeed();
   silnik2.runSpeed();
   silnik3.runSpeed();
}



By rozstrzygnąć wątpliwości najlepiej poczytać dokumentację biblioteki a jak to nie pomoże to przejrzeć źródła. Jednak analizowanie obcych źródeł jest dość trudne, czasami łatwiej jest napisać swoje od początku niż wgryzać się w czyiś kod...


Jeśli jednak lubisz analizowanie kodów może zerknij na GRBL - to oprogramowanie to sterownika maszyn CNC (drukarki 3D, graweki itp). Tam to dwa silniki potrafią poprowadzić narzędzie po okręgu co wymaga ciągłej zmiany szybkości i kierunku.


PS. Zerknąłem na dokumentacje - masz tam obiekt MultiStepper, który służy do zsynchnizowanego sterowania wielu silników (kilka obiektów AccelStepper), a sterujesz tym podając "koncowy punkt" który mają osiągnąć. Dla pojedynczego AccelStepper też masz taką opcje (tyle że "jednowymiarową") - nie liczysz kroków tylko podajesz do jakiej pozycji silnik ma się obracać. Aktualną pozycje odczytujesz currentPosition() a ile brakuje do celu distanceToGo().
 
Odpowiedź
#7
Piękne dzięki Kol. oscarX, ale na moim "piaskownicowym poziomie" jestem bardzo zainteresowany tym jak do tego jednego silnika użyć przycisku bez koszmarnego delay. Przyznam, że niewiele jestem w stanie wyczytać z opisu biblioteki, za cienki jeszcze jestem. W przykładach AccelStepper nie udało mi się zauważyć rozwiązania z przyciskiem.
 
Odpowiedź
#8
(25-06-2024, 15:59)anszun napisał(a): Piękne dzięki Kol. oscarX, ale na moim "piaskownicowym  poziomie" jestem bardzo zainteresowany tym jak do tego jednego silnika użyć przycisku bez koszmarnego delay. Przyznam, że niewiele jestem w stanie wyczytać z opisu biblioteki, za cienki jeszcze jestem. W przykładach AccelStepper nie udało mi się  zauważyć rozwiązania z przyciskiem.

Po prostu wywal delay.

Musisz zauważyć, że w tej bibliotece są funkcje różnie działające, które można zastosować w różnym "kontekście". Jedne trzeba wołać jak wykryto przycisk, a inne w samej pętli loop.

Właściwa dokumentacja

Kod:
void loop() {
  long ms = millis();       // To na przyszłość
  int buttonState = digitalRead(BUTTON_PIN);

  // delay(50);   OK wywalamy

  // Sprawdź, czy przycisk został wciśnięty (zbocze narastające)
  if (buttonState == LOW && buttonStatePrevious == HIGH) {
      stepper.moveTo(200);
  }
  buttonStatePrevious = buttonState; // Aktualizacja poprzedniego stanu przycisku

  if (stepper.runSpeed()  == false) // można run(), wynik false jak silnik osiągnął zadaną pozycje
  {
      // Gdy silnik dojdzie do 200 wracamy na początek
      // wiem tak, bedzie pracował raczej ten drugi silnik.
      stepper.MoveTo(0);
  }
}

W tym zastosowaniu ewentualne drgania silnika nie będą miały złych skutków. Pewnie trzeba będzie się tym zająć w przyszłości.

Tak swoją drogą mam właśnie proste urządzenie z dwoma silnikami krokowymi, może zastosuję bibliotekę AccelStepper?
 
Odpowiedź
#9
long ms = millis(); // To na przyszłość
int buttonState = digitalRead(BUTTON_PIN);

// delay(50); OK wywalamy


Zapomniałeś o drgania styków przycisku, delay to niwelował bez tego jedno przyciśniecie może traktować jako wielokrotność.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#10
(25-06-2024, 22:31)Jarewa0606 napisał(a): long ms = millis();      // To na przyszłość
  int buttonState = digitalRead(BUTTON_PIN);

  // delay(50);  OK wywalamy


Zapomniałeś o drgania styków przycisku, delay to niwelował bez tego jedno przyciśniecie może traktować jako wielokrotność.

Jak napisałem pod kodem (nie wiem czemu napisałem "silnika" zamiast "styków") w tym przypadku nie przeszkadza ponieważ wykrycie nacisniecia przycisku tylko ustala końcowe położenie silnika. Ustawienie tego drugi raz na tą samą wartość raz nic nie zmieni.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości