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).
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