Bogusław Kempny

Serwomechanizm SG90

×
Autor adres English
Początek HC-SR04 LCD Kamera fork() sms strfry() GPIO impulsy Klawiatura Brama GPIO PWM SG90 RFID Grafolog RCP Shutdown Temperatura ....











Takie maleństwo. Waży zaledwie 9 gramów, ale moment siły ma całkiem spory, 1,6 kg/cm.

Zasilany jest napięciem 4,8-6V, maksymalny prąd to 800 mA.

Jednak najbardziej może nas zainteresować sterowanie tego serwomechanizmu. Otóż sterowany jest impulsami o modulowanej szerokości.

Mamy trzy wyprowadzenia, zasilanie (czerwony), masę (brązowy) i sterowanie (pomarańczowy. Jeśli na pomarańczowy styk podamy sygnał o okresie 20ms, i jedynką przez 1,5 ms, wałek serwomechanizmu ustawi się w środkowym położeniu. Jeśli jedynka będzie trwała 0,6 ms, przekręci się w prawe skrajne położenie, 2,5 ms - w lewe skrajne.

Wprawdzie producent podaje, ze jedynka logiczna to 5V, ale sygnał z pinu GPIO, 3,3V też działa.

Sygnał jest potrzebny jedynie przez czas niezbędny do wykonania zadanego obrotu, wbudowana czterostopniowa przekładnia powoduje, ze wał serwomechanizmu pozostanie w swoim położeniu nawet po wyłączeniu zasilania, nie przekręci się samoczynnie.

Podłączamy zasilanie, generujemy sygnał PWM, podłączamy do sterowania serwomechanizmu i gotowe. Jak sobie poradzić z PWM w Raspberry, już opisałem, zobacz GPIO PWM , więc skupimy się na sterowaniu samego SG90.

No to podłączamy nasze serwo, pomarańczowy kabelek do pinu 1 GPIO (fizycznie pin 12), brązowy do masy, czerwony do zasilania. Możemy podłączyć czerwony przewód do 5V na łączówce GPIO, jednak ze względu na spory prąd, jaki serwomechanizm może pobrać, nawet 800 mA, lepiej podłączyć bezpośrednio do wyjścia z zasilacza:

Możemy przewód sterujący podłączyć do innego wolnego pinu GPIO, jeśli jednak będziemy używać sprzętowego generatora pwm musi to być jeden z pinów które go obsługują.

Teraz musimy się zająć generowaniem sygnału sterującego. Potrzebujemy przebieg prostokątny, o okresie 20ms i szerokości impulsu pomiędzy 0,5 ms a 25 ms. Przebieg 2,5 ms spowoduje obrót walka serwomechanizmu w skrajne lewe położenie:

1,5 ms ustawi nam wałek w środkowym położeniu:

0,5 ms spowoduje jego przekręcenie maksymalnie w prawo:

Oczywiście impuls o jakiejś innej szerokości, pomiędzy 0,5 i 2,5 ms spowoduje obrót o odpowiadający mu kąt, pomiędzy 0 a 180°. W najprostszym przypadku interesujący nas przebieg prostokątny wygenerować możemy programowo, jak to jest robione w programie serv.c (skrypt do kompilacji cs).

Generuje on sygnał prostokątny programowo odmierzając czas trwania jedynki logicznej i czas trwania przerwy:

for(time=500;time<2500;time=time+STEP)
   {
    printf("%d ms\n", time);fflush(0);
    for(i=0;i<10;i++)
     {
      digitalWrite(1,HIGH);
      Delay(time);
      digitalWrite(1,LOW);
      Delay(PERIOD-time);
     }
    Delay(PAUSE);
   } 
Tworzy sygnał prostokątny o czasie trwania jedynki od 0,5 ms do 2,5 ms zwiększając ten czas co 0,3 s o 0,02 ms.

Jeśli uruchomisz ten program, wał serwomechanizmu będzie się obracał malutkimi skokami, trochę podobnie, jak to robi wskazówka sekundowa w zegarku.

Zaletą takiego programowego rozwiązania jest po pierwsze jego prostota, po drugie jednym Raspberry można sterować nawet 28 serwomechanizmami (tyle jest, jeśli dobrze policzyłem, pinów na łączówce GPIO które możemy ustawić na output).

Niestety sposób ten ma też wadę, która może być istotna jeśli chcemy precyzyjnie i niezawodnie sterować naszym serwomechanizmem.

Czas trwania jedynki logicznej i okres sygnału wyliczane są z rozdzielczością nanosekundową, jednak nasz program działa pod systemem wielozadaniowym.

Nie ma pewności, że w czasie kiedy upłynął precyzyjnie odliczany okres czasu nasz proces akurat jest aktywny. Z dużym prawdopodobieństwem będzie akurat czekał grzecznie w kolejce, aż jądro wylosuje go spośród kilkuset innych, również czekających.

W efekcie zamiast spodziewanego impulsu np. 1,25 ms pojawi się 1,31. Serwomechanizm oczywiście zacznie posłusznie przestawiać wałek do położenia odpowiadającego impulsowi 1,31 ms.

Jeśli uruchomisz program serv.c, z pewnością zaobserwujesz, że wał serwomechanizmu czasami zachowuje się jakby napadła go czkawka.

Rozwiązaniem problemów wiązanych z niedokładnościami opisanymi na poprzedniej stronie jest użycie sprzętowego generatora PWM, w który uzbrojony jest nasz komputerek Raspberry.

Użyjemy testowego programu servp.c (skrypt do kompilacji csp).

Program ten steruje serwomechanizmem pokazanym na filmiku na pierwszej stronie tego opisu.

Jeśli pominąć niuanse związane z samym pwm, jest bardzo prosty.

Programujemy kanał pwm, zegar 0,1 ms, okres 20 ms:

  pinMode(1, PWM_OUTPUT);
  pwmSetMode(PWM_MODE_MS);
  pwmSetClock(1920);
  pwmSetRange(200);
Dwukrotnie poruszamy wałkiem od jednego skrajnego położenia do drugiego, zatrzymując się pośrodku:
  for(i=0;i<2;i++)
    {
     pwmWrite(1,6);
     sleep(1);
     pwmWrite(1,15);
     sleep(1);
     pwmWrite(1,25);
     sleep(1);
     pwmWrite(1,15);
     sleep(1);
    }
Teraz obracamy wał serwomechanizmu od jednego skrajnego położenia do drugiego zwiększając czas trwania jedynki logicznej skokowo co 0,1 ms (9°). Po każdym przeprogramowaniu generatora (pwmWrite(1,i);) w prostej pętli odliczamy niewielkie opóźnienie, żeby serwomechanizm zdążył obrócić wałek:
    for(i=6;i<26;i++)
      {
       pwmWrite(1,i);
       for (j=0;j<30000000;j++);
      }