• 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
Sterowanie servo za pomocą PWM
#1
Lightbulb 
Witam,
pracuję nad oprogramowaniem do sterowania serwomechanizmem pozycyjnym za pomocą PWM. Według teorii w celu ustawienia servo na danej pozycji należy wygenerować impuls prostokątny o łącznym czasie trwania jednego impulsu 20ms i w zależności od kąta obrotu poziom wysoki powinien trwać odpowiednio:
- dla 0[stopni] - 1ms,
- dla 90[stopni] - 1,5ms,
- dla 180[stopni] - 2ms.
Problem pojawia się, że dla wyżej wyznaczonych czasów servo ustawia się na innych pozycjach odpowiednio:
- dla 1ms - 45[stopni],
- dla 1,5ms - 90[stopni],
- dla 2ms - 125[stopni].
Oczywiście metodą prób i błędów jestem w stanie tak dobrać czas trwania impulsu aby servo pracowało w pełnym zakresie 0-180[stopni] ale chciałbym usłyszeć opinię bardziej doświadczonych osób co o tym sądzą.

Poniżej fragment kodu:
Kod:
void setup()
{
  pinMode(3, OUTPUT);
}

void loop()
{
  for(int i = 0; i <= 100; i++){     //pętla umożliwiająca ustawienie odpowiedniej pozycji
    digitalWrite(3, HIGH);            //stan wysoki
    delayMicroseconds(1000);        //czas trwania stanu wysokiego
    digitalWrite(3, LOW);    //stan niski
    delayMicroseconds(19000);          //czas trwania stanu niskiego
    delay(10);                                //opóźnienie w celu spowolnienia ruchu
  }
  delay(1000);                                //opóźnienie przed ruchem do kolejnej pozycji
  for(int i = 0; i <= 100; i++){
    digitalWrite(3, HIGH);
    delayMicroseconds(2000);
    digitalWrite(3, LOW);
    delayMicroseconds(18000);
    delay(10);
  }
  delay(1000);
  for(int i = 0; i <= 100; i++){
    digitalWrite(3, HIGH);
    delayMicroseconds(1500);
    digitalWrite(3, LOW);
    delayMicroseconds(18500);
    delay(10);
  }
  delay(1000);
}


Załączone pliki
.txt   servo_PWM.txt (Rozmiar: 874 bajtów / Pobrań: 1)
 
Odpowiedź
#2
(18-12-2023, 20:30)makuban napisał(a): Poniżej fragment kodu:
Kod:
  for(int i = 0; i <= 100; i++){     //pętla umożliwiająca ustawienie odpowiedniej pozycji
    digitalWrite(3, HIGH);            //stan wysoki
    delayMicroseconds(1000);        //czas trwania stanu wysokiego
    digitalWrite(3, LOW);    //stan niski
    delayMicroseconds(19000);          //czas trwania stanu niskiego
    delay(10);                                //opóźnienie w celu spowolnienia ruchu
  }

W jakim celu na końcu for-a jest to delay(10), przecież to się po prostu dodaje do poprzedniego delayMicroseconds i razem zamiast 20ms okresu masz 30, stąd wypełnienie jest mniejsze. Nie wiem czy serwa reagują na samą długość impulsu, czy na współczynnik wypełnienia. Na pewno na impulsy o istotnie innej częstotliwości mogą w ogóle nie zareagować.

Po drugie - te impulsu mają przychodzić cały czas, nie tylko w czasie zmiany pozycji. Serwo ciągle porównuje impulsy wejściowe z położeniem i dokonuje korekty jeśli coś się poruszy. Przypuszczam, że gdy brakuje impulsów silnik zostaje odłączony i nie ma aktywnego ustawiana pozycji.
 
Odpowiedź
#3
Jak nie robisz z tego doktoratu to w Arduino są do tego gotowe funkcje biblioteki, każdy timer ma dedykowane piny do PWM.
Delayami nie ustawisz dokładnie czasu, bo to jest funkcja, której wywołanie też coś trwa, a po to są timery z PWM by robić to "w tle" niezależnie od tego co robi się w programie.
http://akademia.nettigo.pl/serwomechanizm/
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości