roboforum.ru

Технический форум по робототехнике.

Драйвер сервы

Re: Драйвер сервы

semak » 12 мар 2010, 21:34

кому интересно, вот моя версия сервоконтроллера на 8 серв для меги8. используется только таймер/счетчик2. для простоты под сервы выделяется свой порт (SERVOPORT) с возможностью маскирования нужных пинов (SERVOMASK). разрешение примерно 1градус на каждую для частоты 11.0592МГц при использовании HXT900.
код проверен, отлично работает на моем роботе (3 сервы)

Код: Выделить всёРазвернуть
// Для компилятора AVR-GCC / WinAVR
// Сервоконтроллер на 8 серво (АТмега8, 11.0592МГц)
// Работает на прерываниях таймера-счетчика 2

#define F_CPU   11059200   //частота проца

#include <avr/io.h>
#include <avr/interrupt.h>

//макросы для установки/сброса/переключения отдельных битов
#define clrs( x,y )   x &= ~(y)
#define sets( x,y )   x |= (y)
#define togs( x,y )   x ^= (y)
#define clr( x,y )   clrs( x,(1<<y) )
#define set( x,y )   sets( x,(1<<y) )
#define tog( x,y )   togs( x,(1<<y) )

//порт сервоконтроллера
#define SERVOPORT   PORTD
//маска сервоконтроллера
#define SERVOMASK   0xF0

//частота таймера2 Ft2=400Гц, вычисляется как F_CPU/Ft2/PRSt2
//где PRSt2 - значение предделителя
#define EVERY400   216
#define TCNT2_VAL   (255-EVERY400)
//среднее значение для серво, вычисляется как EVERY400*1.5/2.5+TCNT2_VAL
#define SERVO_AVG   169

//массив, с помощью которого устанавливаются значения серв
volatile unsigned char servo[8], servo_i, servo_next;

ISR( TIMER2_OVF_vect )
{
   TCNT2 = TCNT2_VAL;
   servo_i = servo_next;
   servo_next++; if( servo_next>7 ){ servo_next=0; }
   OCR2 = servo[ servo_next ];
   if( servo[servo_i] < TCNT2_VAL ){ return; }
   sets( SERVOPORT, (1<<servo_i)&SERVOMASK );
}

ISR( TIMER2_COMP_vect )
{
   clrs( SERVOPORT, (1<<servo_i)&SERVOMASK );
}

int main()
{
   //PORT D as SERVO
   //4-7 servo
   DDRD  = (1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);
   PORTD = 0;

   //Инициализация таймера2
   TCCR2 = (1<<WGM20)|(1<<WGM21)|(5<<CS20);
   TCNT2 = TCNT2_VAL;

   TIMSK = (1<<OCIE2)|(1<<TOIE2);

   servo_i = 0;
   servo_next = 1;
   for( unsigned char i=0; i<8; i++ ){ servo[i] = 0; }

   sei();

                     //для примера
   servo[4] = SERVO_AVG;    //серво4 - T=1500us (  0*)
   servo[5] = SERVO_AVG+86;//серво5 - T=2500us (+90*)
   servo[6] = SERVO_AVG-86;//серво6 - T= 500us (-90*)
   servo[7] = SERVO_AVG+43;//серво7 - T=2070us (+45*)
                     //остальные каналы не используются (маскированы SERVO_MASK)

   while(1);

   return 0;
}
Последний раз редактировалось semak 12 мар 2010, 21:42, всего редактировалось 1 раз.

Re: Драйвер сервы

=DeaD= » 12 мар 2010, 21:35

А точность работы в микросекундах какая? :oops:

Re: Драйвер сервы

semak » 12 мар 2010, 21:37

зависит от частоты. в данном примере 2500/216=11.57мкс

Re: Драйвер сервы

avr123.nm.ru » 12 мар 2010, 22:40

Многовато, но проект всеравно "гуд" если правильно работает.

Возможно стоит посмотреть постой протокол управления servo который применяется в популярных западных прогах - пример есть у меня на http://proavr.narod.ru/z13.htm

Re: Драйвер сервы

Michael_K » 13 мар 2010, 07:06

Специально исследовал эти вопросы.

ПОЛОЖЕНИЕ обычной сервы не зависит от частоты вообще,
Даже если частота плавает или изменяется в широких пределах. Только от ширины импульса.
Глюки начинаются только если серву механически перегрузить :) но это и так понятно...
Ну или если частота уже совсем большая (у меня герцах на 80 начинала дурить при относительно легкой нагрузке).

СКОРОСТЬ переделанной сервы ЗАВИСИТ от частоты.
Джиттер (дрожание фазы импульса) сглаживается механической инертностью мотора,
поэтому вы его не заметите и примерчики от АВР-а наверняка будут нормально работать.
Потому что там, хотя фаза и плавает, частота (в среднем) остается постоянной.

На моей серве драйвер нифига не ШИМил
(HXT900 тоже самая простая аналоговая - нету там "собственного" шима)
- он только выдавал импульс напряжения на мотор после каждого управляющего импульса.
Ширина импульса на моторе зависит (про пропорциональность не буду врать :wink: )
от ширины управляющего импульса и положения резистора. Вот и все.

Re: Драйвер сервы

=DeaD= » 13 мар 2010, 09:12

Michael_K писал(а):На моей серве драйвер нифига не ШИМил
(HXT900 тоже самая простая аналоговая - нету там "собственного" шима)
- он только выдавал импульс напряжения на мотор после каждого управляющего импульса.
Ширина импульса на моторе зависит (про пропорциональность не буду врать :wink: )
от ширины управляющего импульса и положения резистора. Вот и все.

Поздравляю, вы только что изучили схему работы аналоговой сервы :D
Можно было просто прочитать http://www.rcdesign.ru/articles/radio/digital_servos

Re: Драйвер сервы

Michael_K » 13 мар 2010, 09:37

Я глюканул :oops: - ответил Радисту, не посмотрев на дату и страницу :)

Dead, вашу реплику не понял. Чего это я "только что изучил"???
Вы бы ссылки лучше задающему вопросы рассылали... :wink: ,
когда он писал про "то, что драйвер HXT900 сам шимит сигнал управления на своем мосту".

Реально же я не видел чтобы кто-то сказал ему (не мне, мне уже не надо),
что скорость переделанной сервы зависит от частоты импульсов (а не только от ширины).

Re: Драйвер сервы

=DeaD= » 13 мар 2010, 09:51

Очень эмоционально (= с удивлением) написано было "на моей сервер драйвер нифига не ШИМил".
Аналоговые сервы никогда не ШИМят сами, они только в ответ на управляющий импульс выдают сигнал на движок и всё ;)
Это одно из основных отличий от цифровых серв.

Re: Драйвер сервы

Radist » 14 мар 2010, 15:29

Я задал простой вопрос: Зависит ли угловая скорость от ширины импульса. Мне АВР ответил что ДА. Что такое угловая скорость - это за какое время серва повернется на какой-то угол. Пусть угол 30 градусов. Так вот что я спросил: если я подам ширину импульса 1,4 мС, или 1 мС серва повернется за одно время или нет. Поначалу мне говорили что нет, при ширине 1,4 мС она будет поворачиваться медленнее. Поэтому я и предположил, что драйвер шимит сигнал. Но судя по последним ответам в теме, время поворота на один угол не зависит от ширины импульса, лишь бы импульс не был равен 1,5 мС. Так все-таки где же истина? Снова у меня вопрос- можно ли управлять скоростью сервы? Угловой скоростью.

Re: Драйвер сервы

=DeaD= » 14 мар 2010, 15:31

Можно, плавно меняя управляющий сигнал от текущего положения до нужного.

Re: Драйвер сервы

Radist » 14 мар 2010, 17:22

Кажется я понял, как это происходит. Я подаю ширину немного отличающуюся от 1,5 мС, через 20 мС - еще чуток меняю. Даже если угловая скорость постоянная - скорость поворота будет медленнее, чем если бы я сразу подал 1 мС. Меня смутил ответ АВР, насчет того, что угловая скорость разная. Наверное произошло обычное непонимание, он не понял что я спросил, я не понял что он ответил. Теперь вроде я разобрался.

Re: Драйвер сервы

Michael_K » 14 мар 2010, 17:44

Radist, угловая скорость переделанной сервы _зависит_ от ширины импульса.
Вам АВР правильно сказал. НО еще она зависит от нагрузки, напряжения питания.
Поэтому никто вам не скажет сколько именно надо подать,
чтобы скорость была, скажем половинной.

На холостом ходу (без механической нагрузки) рядом с серединой скорость управляется...
Дальше - держится примерно постоянной... То есть например
1.5 - стоим.
1.55 - медленно крутимся
1.6 - крутимся быстрее
А вот 1.8 от 1.9 если и отличается, то незаметно
(Цифры условные - какие будут именно у вас - неизвестно)

Под нагрузкой все это будет меняться.

Естественно, на _непеределанной_ серве, чтобы управлять скоростью, нужно плавно менять позицию (она позицию стремится держать), а вот у _переделанной_ обратной связи нету никакой - поэтому все это неопределенно.

Re: Драйвер сервы

TrashVigor » 23 мар 2010, 20:48

Где софт для компа достать управление серв от 4 и больше, через UART?

Re: Драйвер сервы

Angel71 » 23 мар 2010, 21:46

написать самому, заюзать терминал или :) или в студию описание, что значит управлять

Re: Драйвер сервы

TrashVigor » 23 мар 2010, 21:57

у меня манипулятор с 4мя сервами, нужно потестить его с компа, в дальнейшем юзаться будет не с компа. Че то мне думалось таких прог навалом должно быть, придется в делфях весь вечер провести


cron
Rambler\'s Top100 Mail.ru counter