• 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
Camera Slider sterowany przez Bluetooth
#11
Popatrz jeszcze na przykłady tej biblioteki do stepper, tak to nie będzie dobrze działać, jeśli np. ustalisz że krokowiec 1 ma zrobić 5000 kroków to on będzie je robił aż skończy, przecież jest komentarz //blokuje dopóki wszystkie krokowce są na pozycji. I tak dobrze, że wszystkie, nie ten jeden. Nie zatrzymasz ich pracy w tym czasie, nie zamigasz ledem, nie odbierzesz nowej pozycji.
Krokowce nie jeżdżą tak jak chcesz bo źle im podajesz pozycje, przypisujesz wartości do tablicy na pozycjach [0] i [1] a potem piszesz steppersControl.moveTo(gotoposition);, gotopozsition jest nazwą tablicy, czyli wskaźnikiem na adres w pamięci.
Tak czy inaczej zobacz inne przykłady, np. DualMotorShield, w tym przykładzie jest używana metoda .run() i sprawdzanie pozycji, ale loop cały czas działa, możesz migać ledami (byle bez delay) i odbierać polecenia, parsować, zmieniać cele krokowca.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#12
Andrzejn, zajrzyj jeszcze do wątku z tą samą biblioteką, może się przyda.
 
Odpowiedź
#13
No i wreszcie się udało! 
Chciałbym serdecznie wszystkim podziękować. Każda Wasza uwaga jest dla mnie bezcenna, bowiem bardzo wiele mnie nauczyła.
Problem tkwił (zgodnie z sugestią oscarX) w umiejscowieniu ustawienia parametrów prędkości. Przeniosłem je do pętli loop() i zaskoczyło. Nie wiem, czy z punktu widzenia poprawności programowania jest to właściwe, ale działa.
Jest jednak w tej beczce miodu łyżka dziegciu. Otóż zestaw danych mogę wprowadzić tylko raz. By wprowadzić ponownie dane muszę zresetować Arduino. Jak temu zaradzić?
Oto działąjący kod:

Kod:
//#include <String.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#define buffsize 64

char input[buffsize];
uint16_t dane [4]; // jakie i ile  zmiennych odbieramy z UART
byte index = 0;
boolean stringComplete = false;  // gdy cale polecenie/napis odebrany

long Lkp;
int Lko ;
int Prp;
int Pro;


AccelStepper stepper1 (1, 2, 5); //shield V3
AccelStepper stepper2 (1, 3, 6);
const int enablePin1 = 8; // Steruje wyłączaniem sterowników
const int enablePin2 = 8;
MultiStepper steppersControl; 
long gotoposition[3];

void   parsujpolecenia()
  {
    /*polecenie ma wygladac tak: cmd=zmienna1,zmienna2,zmienna3,zmienna4  z zalozenia sa to 4 liczby calkowite
     do 5 cyfr, dlatego buffsize32 ma zapas, dla innych trzeba zmodyfikowac bufor, tablice zmiennych, funkcje
     do konwersji napisu na liczby
     cmd=234,342,553,3432*/
   
     uint8_t index=0;
    char * polecenie=input;
    Serial.print("Otrzymane polecenie: ");
    Serial.println(polecenie);

    char* command1 = strtok(polecenie, "=");

if (strcmp(command1 , "cmd")==0)
{
    while ((command1 = strtok(NULL, ",")) != NULL)
    {
        // Znajdź następne polecenie w ciągu wejściowym
        dane[index++]=atoi(command1); //konwersja napisu na INT i zapisanie do kolejnej pozycji w tablicy
        if (index == (sizeof(dane)/sizeof(dane[0])))
            break;
}
   Lkp = dane[0];
   Lko = dane[1];
   Prp = dane[2];
   Pro = dane[3];
}
  else   
  Serial.println("Polecenie nieprawidlowe");
  Serial.println("Aktualne parametry:");
  Serial.print(" Lkp = ");
  Serial.println(Lkp);
  Serial.print(" Lko = ");
  Serial.println(Lko);
  Serial.print(" Prp = ");
  Serial.println(Prp);

  Serial.print(" Pro = ");
  Serial.println(Pro);

    stringComplete = false;
  }
  // Arduino initialization function.
void setup()
{
  Serial.begin(9600);

  pinMode(enablePin1,OUTPUT);
  pinMode(enablePin2,OUTPUT);

/* stepper1.setMaxSpeed(2000);
  stepper2.setMaxSpeed(1000);
  steppersControl.addStepper(stepper1);
  steppersControl.addStepper(stepper2);
  */
}
void loop()
{
  while (stringComplete == 0)
   
        serialEvent();
    parsujpolecenia();

    // Teraz mozna cos zrobic ze zmiennymi
 
  stepper1.setMaxSpeed(Prp);
  stepper2.setMaxSpeed(Pro);
  steppersControl.addStepper(stepper1);
  steppersControl.addStepper(stepper2);
 
    pan();
}
void serialEvent() {
  while (Serial.available()>0) {
char aChar = Serial.read();
     if(aChar == '\n')
     {
       // wykryto znak konca linii \n, koniec odbioru
       input[index] = 0;
       index = 0;
       stringComplete = true;
     }
     else
     {
        input[index] = aChar;
        if(index<buffsize) index++;
        input[index] = '\0'; // Na koncu napisu wstawiamy 0   
     }
  }
}
void pan()
{   
  gotoposition[0] = Lkp;  // 800 steps - full rotation with quater-step resolution
  gotoposition[1] = Lko;

  steppersControl.moveTo(gotoposition); // Calculates the required speed for all motors
  steppersControl.runSpeedToPosition(); // Blocks until all steppers are in position
}
 
Odpowiedź
#14
(27-10-2024, 14:30)andrzejn napisał(a): No i wreszcie się udało! 
Chciałbym serdecznie wszystkim podziękować. Każda Wasza uwaga jest dla mnie bezcenna, bowiem bardzo wiele mnie nauczyła.
Problem tkwił (zgodnie z sugestią oscarX) w umiejscowieniu ustawienia parametrów prędkości. Przeniosłem je do pętli loop() i zaskoczyło. Nie wiem, czy z punktu widzenia poprawności programowania jest to właściwe, ale działa.
Jest jednak w tej beczce miodu łyżka dziegciu. Otóż zestaw danych mogę wprowadzić tylko raz. By wprowadzić
ponownie dane muszę zresetować Arduino. Jak temu zaradzić?Proponuje następujące zmiany

1. przeniesienie setSpeed do funkcji pan
2. w tej chwili wielokrotnie dodajesz stepper do multi - to powinno być raczej jeden raz.
3. Multistepper działa ze stałą szybkością - więc pewnie ważne jest ustawienie setSpeed (czyli tej stałej szybkości)
   a nie setMaxSpeed (to jest ten limit dla stopniowego przyspieszania)

Poniższy kod to tylko te zmienione funkcje - reszta pozastaje bez zmian.
Kod:
  // Arduino initialization function.
void setup()
{
  Serial.begin(9600);

  pinMode(enablePin1,OUTPUT);
  pinMode(enablePin2,OUTPUT);

  // Tu zostaje
  steppersControl.addStepper(stepper1);
  steppersControl.addStepper(stepper2);
}
void loop()
{
  while (stringComplete == 0)
  
        serialEvent();
    parsujpolecenia();

    // Teraz mozna cos zrobic ze zmiennymi
 
    pan();
}
void pan()
{   
  gotoposition[0] = Lkp;  // 800 steps - full rotation with quater-step resolution
  gotoposition[1] = Lko;


  steppersControl.moveTo(gotoposition); // Calculates the required speed for all motors
  stepper1.setSpeed(Prp);
  stepper2.setSpeed(Pro);
  steppersControl.runSpeedToPosition(); // Blocks until all steppers are in position
}



Jednak nie jestem pewny, czy z multistepper to zadziała - ja bawiłem się silnikami pojedynczo.

Powyższy kod powinien przyjąć kolejne polecenie bez restartowania, jednak wykona go dopiero po zakończeniu zakończeniu poprzedniego ruchu. Jedno polecenie - jeden przebieg funkcji loop().
Nie ma możliwości przerwania trwającego ruchu - więc jak się pomylisz i dasz np. bardzo małą prędkość to będziesz musiał czekać.
By to zmienić trzeba by przejść na ruch asynchroniczny lub jakieś przerwania.
 
Odpowiedź
#15
Może w końcu potwierdzisz jakiej płytki używasz, jeśli serial event nie działał to zapewne ESP, ale może powód był inny?
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#16
Niestety, nadal bez resetu kontrolera nie można przesłąć nowego zestawu danych. 
Przy ustawieniach setSpeed biblioteka Multistepper nie działa. Ustawienia setMaxSpeed jest OK. Praktycznie nie zauważyłem jakiegokolwiek przyspieszenia.
Ale pojawiło się nowe kuriozum, które zwaliło mnie z nóg. Aby zmienić kierunek obrotu silnika w Multistepper  należy gotoposition[0] podać ze znkiem "-". Zmienną Lkp mam ustawiną jako long. Gdy przesyłam taką komendę "cmd=64000,4800,6400,480\n" wszystko pięknie pracuje. Ustawienie pierwszej pozycji na "-64000" powoduje, że wartość zmiennej przypisanej do tej pozycji wynosi Lkp=1536. Tak się nie dzieje gdy pozycja druga jest ujemna. Wartość drugiej zmiennej Lko jest zawsze poprawnie pokazywana ze znakiem "-".
Próbowałem jeszcze tak: 
int Lkp;
Lkp=dane[0]*100; a wprowadzona wielkość to 640. Kaszana taka sama tylko inną wartość zmiennej pokazuje.


Kod:
//#include <String.h>
#include <AccelStepper.h>
#include <MultiStepper.h>
#define buffsize 64

char input[buffsize];
uint16_t dane [4]; // jakie i ile  zmiennych odbieramy z UART
byte index = 0;
boolean stringComplete = false;  // gdy cale polecenie/napis odebrany

long Lkp;
int Lko ;
int Prp;
int Pro;


AccelStepper stepper1 (1, 2, 5); //shield V3
AccelStepper stepper2 (1, 3, 6);
const int enablePin1 = 8; // Steruje wyłączaniem sterowników
const int enablePin2 = 8;
MultiStepper steppersControl; 
long gotoposition[3];

void   parsujpolecenia()
  {
    /*polecenie ma wygladac tak: cmd=zmienna1,zmienna2,zmienna3,zmienna4  z zalozenia sa to 4 liczby calkowite
     do 5 cyfr, dlatego buffsize32 ma zapas, dla innych trzeba zmodyfikowac bufor, tablice zmiennych, funkcje
     do konwersji napisu na liczby
     cmd=234,342,553,3432*/
   
     uint8_t index=0;
    char * polecenie=input;
    Serial.print("Otrzymane polecenie: ");
    Serial.println(polecenie);

    char* command1 = strtok(polecenie, "=");

if (strcmp(command1 , "cmd")==0)
{
    while ((command1 = strtok(NULL, ",")) != NULL)
    {
        // Znajdź następne polecenie w ciągu wejściowym
        dane[index++]=atoi(command1); //konwersja napisu na INT i zapisanie do kolejnej pozycji w tablicy
        if (index == (sizeof(dane)/sizeof(dane[0])))
            break;
}
   Lkp = dane[0];
   Lko = dane[1];
   Prp = dane[2];
   Pro = dane[3];
}
  else   
  Serial.println("Polecenie nieprawidlowe");
  Serial.println("Aktualne parametry:");
  Serial.print(" Lkp = ");
  Serial.println(Lkp);
  Serial.print(" Lko = ");
  Serial.println(Lko);
  Serial.print(" Prp = ");
  Serial.println(Prp);

  Serial.print(" Pro = ");
  Serial.println(Pro);

    stringComplete = false;
  }
  // Arduino initialization function.
void setup()
{
  Serial.begin(9600);

  pinMode(enablePin1,OUTPUT);
  pinMode(enablePin2,OUTPUT);
  steppersControl.addStepper(stepper1);
  steppersControl.addStepper(stepper2);

/* stepper1.setMaxSpeed(2000);
  stepper2.setMaxSpeed(1000);
  steppersControl.addStepper(stepper1);
  steppersControl.addStepper(stepper2);
  */
}
void loop()
{
  while (stringComplete == 0)
   
        serialEvent();
    parsujpolecenia();

    // Teraz mozna cos zrobic ze zmiennymi
 
 
 
 
    pan();
}
void serialEvent() {
  while (Serial.available()>0) {
char aChar = Serial.read();
     if(aChar == '\n')
     {
       // wykryto znak konca linii \n, koniec odbioru
       input[index] = 0;
       index = 0;
       stringComplete = true;
     }
     else
     {
        input[index] = aChar;
        if(index<buffsize) index++;
        input[index] = '\0'; // Na koncu napisu wstawiamy 0   
     }
  }
}
void pan()
{   
  stepper1.setMaxSpeed(Prp);
  stepper2.setMaxSpeed(Pro);
  gotoposition[0] = Lkp;  // 800 steps - full rotation with quater-step resolution
  gotoposition[1] = Lko;

  steppersControl.moveTo(gotoposition); // Calculates the required speed for all motors
  steppersControl.runSpeedToPosition(); // Blocks until all steppers are in position
}
 
Odpowiedź
#17
Jaki uC?
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#18
Wydaje mi się, iż dlatego wymagany jest reset, gdyż funkcja pan() nie kończy się mimo uzyskania przez silniki docelowych pozycji. Zauważyłem także, że grzeją się stepsticki.
Po wprowadzeniu takiej modyfikacji i wybraniu opcji "1" możliwe jest ponowne wysłanie danych. 
Kod:
void loop()
{
  while (stringComplete == 0)
   
        serialEvent();
    parsujpolecenia();

    // Teraz mozna cos zrobic ze zmiennymi
 

  switch (a)
   {
    case 0:
     pan();
     
      break;
    case 1:
   timelaps(); //gdzie timelaps() to np Serial.print ("x")
      break;
   
  }
}
 
Odpowiedź
#19
Jaki używasz uC, jaka płytka? Czy Ty w ogóle czytasz co tu piszemy?
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#20
Co to jest uC? Używam Uno. Wszystko co piszecie czytam bardzo wnikliwie. Pewnie gorzej jest ze zrozumieniem.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości