6.08.2015

Serwo Tower Pro SG90

Tower Pro SG-90 to małe, lekkie i przede wszystkim tanie, uniwersalne serwo. Bez problemu da się podłączyć do STM32F4Discovery. Urządzenie ma 3 przewody połączeniowe: brązowy, czerwony i żółty. Brązowy podłączamy do masy (GND), czerwony do zasilania (+5V), a żółty do wyjścia PWM na płytce. Ja wybrałem wyjście PWMChannel.PWM_0 (czyli pin PD12 - zielona dioda LED).
Tower Pro SG90

Sterowanie kątem obrotu odbywa się poprzez zmianę szerokości impulsu na wejściu PWM. Według dokumentacji częstotliwość sygnału sterującego powinna wynosić 50Hz (okres 20ms), natomiast szerokość impulsu dla wychyleń -90..+90 stopni powinna zawierać się w przedziale: 1ms..2ms. Po zbadaniu skrajnych położeń orczyka wyszło mi, że szerokość impulsu powinna być z przedziału 0.53ms..2.35ms. Do takiego sterowania nadaje się drugi sposób regulacji parametrów PWM: zmiana właściwości Period (czas jednego okresu sygnału) oraz Duration (czas trwania stanu wysokiego). Poniżej kot, który wychyla orczyk do skrajnych położeń:

public static void Main()
{
    const uint period = 20000;    //20ms in us
    const uint minDuration = 530; //0.53ms in us
    const uint maxDuration = 2350;//2.35ms in us
    const uint midDuration = minDuration + (maxDuration - minDuration)/2;

    var servo = new PWM(Cpu.PWMChannel.PWM_0, period, minDuration,
                        PWM.ScaleFactor.Microseconds, false);
    servo.Start();

    for (;;)
    {
        servo.Duration = minDuration;
        Thread.Sleep(2000);

        servo.Duration = midDuration;
        Thread.Sleep(2000);

        servo.Duration = maxDuration;
        Thread.Sleep(2000);

        servo.Duration = midDuration;
        Thread.Sleep(2000);
    }
}

Jeśli byśmy chcieli sterować kątem obrotu podając stopnie, to przyda się jedna bardzo fajna funkcja z Arduino. Funkcja "map":

static uint Map(uint x, uint minX, uint maxX, uint outMin, uint outMax)
{
    return (x - minX)*(outMax - outMin)/(maxX - minX) + outMin;
}

A użyć jej możemy tak (orczyk zmienia położenie co 30 stopni):

public static void Main()
{
    const uint period = 20000; //20ms in us
    const uint minDuration = 530; //0.53ms in us
    const uint maxDuration = 2350; //2.35ms in us

    var servo = new PWM(Cpu.PWMChannel.PWM_0, period, minDuration,
                        PWM.ScaleFactor.Microseconds, false);
    servo.Start();

    uint step = 30;
    for (uint angle = 0;; angle += step)
    {
        if (angle > 180)
        {
            step = (uint) -step;
            continue;
        }

        servo.Duration = Map(angle, 0, 180, minDuration, maxDuration);
        Thread.Sleep(2000);
    }
}

Brak komentarzy:

Prześlij komentarz