Table of Contents

Servo motor

Conhecimento prévio: [HW] User Interface Module, [HW] Combo module, [AVR] Counters/Timers, [AVR] Analog-to-digital Converter, [LIB] Motors, [LIB] Analog to Digital Converter

Teoria

Servo motor RC
A relação entre a largura do sinal e a posição do Servo PWM.

Servo motores RC (radio-controlled - controlados por rádio) são dispositivos atuadores muito comuns em robótica e construção de modelos. Servo motores RC consistem dum motor DC pequeno, de engrenagens de redução e um dispositivo de controle lógico. Normalmente o rotor do servo-motor move-se para uma determinada posição e tenta manter esta posição. A posição do rotor depende do sinal de controlo recebido pelo servo-motor. 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.

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, cujas funções alternativas são saídas de comparação das unidades do temporizador. O temporizador é capaz de produzir sinal PWM e devido a isso o controlo de motores é muito simples no programa. A única dificuldade é a configuração do temporizador.

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, a frequência exacta de PWM para controlar o servo motor pode ser determinada. Com o registo de comparação do temporizador, comprimentos de ambos os períodos de semi elevadas de sinal PWM podem ser determinados. Os temporizadores têm unidades especiais comparando o que estão monitorizando o valor do contador e, em caso de ele ser igual ao valor da comparação no registo, alteram o valor das unidades de comparação. O seguinte é o código do programa da biblioteca do HomeLab para controle de servo motor. Para a finalidade de funcionalidade, que utiliza parâmetros para temporizadores que são determinados com funções macro. Por exemplo, o período é encontrado utilizando constante F_CPU, que marca a frequência de relógio do microcontrolador. Quando se utilizam macros, não há necessidade de calcular os parâmetros do temporizador para diferentes taxas de relógio e o compilador converte as operações de macros para constantes de qualquer maneira, por isso a memória do programa não cresce e não exige mais tempo. O exemplo a seguir é da biblioteca para HomeLab II (ATmega2561).

// 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      (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)
 
// 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 servomotor_init. O valor da posição do servo motor é obtido a partir do canal do conversor analógico-digital, onde um potenciómetro na placa de sensores está ligado. Para obter a gama de -100% - +100% necessária para o controlo do servo motor metade do máximo (512) é subtraído do valor de ADC e o resultado é dividido por 5. O resultado é de +/- 102, mas pequenas imprecisões não contam porque os servo motores também diferem pela relação do sinal PWM e do ângulo de rotação. Largura do semi-período do sinal PWM em aplicação tem que ser determinado utilizando o método de ensaio e erro. Também os controles remotos de modelos de RC têm oportunidades correspondentes para a instalação precisa (função trim). Quando o programa é iniciado a posição de rotores do servomotor é alterado de acordo com a posição do potenciómetro.

// Testing program of the motors module of the HomeLab kit
#include <homelab/adc.h>
#include <homelab/module/motors.h>
 
// Main program
int main(void)
{
	short position;
 
	// Set-up of the ADC
	adc_init(ADC_REF_AVCC, ADC_PRESCALE_8);
 
	// 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, position);
	}
}