roboforum.ru

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

Проблема управление сервы с кнопки

Re: Проблема управление сервы с кнопки

AVRus » 13 фев 2011, 18:28

кварц 12МГцб предделитель 8,
Код: Выделить всёРазвернуть
char n=0;
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{

if (n==0) {
PORTD=0x00;
OCR1AH=0x75;
OCR1AL=0x00;
n=1;
} else {
PORTD=0x01;
OCR1AH=0x08;
OCR1AL=0xCA;
n=0;
}

}
TCCR1A=0x03;
TCCR1B=0x1A;
OCR1AH=0x75;
OCR1AL=0x00;
TIMSK=0x04;

этоже аналог
Код: Выделить всёРазвернуть
  PORTD = 0x01;   
  delay_us(1500);
  PORTD = 0x00; 
  delay_ms(19);

В протеусе работают одинаково..НО на реальной серве должным образом работает только 2й вариант :((

Re: Проблема управление сервы с кнопки

Duhas » 13 фев 2011, 18:42

еще раз.. сколькими сервами нужно будет управлять ?!

Re: Проблема управление сервы с кнопки

dccharacter » 13 фев 2011, 19:43

Питание какое? Сервам нужно 6В, на 5 они, бывает, дурят.

Судя по этому:
Код: Выделить всёРазвернуть
Assembly Code Example(1)
TIM16_ReadTCNT1:
; Save global interrupt flag
in r18,SREG
; Disable interrupts
cli
; Read TCNT1 into r17:r16
in r16,TCNT1L
in r17,TCNT1H
; Restore global interrupt flag
out SREG,r18
ret
C Code Example(1)
unsigned int TIM16_ReadTCNT1( void )
{
unsigned char sreg;
unsigned int i;
/* Save global interrupt flag */
sreg = SREG;
/* Disable interrupts */
_CLI();
/* Read TCNT1 into i */
i = TCNT1;
/* Restore global interrupt flag */
SREG = sreg;
return i;
}

, можно делать вместо

Код: Выделить всёРазвернуть
 OCR1AH=0x75;
OCR1AL=0x00;


вот так:

Код: Выделить всёРазвернуть
 OCR1A=0x7500;
, смотрите параграф Accessing 16-bit Registers

Вот это не пойму, что: Writing the OCR1x Registers must be done via the TEMP Register
since the compare of all 16 bits is done continuously., атмегаводы пусьб подскажут

Ну и вот, надо определить режим работы, чтобы при достижении compare vales таймер обнулялся (хотя это странный режим работы для пиковода :-)))

Clear Timer on
Compare Match (CTC)
Mode
In Clear Timer on Compare or CTC mode (WGM13:0 = 4 or 12), the OCR1A or ICR1 Register
are used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when
the counter value (TCNT1) matches either the OCR1A (WGM13:0 = 4) or the ICR1 (WGM13:0 =
12). The OCR1A or ICR1 define the top value for the counter, hence also its resolution. This
mode allows greater control of the compare match output frequency. It also simplifies the operation
of counting external events.
The timing diagram for the CTC mode is shown in Figure 45. The counter value (TCNT1)
increases until a compare match occurs with either OCR1A or ICR1, and then counter (TCNT1)
is cleared.

Re: Проблема управление сервы с кнопки

Duhas » 13 фев 2011, 20:37

таймеру можно задать регистр сравнения.. вызывая прерывания/ШИМ на пине, или управлять периодом таймера..

ТС еще раз определиться с итоговой задачей... а дальше распишем что и как кодить...

Re: Проблема управление сервы с кнопки

dccharacter » 13 фев 2011, 20:55

Да у него задача - серву в среднее положение поставить, даже это пока не выходит. Какие там дальше задачи. Давайте начинать с малого и не забивать человеку голову полетами на Марс.

Re: Проблема управление сервы с кнопки

Duhas » 13 фев 2011, 21:00

можно решать задачу А, и начинать с ее деталей, а можно начать страдать хренью..

Re: Проблема управление сервы с кнопки

boez » 14 фев 2011, 01:47

А можно вообще повесить серву на ногу PD5 (если надо вторую - на PD6) и выкинуть прерывание нафиг. А если уж делать на прерывании - то я бы делал в режиме CTC, со счетом только вверх, а не баловался с хитропопыми PWM со счетом вперед-назад.

AVRus, вот для теста вариант с fast pwm. Когда надо поменять положение сервы - просто вписываем новое число от 1500 до 3000 в OCR1A. Кварц 12 МГц.

Код: Выделить всёРазвернуть
    TCCR1A = (1<<COM1A1)|(1<<WGM11); // Non-inverting Fast PWM mode on OC1A, TOP=ICR1
    TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11); // OSC/8
    ICR1 = 20000*(12.0/8);
    OCR1A = 1500*(12.0/8);
    DDRB = (1<<5);

    while (1) {
        //тут можно делать все что угодно :)
    }


Ни на чем не проверялось и ничего не гарантировано :). Хотя я надеюсь, что мой опыт позволяет мне писать такие штуки просто на листике и чтоб сразу работало :).

Re: Проблема управление сервы с кнопки

AVRus » 14 фев 2011, 03:49

чтож определимся с задачей !
Нужно крутить одной сервой "туды сюды" (про управление с кнопки пока забудем), с помощью прерывания на таймере, проблема в том что в протеусе сигнал получается нужный, но в реальной ситуации серва ведет себя странно (то не двигается, то дребежжит, то двигается очень медленно и дребежжит).
Также замечу что просто задавать какой либо угол и удерживать его на серве получается с помощью delay(), но с помощью таймера не получается, хотя опять же в протеусе все симулируется как надо!
Серва как и МК питается от программатора, он в свою очередь от USB.

Re: Проблема управление сервы с кнопки

Angel71 » 14 фев 2011, 04:09

и чтож это у вас за серва такая, что ей хватает менее 500ма? :) ну и так, о тичках: не на всех мб реализована защита от кз и/или чрезмерного потребления тока

Re: Проблема управление сервы с кнопки

HarryStar » 14 фев 2011, 09:36

dccharacter писал(а):Питание какое? Сервам нужно 6В, на 5 они, бывает, дурят.

Это неправда. Для большинства серв 5В - штатное напряжение, у них в спецификации указываются параметры на 4.8В и 6В - различается скоростью и усилием. Так что от 5В все прекрасно работает (исключение - спец сервы с повышенным напряжением).
Angel71 писал(а):и чтож это у вас за серва такая, что ей хватает менее 500ма?

Микросерва HXT-900 жрет ДО 200 мА, от USB их можно до 4х штук питать без проблем.

Топикстартеру:
Если у вас одна серва, можно сделать оч простую и наглядную прогу.
На 8-ми битном таймере делаете прерывание по значению, задав его так, чтобы прерывание было каждые 20 мс.
Внутри сразу делаете старт импульса и обнуление другого таймера (16-ти битного) считающего каждую 1 мкс и дальше просто в while считаете нужную длительность импульса, после чего останавливаете импульс.

Для малого количества серв быстродействия хватит, программа будет очень наглядной.

Re: Проблема управление сервы с кнопки

Angel71 » 14 фев 2011, 13:12

точно, про мелкосервы я как-то сходу и запамятовал, они действительно относительно немного потребляют. :) но не настолько же. по стандарту 3.0 максимум 900ма, а все предыдущие позволяют до 500ма. пардон, я с утра иногда плохо считаю, но всё же попробую. 2*200ма + мк + программатор = максимум 2 сервы, если поверить вам на слово про 200ма. :oops: а я не верю. а вот в минимум 500..600ма без нагрузки верю, по форумам и тематическим сайтам для мелкосерв в этом диапазоне частенько мелькают такие циферки. вот один из таких источников http://homepages.paradise.net.nz/bhabbott/Servo.html :pardon: мне с моим мультиметром мерять импульсное потребление своих серв слегка не логично, приходиться доверять другим. а вот про 5в таки да, от 5ти прекрасно работают даже "стандартные" сервы.
Последний раз редактировалось Angel71 14 фев 2011, 13:38, всего редактировалось 1 раз.

Re: Проблема управление сервы с кнопки

HarryStar » 14 фев 2011, 13:35

Без нагрузки серва ток не потребляет, только копейки на электронику. Потребление идет скачками в момент перемещения, если стоит кондер хотябы 1000 мкф, то проблем нет.

Я питал и 8 серв таких от USB, проблемы были только при их одновременном движении под нагрузкой, при перемещении в воздухе 8 серв работали без проблем, от 1-4 как я написал вообще проблем нет никаких, мк ток не потребляет (2-6 ма можно пренебречь), программатор если 5 проводков - тоже, светодиоды по 10 ма, все это мелочи.

В любом случае простейший код с задержками у человека работает, значит дело только в программе.
Последний раз редактировалось HarryStar 14 фев 2011, 14:12, всего редактировалось 1 раз.

Re: Проблема управление сервы с кнопки

Angel71 » 14 фев 2011, 13:52

это с кондёром, вполне логично.

Re: Проблема управление сервы с кнопки

AVRus » 14 фев 2011, 21:51

HarryStar писал(а):Топикстартеру:
Если у вас одна серва, можно сделать оч простую и наглядную прогу.
На 8-ми битном таймере делаете прерывание по значению, задав его так, чтобы прерывание было каждые 20 мс.
Внутри сразу делаете старт импульса и обнуление другого таймера (16-ти битного) считающего каждую 1 мкс и дальше просто в while считаете нужную длительность импульса, после чего останавливаете импульс.

Для малого количества серв быстродействия хватит, программа будет очень наглядной.

А в чем разница использовать один или 2а таймера ?
И кстати серва у меня SG90 micro servo 9g/.12s/1.6kg, с кодом использующим delay() поднимает мобилку на нитке - так что питания явно хватает...

Re: Проблема управление сервы с кнопки

HarryStar » 15 фев 2011, 18:48

AVRus писал(а):А в чем разница использовать один или 2а таймера ?


Для наглядности, яж написал. Мне так больше нравится.
Вот набросал простейшую прогу, на атмега32 / 16Мгц, все работает, проверил в железе.
Код: Выделить всёРазвернуть
#include <mega32.h>
#include <delay.h>
#include <stdlib.h>

unsigned int servo_time=0; // Удвоенная длительность импульса

// 0 - 255 угол поворота сервы
void servo(unsigned char p)
{
  servo_time = 2000 + 8*(unsigned int)p;
}
void main(void)
{
  unsigned int i;
  // Port initialization
  PORTA=0x00; DDRA=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x05;
TCNT0=0x00;
OCR0=0x9c; // 100 Hz (10ms)

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 2000,000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

TIMSK=0x02; // Старт таймер 0
#asm("sei")

while(1)
{
  // Серва в одну сторону
  for(i=0;i<255;i++)
  {
    servo(i);
    delay_ms(20);
  }
  // Серва в другую
  for(i=0;i<255;i++)
  {
    servo(255-i);
    delay_ms(20);
  }
}

while(1);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
   // Сюда мы попадаем с частотой 100 Гц
   static unsigned char half=0;
   TCNT0=0x00; // Обнуление таймера
   half++; if(half&1)return; // Прерывание идет в 2 раза быстрее чем надо.
   
   // Сюда мы попадаем с частотой 50 Гц
   PORTA = 0xFF; // Старт импульса
   TCNT1 = 0; // Обнуление таймера 1
   while(servo_time > TCNT1); // Ожидание нужной длительности импульса
   PORTA = 0x00; // Стоп импульса
}


По программе серва медленно поворачивается туда-сюда


cron
Rambler\'s Top100 Mail.ru counter