Управление Сервами в WinAvr

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Сообщение Lirzman » 15 авг 2006, 20:28

Поначалу я хотел вообще точность ~5гр сделать, так что к извращенцам я себя отнести немогу. :D  :D  :D
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Сообщение Lirzman » 15 авг 2006, 20:34

"servos have a deadband of 1~3us."

Слушайте, а чё я карячусь то?:shock:
Если 3мс и точность составляет ~0.12гр, сервы трясти не будет?
Если так то можно сразу переходить к раззаботке управленя 8-ю сервами   :?:
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Сообщение aesok » 15 авг 2006, 20:48

Lirzman писал(а):Если так то можно сразу переходить к раззаботке управленя 8-ю сервами   :?:


Давай вначале с одной разберемся. :?:
aesok
 
Сообщения: 69
Зарегистрирован: 11 авг 2006, 01:02
Откуда: ----

Сообщение Lirzman » 15 авг 2006, 21:01

aesok писал(а):Давай вначале с одной разберемся

Да я уже разобрался.
Подаётся управляющий импульс(1.5мс) с частотой 50 герц, на оссцилографе всё прекрасно видно :D
Таймер бегает по кругу подавая на выбранную серву управляющий импульс(1.5мс) с частотой 50 герц, если выбрать другую серву, то таймер предидущюю оставит в покое и займется новой.   :D

На картинку посмотрите и все поймете :D
Вложения
simul1.JPG
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Сообщение aesok » 15 авг 2006, 21:07

Lirzman писал(а):Да я уже разобрался

Отлично Давай код.
aesok
 
Сообщения: 69
Зарегистрирован: 11 авг 2006, 01:02
Откуда: ----

Сообщение Lirzman » 15 авг 2006, 21:11

Держи :D
Вложения
demo.c
(4.63 КиБ) Скачиваний: 324
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Сообщение aesok » 15 авг 2006, 21:32

Lirzman писал(а):Держи :D


Поправь вначале ошибки про кроторые я писал.

SIGNAL(SIG_OVERFLOW1)
      TCNT1 = period;  => TCNT1 = period - gangle;
Зачем я уже писал. Не 0 должен быть 20 мс а 0 +1!

void Servo_Control()
char szInput [4]; =>  char szInput [5];
 szInput[4] = USART_Receive(); => szInput[4] = 0;

Тут можно в будущем нарвться но плохую ошибку. Строка должна заканчиваться 0 :!:  :!:  :!:  :!:  :!:  Enter  надо обрабатывать по другому.

Здесь еще одна класическая ошибка. Размер масива равен 4, а символов ты присваиваеш 5: первый - [0], [1], [2], [3], пятый- [4]. Размер масива должен быть 5.

сделай всетаки 'сur_state' локальной. Запомни: Переменная должна быть видна только там где она нужна. И глобальных переменных должно быть Так мало, как это возможно.

Анатолий.
aesok
 
Сообщения: 69
Зарегистрирован: 11 авг 2006, 01:02
Откуда: ----

Сообщение aesok » 15 авг 2006, 21:36

Какая у тебя версия WinAVR?
aesok
 
Сообщения: 69
Зарегистрирован: 11 авг 2006, 01:02
Откуда: ----

Сообщение Lirzman » 15 авг 2006, 21:47

aesok писал(а):сделай всетаки 'сur_state' локальной.

Исправил.

aesok писал(а):Размер масива равен 4, а символов ты присваиваеш 5: первый - [0], [1], [2], [3], пятый- [4]. Размер масива должен быть 5.

Исправил, получилось:

Код: Выделить всё
void Servo_Control()
{char s;
int angle;
char szInput [5];
s=USART_Receive();

s=s-0x31;

szInput[0] = USART_Receive();
szInput[1] = USART_Receive();
szInput[2] = USART_Receive();
szInput[3] = USART_Receive();
szInput[4] = USART_Receive();
szInput[5] = 0; // Строка должна заканчиваться 0

angle = atoi (szInput);

Pos(s,angle);
}


aesok писал(а):SIGNAL(SIG_OVERFLOW1)
     TCNT1 = period;  => TCNT1 = period - gangle;
Зачем я уже писал. Не 0 должен быть 20 мс а 0 +1!


А вот с этой ошибкой возникла небольшая проблема.
Как мне их складывать если пауза отсчитывается в тиках таймера=тиках процессора(делитель=1)? Следовательно чем больше число тем меньше задержка, понимаете?
60000 это управляющий импульс а 1000 это - пауза в 20мс.
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Сообщение Lirzman » 15 авг 2006, 21:49

мне щас идти надо, через час буду. :wink:
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Сообщение aesok » 15 авг 2006, 21:57

Lirzman писал(а):
Исправил, получилось:

Код: Выделить всё
void Servo_Control()
{char s;
int angle;
char szInput [5];
s=USART_Receive();

s=s-0x31;

szInput[0] = USART_Receive();
szInput[1] = USART_Receive();
szInput[2] = USART_Receive();
szInput[3] = USART_Receive();
szInput[4] = USART_Receive();
szInput[5] = 0; // Строка должна заканчиваться 0

angle = atoi (szInput);

Pos(s,angle);
}



внимательней!  char szInput [5]; - Место под 5 символов, а szInput[5] = 0; уже шестой. К сожелению С, В отличии от некоторых других языков,  не проверяет на нарушение границ масива. Ето обязанность програмиста. Будте внимательны. Основная масса ошибок в пограмах на С из за этого!!!!!

aesok писал(а):SIGNAL(SIG_OVERFLOW1)
     TCNT1 = period;  => TCNT1 = period - gangle;
Зачем я уже писал. Не 0 должен быть 20 мс а 0 +1!


А вот с этой ошибкой возникла небольшая проблема.
Как мне их складывать если пауза отсчитывается в тиках таймера=тиках процессора(делитель=1)? Следовательно чем больше число тем меньше задержка, понимаете?
60000 это управляющий импульс а 1000 это - пауза в 20мс.

Буду смотреть.

Анатолий.
aesok
 
Сообщения: 69
Зарегистрирован: 11 авг 2006, 01:02
Откуда: ----

Сообщение aesok » 15 авг 2006, 22:12

Lirzman писал(а):
aesok писал(а):SIGNAL(SIG_OVERFLOW1)
     TCNT1 = period;  => TCNT1 = period - gangle;
Зачем я уже писал. Не 0 должен быть 20 мс а 0 +1!


А вот с этой ошибкой возникла небольшая проблема.
Как мне их складывать если пауза отсчитывается в тиках таймера=тиках процессора(делитель=1)? Следовательно чем больше число тем меньше задержка, понимаете?
60000 это управляющий импульс а 1000 это - пауза в 20мс.


Есть 2 варианта.
1 - Использовать В таймере делитель на 2.

но я предлогаю другой вариант.

Максимальный периуд который может обеспечить 16-битный таймер без делителя это 17,7 мс.  Так пускай это и будет периудом управляющих импульсов! 20 мс - это взято из систем радиоуправления моделями. Сервомашинка будет отлично работать и с 17 мс.

Попробуйте переделать так.

Анатолий.
aesok
 
Сообщения: 69
Зарегистрирован: 11 авг 2006, 01:02
Откуда: ----

Сообщение Lirzman » 16 авг 2006, 00:12

aesok писал(а):Сервомашинка будет отлично работать и с 17 мс.

И работает же!!! :D
По крайней мере в симуляторе.

Теперь надо переводить всё это дело под несколько серв.
Пока сформулирую возможное(частичное) решение проблемы на словах.
Период в 20(~17)мс :D  можно делать для всех серв сразу.

А вот с управляющим импульсом надо думать что делать. :shock:
Делать параллельно управляющий импульс для всех одновременно ну никак не получится т.к таймер всего один, а импульсы нужны разные:(

Как делать их последовательно я себе тоже не очень представляю.
8 * 1.5 = 12
Съесть 12мс из 20мс импульса нельзя никак(точность упадет до неприемлимых величин).

Может у кого есть соображения по этому поводу?
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Сообщение avr123.nm.ru » 16 авг 2006, 00:13

Для измерения времени между событиями в PROTEUS можно поставить точки останова.

Как это сделать написано на  proteus123.narod.ru/01.htm  
и  при остановках программы на них смотреть текущее время симуляции в низу экрана PROTEUS и затем посчитать разницу во времени.
Последний раз редактировалось avr123.nm.ru 16 авг 2006, 02:11, всего редактировалось 1 раз.
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Сообщение Lirzman » 16 авг 2006, 00:43

avr123.nm.ru писал(а):по-моему atoi коротковат будет, возможно нужен  atol    ?

Работает и бог с ним.
К счастью, PROTEUS терминал нормально эмулирует. :D

aesok писал(а):char szInput [5]; - Место под 5 символов

А разве счет в массиве не с нуля идет?
Просто я уже проверял, если в массив под 5 запихнуть 4 символа
оно не заработает пока Enter не нажмешь, ну или там символ какой-нибудь не введешь.



Насчет нескольких серв мне пришла интересная идея:idea: .
А что если поставить все управляющие импульсы в очередь?
Учитывая что МК остаётся свободным(работает таймер) времени и ресурсов это займет немного.
Пример:
(2мс+20мс)*8(кол-во серв)=88мс
Сервы успеют за это время 20 раз туда и обратно повернутся.

Как идейка реализуема?
Аватара пользователя
Lirzman
 
Сообщения: 257
Зарегистрирован: 22 мар 2005, 03:59
Откуда: Питер

Пред.След.

Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4