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