This is an old revision of the document!
Necessary knowledge: [HW] Motor Module, [HW] Sensors Module, [AVR] Digital Inputs/Outputs, [LIB] Motors, [LIB] Analog to Digital Converter
Servo motors are often used in radio-controlled (RC) models, and are very useful in many kinds of small robotics applications because they are compact and inexpensive. An RC servo motor includes a built-in DC motor, gearbox, position feedback sensor (usually potentiometer), and drive electronics. RC servo motors can be controlled by an external pulse-width modulation (PWM) signal. If a signal meets RC servo timing requirements, it usually “describes” a (target) position input for the servo drive electronics. Servo motor electronics compare the shaft position with the inputted position, trying to find a shaft position where they match. The position control signal is a continuous square-wave signal, as depicted in figure.
RC (radio-controlled) servo-motors are very common actuator devices in robotics and model building. RC servo motors are consisting of a small DC motor, reduction gear and control logic device. Usually the rotor of the servo motor moves to a certain position and tries to maintain that position. The position of the rotor depends of the control signal received by the servo motor. Depending on the type of the motor, the maximum revolving angle of the motor may differ. Servo motors that revolve constantly are rare. In this case, the control signal determines not the revolving angle but the speed of revolving. Servo motor “hack” is also quite common. This makes the position determining servo motor to constantly revolving servo. In this case the feedback potentiometer is replaced by two fixed resistors and the mechanical resistor that prevents full rotations is removed from the gear. A very important characteristic of servo motors is its power-weight ratio
The controlling signal of servo motor is specific pulse with modulated signal (PWM), where with of the pulse determines the position of the rotor. The period of the signal is 20 ms (50 Hz) and the with of the high period is 1 ms – 2 ms. 1 ms marks one extreme position and 2 ms marks the second one. 1,5 ms marks the middle position of the servo motor’s rotor.
Traditional RC servo motor is also known as analogue-servo motor. It is because in the last decade so called digital servo motors were becoming common. The difference between those two is that is analogue servo motor the motor is controlled with the same 50 Hz PWM input signal. In digital servo motor the motor is controlled by a micro controller with much higher frequency signal. The input signal is the same in the digital servo motor but higher modulation frequency of the motor enables much more precise and faster position determining.
On the board of module of motors of the home-lab are two plugs for connecting RC servo motors. The PWM ends of the plugs are connected to the PB5 and PB6 pins of the micro controller, which’s alternative functions are outputs of comparing units A and B of the timer 1. Timer 1 is capable of producing PWM signal and due to that the control of motors is very simple in the program. Only difficulty is setup of the timer.
The timer 1 must be set up in PWM production mode, where the maximum value of the timer is determined with ICR register. With the maximum value changed in the program and in the pace divider (taktijagur?) of the timer, the precise PWM frequency for controlling the servo motor con be determined. With the comparison register of the timer, lengths of both high semi periods of PWM signal can be determined. The timers have special comparing units which are monitoring the value of the counter and if it remains equal with the value of the comparison register then they change the output value of comparing units. The following is the program code of the servo motor control library of the home-lab. For the purpose of functionality, it uses parameters for timers which are determined with macro functions. For example, the period is found using F_CPU constant, which marks the clock rate of the micro controller. When using macros, there is no need to calculate the parameters of timer for different clock rates and the compiler converts the operations with macros to constants anyway, so the program memory is not growing and does not demand more time.
// // The value of the timer (20 ms)for achieving the full period of PWM. // F_CPU is the clock rate of the micro controler which is divided with 50 Hz and 8. // // #define PWM_PERIOD (F_CPU / 8 / 50) // // Middle position of PWM servo (5 ms / 20 ms) // Middle position is 15/200 of full period. // #define PWM_MIDDLE_POS (PWM_PERIOD * 15 / 200) // // Factor for converting the percents (-100% to 100%)to periods. // +1 is added to ensure that semi periods would reach to the boundaries of 1 ms and 2 ms or // a little over. // #define PWM_RATIO (PWM_PERIOD / 20 / 2 / 100 + 1) // // Setup of the pins. // static pin servo_pins[2] = { PIN(B, 5), PIN(B, 6) }; // // Prepearing the servo motor for working. // void servomotor_init(unsigned char index) { // The pin of PWM signal for output. pin_setup_output(servo_pins[index]); // Setup of timer 1. // Pace divider (taktijagur?) 8 // Fast PWM mode, where TOP = ICR // OUTA and OUTB to low in comparisson. timer1_init_fast_pwm( TIMER1_PRESCALE_8, TIMER1_FAST_PWM_TOP_ICR, TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, TIMER1_FAST_PWM_OUTPUT_DISABLE); // Determining the period by maximum value. timer1_set_input_capture_value(PWM_PERIOD); } // // Determining the position of the servo motor. // The parameter of the position is from -100% to +100%. // void servomotor_position(unsigned char index, signed short position) { switch (index) { case 0: timer1_set_compare_match_unitA_value( PWM_MIDDLE_POS + position * PWM_RATIO); break; case 1: timer1_set_compare_match_unitB_value( PWM_MIDDLE_POS + position * PWM_RATIO); break; } }
Näiteprogramm kasutab kirjeldatud kodulabori teegi funktsioone. Programmi alguses pannakse esimese servomootori PWM signaali? generaator tööle? servomotor_init funktsiooniga. Servomootori asendi väärtus saadakse analoog-digitaalmuunduri kanalist 3, kuhu on andurite plaadil ühendatud potentsiomeeter. Et servomootori juhtimiseks vajalikku -100 kuni 100 vahemikku saavutada, lahutatakse ADC väärtusest pool maksimumi (ehk 512) ja jagatakse viiega. Tulemuseks on küll ±102, kuid pisike ebatäpsus ei loe, sest servomootorid ise ka erinevad PWM signaali ja pöördenurga suhtelt. Lõplikult tuleb rakendustes PWM poolperioodi laius siiski katse- ja eksitusmeetodil määrata. Ka raadiojuhitavate mudelite pultidel on täpseks seadistuseks vastavad võimalused. Programmi käivitades muutub vastavalt potentsiomeetri asendile ka servomootori rootori asend.
// // Kodulabori mootorite mooduli servomootori // testprogramm. // #include <homelab/adc.h> #include <homelab/module/motors.h> // // Põhiprogramm // int main(void) { short position; // ADC seadistamine adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Mootori seadistamine servomotor_init(0); // Lõputu tsükkel while (true) { // Potentsiomeetrist positsiooni lugemine ja servo- // mootori piirkonda teisendamine position = ((short)adc_get_value(3) - (short)512) / (short)5; // Servomootori positsiooni määramine servomotor_position(0, position); } }