Table of Contents

Серводвигатель

Необходимые знания: [HW] Mootorite moodul, [HW] Andurite moodul, [AVR] Digitaalsed sisendid-väljundid, [AVR] Loendurid/Taimerid, [LIB] Mootorid, [LIB] Analoog-digitaalmuundur

Теория

RC серводвигатель
Взаимосвязь между шириной сигнала PWM и положением рычага находящегося на валу.

RC (сокращение, на английском языке radio-controlled) серводвигатель - широко распространенный в моделизме и роботике исполнительный механизм, который состоит из маленького двигателя постоянного тока, зубчатого редуктора и управляющей логики. Ротор серводвигателя, как правило, двигается в какое-то определенное положение и пытается это положение постоянно удерживать. Положение ротора зависит от управляющего сигнала, переданного серводвигателю. В зависимости от типа двигателя, максимальный угол поворота может быть разным. Реже встречаются серводвигатели с постоянным вращением. В таком случае управляющий сигнал определяет не положение ротора, а скорость вращения. Распространена так же практика, когда серводвигатель, который определяет положение, переделывают в постоянно вращающийся. По существу, это означает, что дающий из положения ротора обратную связь потенциометр заменяется на два фиксированных резистора и от зубчатого колеса удаляется ограничивающий полное вращение механизм. Один из важных признаков серводвигателя является хороший вес и мощность.

Управляющим сигналом серводвигателя является специфический сигнал широтно-импульсной модуляции (PWM), где длительность импульса определяет положение ротора. Период сигнала - 20 мс (частота 50 Hz) и ширина высокого полупериода 1-2 мс. 1 мс обозначает одно крайнее положение ротора и 2 мс другое крайнее положение ротора. 1,5 мс обозначает среднее положение ротора.

Традиционный RC серводвигатель носит и имя аналогового серводвигателя. Причина в том, что в последнее десятилетие появились так называемые дигитальные серводвигатели. Разница между ними заключается в том, что в аналоговом серводвигателе мотор управляется входным сигналом 50 Hz PWM, а в дигитальном серводвигателе мотором управляет отдельный микроконтроллер с более высокой частотой. Входной сигнал у дигитального серводвигателя такой же, но высокая частота модуляции двигателя позволяет определять положение точнее и быстрее.

 

Практика

На плате модуля «Двигатели» Домашней Лаборатории есть два разъема для подключения RC серводвигателя. Концы разъемов PWM сигнала подсоединены к выводам PB5 и PB6 микроконтроллера, альтернативной функцией которых являются выходы А и В единиц сравнения 16 битнога таймера 1. Таймер 1 способен создавать PWM сигнал, в связи с чем управление двигателями в программе происходит очень просто. Сложнее только настройка таймера.

Таймер 1 нужно настроить на режим создания PWM сигнала, где максимальное значение таймера обозначено ICR регистром. С помощью делителя такта таймера и меняющимся в программе максимального значения можно точно обозначить необходимую для управления серводвигателя частоту PWM сигнала. Регистром сравнения таймера можно обозначить длину высокого полупериода обоих PWM сигналов. У таймера имеются специальные единицы сравнения, которые отслеживают значение счетчика. Если оно становится таким же, как и значение регистра сравнения, то они меняют значение выхода единицы сравнения. Далее приведен программный код библиотеки Домашней Лаборатории, управляющий серводвигателями, который в целях универсальности использует параметры таймера, определенные макрофункцией. К примеру, для нахождения периода используется постоянная F_CPU, которая обозначает тактовую частоту микроконтроллера. Для разных тактовых частот не нужно самому вычислять параметры таймера макросами, и компилятор так и так переводит сравнения макросами в постоянные, так что память программы не увеличивается и не занимает больше время исполнения.

//
// Значение таймера для достижения полного периода (20 мс) PWM.
// F_CPU - тактовая частота микроконтроллера, которая делится на 8 и 50 Hz.
//
#define PWM_PERIOD      (F_CPU / 8 / 50)
 
//
// Центрально положение серво PWM (1,5 мс / 20 мс)
// Центральное положение достигается взятием из полного периода 15/200
//
#define PWM_MIDDLE_POS  (PWM_PERIOD * 15 / 200)
 
//
// Повторный фактор, чтобы получить необходимый период +1 
// в процентах (-100% до 100%) складывается для того, чтобы полупериод  
// точно достигал границ 1 и 2 мс или немного выще.
//
#define PWM_RATIO       (PWM_PERIOD / 20 / 2 / 100 + 1)
 
//
// Настройка выводов
//
static pin servo_pins[2] =
{
	PIN(B, 5), PIN(B, 6)
};
 
//
// Подготовка к работе выбранного серводвигателя.
//
void servomotor_init(unsigned char index)
{
	// Вывод PWM сигнала выходом
	pin_setup_output(servo_pins[index]); 
 
 
	// Настройка таймера 1
	// Делитель такта 8
	// Быстрый PWM режим, где TOP = ICR
	// OUTA и OUTB низким при сравнении 
	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);
 
	// Определение периода с помощью максимального значения
	timer1_set_input_capture_value(PWM_PERIOD);	
}
 
//
// Обозначение позиции серводвигателя
// Параметр позиции от -100 до 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;
	}
}

Пример программы использует функции, описанные в библиотеке Домашней Лаборатории. В начале программы заставляют работать таймер первого серводвигателя, генерирующий PWM сигнал, функцией servomotor_init. Значение положения серводвигателя получается из канала 3 аналого-дигитального преобразователя, куда на плате модуля «Датчики» подсоединен потенциометр. Для того чтобы получить необходимый для управления серводвигателя интервал от -100 до 100, от значения ADC отнимается половина максимума (т.е. 512) и делится на 5. Результатом является ±102, но небольшая неточность не считается, так как серводвигатели сами отличаются в отношении PWM сигнала и угла поворота. Для точного передвижения придется в приложениях обозначить ширину полупериода PWM методом проб и ошибок. Так же у моделей радиоуправляемых пультов для точной настройки существуют соответствующие возможности (на английском языке trim). При запуске программы, изменяется в соответствии с положением потенциометра и положение вала серводвигателя.

 

//
// Тест программа серводвигателя
// модуля «Двигатели» Домашней Лаборатории.
//
#include <homelab/adc.h>
#include <homelab/module/motors.h>
 
//
// Основная программа
//
int main(void)
{
	short position;
 
	// Настройка ADC
	adc_init(ADC_REF_AVCC, ADC_PRESCALE_8);
 
	// Настройка двигателя
	servomotor_init(0);
 
	// Бесконечный цикл
	while (true)
	{
		// Считывание позиции потенциометра и перевод
		// в область серводвигателя
		position = ((short)adc_get_value(3) - (short)512) / (short)5;
 
		// Обозначение позиции серводвигателя
		servomotor_position(0, position);
	}
}