This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| pt:examples:motor:servo [2015/12/14 17:34] – Criação deste novo documento. artica | pt:examples:motor:servo [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Servo motor ====== | ||
| + | // | ||
| + | [HW] [[en: | ||
| + | [AVR] [[en: | ||
| + | [LIB] [[en: | ||
| + | |||
| + | ===== Teoria ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | Servo motores RC (// | ||
| + | |||
| + | O sinal de controlo de servo motor é de largura de pulso modulada específica (PWM), nas quais a largura do impulso determina a posição do rotor. O período do sinal é de 20 ms (50 Hz) e a largura do período alto é de 1 ms - 2 ms. 1 ms marca uma posição extrema e 2 ms marca a segunda. 1,5 ms marca a posição do meio do rotor do servo motor. | ||
| + | |||
| + | Servo motor RC tradicional também é conhecido como servo motor analógico. Isto é devido a durante última década os chamados servo motores digitais se terem tornando comuns. A diferença entre os dois é que no servo motor analógico o motor é controlado pelo mesmo sinal de entrada 50 Hz PWM. No servo motor digital, o motor é controlado por um microcontrolador com sinal de frequência muito mais elevada. O sinal de entrada é o mesmo em que o motor servo digital, mas a mais elevada frequência de modulação do motor permite uma posição muito mais precisa e de mais rápida determinação. | ||
| + | |||
| + | ===== Prática ===== | ||
| + | |||
| + | Na placa do módulo de motores da HomeLab encontram-se duas ou quatro fichas para conexão dos servo motores RC. As extremidades de PWM das fichas são ligadas aos pinos do microcontrolador, | ||
| + | |||
| + | O temporizador deve ser configurado no modo de produção PWM, onde o valor máximo do temporizador é determinado com registo ICR. Com o valor máximo alterado no programa e no divisor de ritmo do temporizador, | ||
| + | |||
| + | <code c> | ||
| + | // The value of the timer (20 ms)for achieving the full period of PWM | ||
| + | // F_CPU is the clock rate of the microcontroller which is divided with | ||
| + | // 50 Hz and 8 | ||
| + | #define PWM_PERIOD | ||
| + | |||
| + | // Middle position of PWM servo (5 ms / 20 ms) | ||
| + | // Middle position is 15/200 of full period | ||
| + | #define PWM_MIDDLE_POS | ||
| + | |||
| + | // 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 | ||
| + | |||
| + | // Set-up of the pins | ||
| + | static pin servo_pins[2] = | ||
| + | { | ||
| + | PIN(B, 5), PIN(B, 6) | ||
| + | }; | ||
| + | |||
| + | // Preparing 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 | ||
| + | // Prescaler = 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; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | O programa de exemplo usa funções descritas da biblioteca do HomeLab. No início do programa gerador de sinal do PWM do primeiro servo motor é iniciado com a função // | ||
| + | |||
| + | <code c> | ||
| + | // Testing program of the motors module of the HomeLab kit | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | short position; | ||
| + | |||
| + | // Set-up of the ADC | ||
| + | adc_init(ADC_REF_AVCC, | ||
| + | |||
| + | // Set-up of the motor | ||
| + | servomotor_init(1); | ||
| + | |||
| + | // Endless loop | ||
| + | while (1) | ||
| + | { | ||
| + | // Reading the position of the potentiometer and | ||
| + | // converting the range of | ||
| + | // the servo motor | ||
| + | // For HomeLab II ADC must be read for the corresponding channel, | ||
| + | // and use the following formula: | ||
| + | // position = ((short)adc_get_value(3) - (short)512) / (short)5; | ||
| + | position = ((short)adc_get_value(15) / 10) - 102 ; | ||
| + | |||
| + | // Determining the position of the servo motor | ||
| + | servomotor_position(1, | ||
| + | } | ||
| + | } | ||
| + | </ | ||