Технический форум по робототехнике.
Правила форума
В данном разделе каждый может иметь не более одной темы. Тема должна начинаться с логина (ника) робофорума.
Romer » 05 дек 2009, 16:43
есть мыслишка последовательно включать сервы таймером, настраивая его на нужное время.
Michael_K » 05 дек 2009, 17:06
По-моему, на сайте у avr123 такая прога готовая была.
попробуйте найдите

ALHIMIK » 05 дек 2009, 17:09
есть "16серв" но для меги 16 нужно ?
Последний раз редактировалось
ALHIMIK 05 дек 2009, 17:38, всего редактировалось 1 раз.
AndreiSk » 05 дек 2009, 17:24
у него пик (микрочип которые делает)
ALHIMIK » 05 дек 2009, 17:37
это я знаю
в них нет прерывания по "совпадению" ?
Romer » 07 дек 2009, 15:44
родил сегодня такой код
- Код: Выделить всё • Развернуть
/*
таймер запущен на переполнение 0,05 мс (50 мкс)
*/
// считаем скоко прошло 1 мс = 20 * ms (20 позиций сервы)
// стартуем текущую серву
if(ms_servo == 0)
output_high(port_servo[cur_servo]);
ms_servo++; //сколько времени она проработала
if(ms_servo == 20 + pos_servo[cur_servo]) // если 1 мс (20 раз таймер сработал) + позиция выключаем
output_low(port_servo[cur_servo]);
if(ms_servo == INTERVAL) // ждем до ms * 0.05 = 2 мс (2000 мкс) и переключаемся на след серву
{
output_low(port_servo[cur_servo]); //выключаем, вдур раньне невыключилась
cur_servo ++;
ms_servo = 0;
if(cur_servo > 9) // 10 серв раз должно прокрутится NUM_SERV -1
cur_servo = 0;
}
// считаем скоко прошло 1 мс = 20 * ms (20 позиций сервы)
// стартуем текущую серву
if(ms_servo1 == 0)
output_high(port_servo[cur_servo1]);
ms_servo1++; //сколько времени она проработала
if(ms_servo1 == 20 + pos_servo[cur_servo1]) // если 1 мс (20 раз таймер сработал) + позиция выключаем
output_low(port_servo[cur_servo1]);
if(ms_servo1 == INTERVAL) // ждем до ms * 0.05 = 2 мс (2000 мкс) и переключаемся на след серву
{
output_low(port_servo[cur_servo1]); //выключаем, вдур раньне невыключилась
cur_servo1 ++;
ms_servo1 = 0;
if(cur_servo1 > 19) // 10 серв раз должно прокрутится NUM_SERV -1
cur_servo1 = 10;
}
это в прерываниии таймера
что скажете? в протеусе работаит.
Добавлено спустя 2 минуты 47 секунд:позиций каждой сервы получается 20 штучек.. думаю хватит на хождение.
Добавлено спустя 12 минут 22 секунды:мда, код немножко глупый
сам вижу. зачем мне два счетчика времени если можно один использовать. ms нигде не используется. убрал.
Добавлено спустя 1 минуту 49 секунд:получается управление последовательно 20-ю сервами.
интересно как в реальности будет загружен мк
AndreiSk » 08 дек 2009, 00:56
эта... 20 позиций всего? не густааа..
executer » 08 дек 2009, 01:24
чето не понял по коду. пока ты отрабатываеш ширину импульса управления для одной сервы - остальные выключены. там что такие огромные (на порядок дольше самого импульса) промежутки между управляющими импульсами предусмотрены?
Добавлено спустя 2 минуты 35 секунд:я тут делал ШИМ - так чтобы избавится от этих счетчиков в каждом прерывании расчитывал через какое время нужно будет чтото сделать и задавал соответсвующую величину в счетчик таймера TCNTx чтобы он через нужное мне время сработал. Помогло для очень быстрого ШИМ, чтобы он не очень основной программе мешал. Потом вспомнил про аппаратный ШИМ

...
Romer » 08 дек 2009, 11:30
ну да
там период 20 мс (20000 мкс)
а управляется серва от 1 до 2 мс (1000 - 2000 мкс) крайние положения
при таком коде, как родился выше плюс один, что используется один таймер, а минусов.. занятость мк >~50%, 20 позиций сервы, да и посмотрел в протеусе осцилографом, не успевает оно обработать за 20 мс 20 серв, только 10 примерно. эх. можно попробовать второй таймер подобным образом настроить тож на 10 серв. должно получится.
но буду возвращаться к двум таймерам таким образом:
первый настроен на 1 мс и в нем настраивается второй на ширину импульса от 0 до 1 мс.
20 серв по 1 мс, получится как раз 20 мс. Если второй таймер гибко настраивать, то можно получить много позиций серв.
правда при таком раскладе не знаю что будет с загруженностью МК.
Romer » 08 дек 2009, 20:59
родилась версия с двумя таймерами
- Код: Выделить всё • Развернуть
#int_timer2
void isr_timer2(void)
{
// вырубаем по прошествию нужного времени (0 - 1мс + 1мс = от 1 до 2 мс)
output_low(port_servo[prev_serv]);
disable_interrupts(INT_TIMER2);
prev_serv = cur_servo;
cur_servo ++; // следующая серва 2 1
if(cur_servo > NUM_SERV-1)
cur_servo = 0;
}
// общее время сервы, настроено на 1 мс
#int_timer0
void isr_timer0(void)
{
set_timer0(START_TIMER0);
//стартуем новую серву раз в 1 мс 1
output_high(port_servo[cur_servo]);
// когда наступила следующая серва надо запустить остановку предыдущей во втором таймере
// во втором таймере отключаем по позиции
clear_interrupt(INT_TIMER2);
setup_timer_2(T2_DIV_BY_4, pos_servo[prev_serv], 5);
set_timer2(0);
enable_interrupts(INT_TIMER2);
}
пока назначаю ее рабочей.
завтра буду шить в железо и смотреть.
executer » 08 дек 2009, 21:32
чтото я не пойму проблему, почему нельзя вот както так:
- Код: Выделить всё • Развернуть
T1OVF
{
if(++cnt>100) // точность - 100 положений
{
cnt=0;
перестраиваем таймер на медленный счет (большой делитель) и устанавливаем подходящее TCNT чтобы он сработал через 18мс
}
else
{
перестраиваем таймер на быстрый счет (цикл вызова 2мс/100 положений = 20 мкс)
if(cnt=1) // точность - 100 положений
{
cnt=0;
Srv1=1; // подаем сигнал на сервы
Srv2=1;
...
SrvN=1;
}
if(Srv1Pos<cnt) Srv1=0;
if(Srv2Pos<cnt) Srv2=0;
...
if(SrvNPos<cnt) SrvN=0;
}
}
Romer » 10 дек 2009, 13:35
наверное можно - надо пробовать:)
зашил в железо - работает

Romer » 11 дек 2009, 17:45
начинаю искать компутер, куда поставить solid.. а то везде убунта стоит.
первое приближение чего хочу делаю в картоне. смешно выходит

.
EdGull » 11 дек 2009, 17:51
тю...
а шо так? почему солид на убунту не ставишь?

Romer » 11 дек 2009, 18:02

я и так удивился что под wine заработало mplab, да proteus.
думаю с солидом номер не пройдет.