Сервопривод HXT 900 с ATmega 8

Решил я попробовать как-то раз подключить сервопривод к контроллеру. Дело с такими вещами я раньше не имел, так что купил первую попавшуюся машинку.

Далее пошел копать на нее мануал, но оказалось это дело непростое. Сам производитель поскупился, и написал всего лишь 1 листочек. Hextronik_HXT900_datasheet. Поиски по разным форумам помогли найти мне электрическую схему.

Servo HXT900

 HXT900 с ATmega8 (не пугаться, на макете много лишнего)

 Приведу некоторые важные параметры

  • Напряжение питания: 4.8 – 6 В (но говорят можно и от 9В питать, правда дольше он от этого не прослужит, на деле питал от 3.3В все ОК)
  • Потребляемый ток: Очень долго искал, и только на одном форуме между строк нашел 700 мА, кажется мне, это враки, ибо от USB (500 мА), он работает у меня прекрасно. Источник на изи элктроникс говорит, что до 100 мА. Лично я намерил 180 мА максимум
  • Крутящий момент: 1.5 кг см2
  • Угол поворота: 90 градусов

Теперь о том как им управлять.

  • Коричневый провод – земля
  • Красный – питание
  • Желтый – сигнальный (должно быть не меньше 3.3 В)

Везде говорят, что это простой ШИМ, но верить им не стоит. Несущая частота 50 Гц (20 мс), и положение вала задается шириной импульса. От 0.45 мс ( 2222.2[2] Гц ) до 2.45 мс ( ~408.16 Гц ).

На деле несущая частота ШИМ может быть любой, но не меньше чем ширина импульса крайнего правого положения.

  1. Если частота например 1 Гц, то он 1 раз в секунду будет поворачивать вал на небольшой угол, и так пока не придет к заданному значению.
  2. Если частота будет 200 Гц, то отклик и жесткость выросте (когда на сигнальной линии пусто, то ротор двигателя можно спокойно вращать), но так же упадет крутящий момент.

servo_pulse

 

Примерно так выглядит сигнальная линия

С точки зрения программирования, эта задача очень простая. И даже не стоит того, чтобы занимать аппаратный ШИМ. Так как в приложениях с этим приводом скорее всего он будет не один, а ШИМ один, думаем как сделать все ручками.

Проще всего сделать это с помощью таймера.

В теле задаем делитель и запускаем таймер, так же разрешаем прерывание. (у меня 12 МГц кристалл, делитель не установлен)

sei(); 
TCCR0 |= (0<<CS02)|(1<<CS00); 
TIMSK |= (1<<TOIE0);

и в прерывании уже доводим до частоты. (данный код раз в секунду двигает вал в другое крайнее положение)

ISR (TIMER0_OVF_vect) {
 if(i>j)//(24) 47 - 94 (118) // через столько переполнений пройдет 0.45 и 2.45 мс соответственно, в скобках дествительные
 PORTB &=0;
 if(i>938){//50Гц - это 938 пререполнений таймера при частоте 12 МГц
 PORTB |=(1<<PB1)|(1<<PB2)|(1<<PB0); // 2 диода и серво
 i=0;
 }
 if(bo>46875){ // 1 секунда // каждую секунду меняет задающее значение ротора.
 if(j==24)
 j=118;
  else
 j=24;
 bo=0;
 }
 bo++;
 i++;
}

Можно все это хорошенько формализовать и сделать хоть для каждой ноги, и на каждую прицепить сервопривод.

Напоследок, видео

Полезные ссылки: