Форум myROBOT.ru » Шаг за шагом » Программирование микроконтроллеров » Управление сервомашинкой.

Страниц (4): [1] 2 3 4 »
 

1. Blitzkrieg - 29 Января, 2009 - 14:09:46 - перейти к сообщению
Хочу научить робота управлять сервомашинкой (робот на PIC16F887), столкнулся с проблемой.
Язык mikroC не позволяет подставлять переменную в процедуры временной задержки (delay_us(const),delay_ms(const)).
Сервомеханизм управляется импульсами длинной примерно от 600 до 2600 микросекунд, длинна периода 20 милисекунд.
Пробовал реализовать такой вариант например:
void pauza(int qnt)
{
int i
for(i=0;i<qnt;i++)
{
delay_us(1); //пробовал и delay_us(10) и delay_us(100);
}
}
while(1)
{
PORTB.F5=1;
pauza(600);
PORTB.F5=0;
pauza(20000-600);
}
По идее это должно работать, НО по всей видимости на это расходуется значительно больше машинных циклов - в итоге импульсы выходят не с необходимой частотой, а значительно реже. Вобщем кривой это метод.
while(1)
{
PORTB.F5=1;
delay_us(1500);
PORTB.F5=0;
delay_us(18500);
}
Вот так серва встает в среднее положение и удерживается в этом положении.
Как можно реализовать управление сервомеханизмом, так чтобы можно было задавать продолжительность импульса вызовом процедуры при постоянном периоде равном 20 мс.?
Чтение даташита навело на мысль использования ШИМ. Получится ли меняя скважность управлять сервомеханизмом, по правильному пути я иду? :-)
2. redcat - 29 Января, 2009 - 16:02:36 - перейти к сообщению
Запутался я чтото....
Процедуры это в Дельфи, в СИ только функции.

Я так понял, что проблема в в не правильной задержке, т.е. задержка меняется но не соответствует заданным критериям?
(Добавление)
СИ очень даже позволяет использовать константы или переменные для передачи числа в любую функцию. т.е.

int a = 1000; //1000 микросекунд

int main(void){
...................

while(1){

PORTB.F5=1;
_delay_ms(a)
PORTB.F5=0;
_delay_ms(a)
}
..............
}
(Добавление)
т.е тут порт (открывается) через секунду (закрывается) и так до бесконечности.

Важно правильно компилятору указать частоту тактового генератора МС, кварца короче.
3. Blitzkrieg - 29 Января, 2009 - 16:20:02 - перейти к сообщению
Функция возвращает значение, а процедура нет :-) вот и все отличие, но по тексту я могу их перемежать ибо пофиг :-)
Я не спроста пишу, что нельзя использовать variable для передачи в delay_us или delay_ms только константу.
Можете проверить. Не знаю как где, а вот в mikroC нельзя. Даж тему такую видел на mikroE


Often, function return value is not used at all, depending on the side effects. These functions are equivalent to procedures of other programming languages, such as Pascal. C does not distinguish between procedure and function – functions play both roles.

Нашел, дабы не быть голословным
http://www.mikroe.com/forum/view...;highlight=servo
4. redcat - 29 Января, 2009 - 17:16:36 - перейти к сообщению
Функции-Процедуры, это понятно. Ща попробую написать программку -
Сначала - Мигает светодиод раз в секунду
Нажимаем кнопку - частота увеличивается в два раза
и.т.д
(Добавление)
ВОТ РАБОЧИЙ ПРИМЕР (Правда для AVR)-
CODE:

#include <avr/io.h>
#include <util/delay.h>

#define F_CPU 4000000//Hz

int ms=1000; // Переменная ms = 1000 миллисекунд;

int main(void){

//Настраиваем порты
DDRD = 0x38; //0b00111000
DDRB = 0x00; //0b00000000;
PORTB = 0x07;//0b00000111;


while(1){ // Бесконечный цикл


PORTD |=_BV(PD4); // Зажигаем светодиод
_delay_ms(ms); //Задержка "мс"
PORTD &=~_BV(PD4); // Гасим светодиод
_delay_ms(ms); //Задержка "мс"


if(!(PINB&(1<<0))){ //Если "нажали кнопку"

while(!(PINB&(1<<0)));// Ждём пока нажата кнопка (от "дребезга")
//не обязательно.
ms = ms / 2; // Делим миллисекунды на 2

}

}
}

(Добавление)
Пример работает на практике, правда в момент задержки нет реакции на кнопку, нужно делать прерывание по кнопке... но это уже другой вопрос.
5. бот_м_16 - 29 Января, 2009 - 17:45:20 - перейти к сообщению
Товарищи nop ре рулит - используйте таймеры-между действиями по таймеру можно чёнить делать(2+2 считать Улыбка ) Подмигивающий
6. redcat - 29 Января, 2009 - 17:51:41 - перейти к сообщению
По таймеру предпочтительнее но нужно чуть подумать))), для быстрого примера и так сойдёт.
7. Blitzkrieg - 29 Января, 2009 - 18:39:05 - перейти к сообщению
Ваш пример тока в микроси ошибка при компиляции. Таже батва если используется delay_us.
Таймер пробовал, чот пока не придумал как его применить к управлению сервой :-)
8. бот_м_16 - 29 Января, 2009 - 18:53:32 - перейти к сообщению
исправь последнию паузу
9. redcat - 29 Января, 2009 - 18:58:46 - перейти к сообщению
Странно, компилятор ругается на не правильное использование константы... Почему константа а не переменная? Бред какойто, попробуй другой компилятор может...

попробуй вот что -

int ms;

int main(void){
ms=1000;
............................
10. Blitzkrieg - 29 Января, 2009 - 19:00:02 - перейти к сообщению
Внимательнее :-) Ошибка на 7 строке, а не на 9
11. redcat - 29 Января, 2009 - 19:02:45 - перейти к сообщению
Может в этом компиляторе переменные по другому обьявляются?
или попробуй через ссылки-

int ms;
int *ss;

int main(void){
ms=1000;
ss = &ms;

............................

_delay_ms(*ss);

.............................
12. бот_м_16 - 29 Января, 2009 - 19:02:53 - перейти к сообщению
и вней тоже Подшучивать, дразнить
(Добавление)
а ты подключил библиотеку с хидером на задержку? как показывает скрин НЕТ
13. redcat - 29 Января, 2009 - 19:09:26 - перейти к сообщению
Да, на скрине не видно нихрена.
delay.h подключен? Может он delay_ms не знает...
14. Blitzkrieg - 29 Января, 2009 - 19:14:43 - перейти к сообщению
redcat пишет:
Странно, компилятор ругается на не правильное использование константы... Почему константа а не переменная? Бред какойто, попробуй другой компилятор может...

Он говорит что ожидалась "целая константа" а я ему "переменную"
Это выглядит странно, но это не я первый с этим столкнулся.
С шим немного разобрался как я понял его можно использовать только на двух выводах, на которые сервы уже подключить не получится.
Значит остался единственный вариант - таймер.
Но примеров нет, а самому чот туго идет.
есть рабочая программка по использованию таймера, но я воще не въезжаю как это дело использовать.
Вот чего в хелпе
Delay_ms
Prototype void Delay_ms(const time_in_ms);

Returns Nothing.

Description Creates a software delay in duration of time_in_ms milliseconds (a constant). Range of applicable constants depends on the oscillator frequency.

This is an “inline” routine; code is generated in the place of the call, so the call doesn’t count against the nested call limit.

Requires Nothing.

CODE:
Example Delay_ms(1000); /* One second pause */


А вот где можно
Vdelay_ms
Prototype void Vdelay_ms(unsigned time_in_ms);

Returns Nothing.

Description Creates a software delay in duration of time_in_ms milliseconds (a variable). Generated delay is not as precise as the delay created by Delay_ms.

Note that Vdelay_ms is library function rather than a built-in routine; it is presented in this topic for the sake of convenience.

Requires Nothing.

Example
CODE:
pause = 1000;
// ...
Vdelay_ms(pause); // ~ one second pause
15. бот_м_16 - 29 Января, 2009 - 19:14:59 - перейти к сообщению
Почему не видно видно
первая строка ште
а в инклуде пустота! Подшучивать, дразнить