Servo tutorial

From Miosix Wiki
Jump to navigation Jump to search

Include statements and namespace required to use this library

#include "drivers/servo_stm32.h"
using namespace miosix;

This is a C++ library, it cannot be used from a C source file.

A servomotor is a device that allows to control the angular position of a shaft, like this one. Servos work by reading a PWM signal with a fixed frequency, 50Hz by default, and a pulse period proportional to the desired angle.

Supported boards

Miosix has a servo library that supports some boards using STM32 microcontrollers, namely the stm32f100rb_stm32vldiscovery and stm32f407vg_stm32f4discovery.

GPIO connection

The library supports up to 4 servo outputs, that must be connected to the following GPIOs (that the library configures as TIMER alternate function when the output is enabled).

  • PB6 is the output 0
  • PB7 is the output 1
  • PB8 is the output 2
  • PB9 is the output 3

Library use

The library is a C++ class named SynchronizedServo. It is a singleton, so to instantiate it you have to call the instance() member function.

You can find examples on how to use the library in the miosix/_examples/servo directory of the kernel.

Closed loop control support

If there is the need to run a closed loop control code using the servo as an actuator, the library supports a way to synchronize the controller with the servo waveform generation, using the waitForCycleBegin() member function in a loop. The value set with setPosition() will be output at the next cycle, so take into account the existence of a z^-1 in your plant model.

#include <stdio.h>
#include "drivers/servo_stm32.h"
using namespace miosix;

int main()
{
    SynchronizedServo& servo=SynchronizedServo::instance();
    servo.enable(0); //Enable channel 0 (connect servo to PB6)
    servo.start();
    for(;;)
    {
        //This loop will be executed 50 times a second, and be synchronized with the waveform generation
        servo.waitForCycleBegin();
        float pos=computeServoPosition();
        servo.setPosition(0,pos);
    }
}

Thread safety considerations

The waitForCycleBegin() member function can be called by only one thread at a given time, so if you want to control more than one servo, be sure to put all the control code into only one loop. The other member functions are thread safe.