Управление сервой с помощью потенциометра. МК PIC16F887

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

Управление сервой с помощью потенциометра. МК PIC16F887

Сообщение kotikov » 08 июл 2010, 20:12

Всем привет!

Задача - задавая поворот ручки потенциометра менять угол поворота сервы.
Я учусь и не могу закончить код. Нужна ваша помощь. Не знаю как связать сигнал от потенциометра с импульсами для сервы.
Придумал на мой взгляд неказистое решение - завязать частоту работы АЦП, которую контролирует потенциометр с переменной для сервы, которая задавала бы импульсы. Но опять же не придумал нужного математического решения.

Подскажите как можно упростить и решить данную задачу?

В наличии:
Отладочная плата с мк PIC16F887
Потенциометр ZX-110
Серва HS-422
Программатор, МикроС.

Схема платы
IMG_0089.JPG

Серва включена в порт RC5 (находится в самом центре схемы)
Потенциометр включен в RA3 (Снизу слева)

Так как код не работает, потому что не закончен выложу его голым, а не проектом.
Код: Выделить всё
void main()
{
ANSEL=0xFF;             //PORTA назначаем анлоговым
TRISA=0xFF;             //PORTA назначаем входом
ADCON0=0b11001101;           //режим: RC_Mode (11) ANALOG1(0011) GO(0) ADON(1)

while(1)                   
      {
      ADCON0.GO=1;                   //запуск цикла анлогово-цифрового преобразоватея
      while(ADCON0.GO);           // ожидание завершения пробразования
      x=(ADRESH*4)+(ADRESL/64);
      }
while(1)
    {
TRISC.F5 =0;         
ANSEL=0x00;
ANSELH=0x00;

PORTC.F5=1;       
delay_us(2400);   

PORTC.F5=0;         
delay_ms(30);   
     }

}


Сервомашинки. Устройство, принцип работы.
http://www.rcdesign.ru/articles/radio/servo_intro
http://www.rcdesign.ru/articles/radio/digital_servos
Последний раз редактировалось kotikov 14 июл 2010, 01:24, всего редактировалось 2 раз(а).
kotikov
 
Сообщения: 24
Зарегистрирован: 28 июн 2010, 11:58
Откуда: СПб
Skype: dmitry.kotikov
ФИО: Котиков Дмитрий

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение avr123.nm.ru » 08 июл 2010, 21:39

Код получаемый в результате АЦП надо преобразовать в ширину импульса управления серво. Например если АЦП в диапазоне 0-1023 то к нему надо добавить 1000. Получим нормальный диапазон ширины сервоимпулса в микро сек.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение kotikov » 09 июл 2010, 10:11

Диапазон ширины импульса для сервы составляет 500-2400.

Если в начале производить вычесление Х
x=(ADRESH*4)+(ADRESL/64)+1000;

а затем поставить Х в функцию работы сервы

PORTC.F5=1;
delay_ms(x);
PORTC.F5=0;
delay_ms(30);

То ничего не выходит.
Как это сделать правильно? Объясните попроще.
kotikov
 
Сообщения: 24
Зарегистрирован: 28 июн 2010, 11:58
Откуда: СПб
Skype: dmitry.kotikov
ФИО: Котиков Дмитрий

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение avr123.nm.ru » 09 июл 2010, 10:28

МИКРО схекунды надо использовать.

И 18 мили сек между импульсами.

И PROTEUS рекомендую - http://proteus123.narod.ru
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение kotikov » 09 июл 2010, 10:57

Изобразите несколько строчек кода, так мне хоть наглядно будет понятно о чем речь идет и как это должно выглядеть. Как именно(кодом) преобразовать работу АЦП в импульсы для сервы?

Я так понял вы это имеете ввиду?
PORTC.F5=1;
delay_ms(x); //как изобразить микросекунды? x/10^3 ? =)
PORTC.F5=0;
delay_ms(18); // здесь теперь 18 миллисекунд

Портес в данный момент изучаю...
kotikov
 
Сообщения: 24
Зарегистрирован: 28 июн 2010, 11:58
Откуда: СПб
Skype: dmitry.kotikov
ФИО: Котиков Дмитрий

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение Zeus » 09 июл 2010, 11:20

Если пользуешь "mikroC PRO for PIC", то там есть такие процедуры:
1) Delay_Cyc(х); /* Hundred MCU cycles pause */
2) Delay_ms(х); /* Millisecond pause */
3) Delay_us(х); /* Microsecond pause */
Может и в вашем микроС есть такое...
«Сон разума рождает чудовищ»
Аватара пользователя
Zeus
 
Сообщения: 862
Зарегистрирован: 28 июл 2009, 10:02
Откуда: Самара
ФИО: Павел Сергеевич

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение kotikov » 09 июл 2010, 12:43

Zeus писал(а):Если пользуешь "mikroC PRO for PIC", то там есть такие процедуры:
1) Delay_Cyc(х); /* Hundred MCU cycles pause */
2) Delay_ms(х); /* Millisecond pause */
3) Delay_us(х); /* Microsecond pause */
Может и в вашем микроС есть такое...

Да, микро С про. Процедуры такие есть.
Теперь ясно как задать микросекнуды.

Если скажемм я ввиду такое, то серва повернется на определенный угол и будет его держать. Как сделать чтобы значение delay_us(); можно было менять?
PORTC.F5=1;
delay_us(2000);
PORTC.F5=0;
delay_ms(18);

Если я вычеслю по формуле частоту процессора и прибавлю 1000, а затем подставлю х в значение delay_us(); то он выдает ошибку.

...
x=(ADRESH*4)+(ADRESL/64)+1000;
...
PORTC.F5=1;
delay_us(x);
PORTC.F5=0;
delay_ms(18);
...

Перед тем как подставить Х его надо как-то преобразовать?
kotikov
 
Сообщения: 24
Зарегистрирован: 28 июн 2010, 11:58
Откуда: СПб
Skype: dmitry.kotikov
ФИО: Котиков Дмитрий

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение Zeus » 09 июл 2010, 12:59

Delay_us
Prototype void Delay_us(const unsigned long time_in_us);

Returns Nothing.

Description Creates a software delay in duration of time_in_us microseconds (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. This routine generates nested loops using registers R13, R12, R11 and R10. The number of used registers varies from 0 to 4, depending on requested time_in_us.

Requires Nothing.

Example Delay_us(1000); /* One millisecond pause */

Читайте встроенный хелп к мироС.

Добавлено спустя 4 минуты 52 секунды:
Re: Управление сервой с помощью потенциометра. МК PIC16F, язык С
тут наверное придется самому писать процедуру задержки от Х в микросекундах.
есть еще:
void Vdelay_ms(unsigned time_in_ms);
и
void VDelay_Advanced_ms(unsigned time_in_ms, unsigned Current_Fosc_kHz);

но они в милисекундах работают...
«Сон разума рождает чудовищ»
Аватара пользователя
Zeus
 
Сообщения: 862
Зарегистрирован: 28 июл 2009, 10:02
Откуда: Самара
ФИО: Павел Сергеевич

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение avr123.nm.ru » 09 июл 2010, 13:02

while(1) будет молотиь и не переходить на следующий while(1)
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение Zeus » 09 июл 2010, 13:04

Так как код не работает, потому что не закончен выложу его голым, а не проектом.
«Сон разума рождает чудовищ»
Аватара пользователя
Zeus
 
Сообщения: 862
Зарегистрирован: 28 июл 2009, 10:02
Откуда: Самара
ФИО: Павел Сергеевич

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение avr123.nm.ru » 09 июл 2010, 13:52

в void VDelay_Advanced_ms(unsigned time_in_ms, unsigned Current_Fosc_kHz);

частоту в 1000 раз больше указать - получи микро сек. с переменной. :ROFL:

Подсказали, что поделить на 1000 надо !
Последний раз редактировалось avr123.nm.ru 09 июл 2010, 15:28, всего редактировалось 1 раз.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение Duhas » 09 июл 2010, 14:44

мб меньше ?
«Как сердцу выразить себя? … Мысль изреченная есть ложь!»
В этом мире меня подводит доброта и порядочность...
"двое смотрят в лужу, один видит лужу, другой отраженные в ней звезды"
Аватара пользователя
Duhas
 
Сообщения: 6338
Зарегистрирован: 15 сен 2007, 13:03
Откуда: Красноярск
прог. языки: ASM(МК), C(PC)
ФИО: Гагарский Андрей Александрович

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение avr123.nm.ru » 09 июл 2010, 15:24

Может быть.
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение kotikov » 09 июл 2010, 16:05

Есть успехи.
Вспомнил что существуют пропорции и сделал зависимость работы АЦП и импульсов для сервы.
Для проверки правильности написал небольшую программу которая выводит на экран частоту АЦП и вычисленные значения для серв (500-2400). Ниже представлены видео, рабочий код программы и архив проекта.


Как заставить серву работать от этой зависимости я НЕ знаю, потому что если делать так, то не работает
PORTC.F5=1;
delay_ms(i);
PORTC.F5=0;
delay_ms(30);
где i - получаемое значение из пропорции (от 500 до 2400)

Как регулировать delay_ms(i); ? Вот уже есть переменная выдающая нужные значения. как их применить?
В коде ниже переменная i отвечает за вычисления импульса для серв.
Код: Выделить всё
char data1[6];
char data2[6];
int x,i;
void main()
{
Lcd_Init(&PORTD);     
Lcd_Cmd(LCD_CURSOR_OFF); //курсор жки выключен
Lcd_Out(1,1,"ADC=");           // показать текст строка 1, нач. с символа 1
Lcd_Out(2,1,"servo=");           // показать текст строка 1, нач. с символа 1
TRISC.F5 =0;
TRISB.F4 =0;
TRISB.F5 =0;
ANSEL=0xFF;          //PORTA назначаем анлоговым
TRISA=0xFF;          //PORTA назначаем входом
ANSEL=0x00;
ANSELH=0x00;

while(1)
    {
ADCON0=0b11001101;           //режим: RC_Mode (11) ANALOG1(0011) GO(0) ADON(1)
while(1)
      {
      ADCON0.GO=1;          //запуск цикла анлогово-цифрового преобразовател€
      while(ADCON0.GO);     // ожидание завершени€ пробразовани€
      x=(ADRESH*4)+(ADRESL/64);
      WordToStr(x,data1);
       Lcd_Out(1,12,data1);
       Delay_ms(100);         

      i=(1900/100)*(x/(1020/100));
      i=i+500;
      WordToStr(i,data2);
      Lcd_Out(2,12,data2);   
      Delay_ms(100);         

       }

    }
}

kotikov
 
Сообщения: 24
Зарегистрирован: 28 июн 2010, 11:58
Откуда: СПб
Skype: dmitry.kotikov
ФИО: Котиков Дмитрий

Re: Управление сервой с помощью потенциометра. МК PIC16F, яз

Сообщение Zeus » 09 июл 2010, 16:33

Я уже писал процедура void Delay_ms(const unsigned long time_in_ms);
Переведу на русский - переменная time_in_ms или ваше i должны быть константой!!! они не могут меняться в процессе работы, а определяются на момент компиляции!
Не правильно: delay_ms(i);
Правильно: delay_ms(30); или const unsigned long i = 30; delay_ms(i);

Для работ с переменный есть другие процедуры:

1. Процедура Vdelay_ms
Prototype - void Vdelay_ms(unsigned time_in_ms);

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.
Программная задержка в "условных" "time_in_ms" милисекунах, которая не привязана к частоте кварца.

Example pause = 1000;
// ...
Vdelay_ms(pause); // ~ one second pause
Минимальное значение 1 мс (не считаю 0 :)).

2. Процедура VDelay_Advanced_ms (изначально предназначена для генерации милисекунд)
Prototype - void VDelay_Advanced_ms(unsigned time_in_ms, unsigned Current_Fosc_kHz);

Description Creates a software delay in duration of time_in_ms milliseconds (a variable), for a given oscillator frequency. Generated delay is not as precise as the delay created by Delay_ms.
Программная задержка в "реальных" "time_in_ms" милисекунах, которая привязана к частоте кварца.

Example pause = 1000;
fosc = 10000; (Частоту вводим в килогерцах, т.е. 10МГц/1000=10000 кГц)

VDelay_Advanced_ms(pause, fosc); // Generates approximately one second pause, for a oscillator frequency of 10 MHz

unsigned = 0...65535, так что максимум типа 65,535 МГц.
Так что четкие и правильные микросекунды этой процедурой не получить.
При кварце 10МГц можно конечно ввести 50000, тогда при time_in_ms = 1 может быть задержка будет 0,2 мс или 200 мкс...

Добавлено спустя 8 минут 2 секунды:
Re: Управление сервой с помощью потенциометра. МК PIC16F, язык С
Потому и говорю, что проще написать свою процедуру для "микросекунд" или машинных инструкций.
типа пустого цикла с переменной i или ему подобного...

Добавлено спустя 9 минут 32 секунды:
Re: Управление сервой с помощью потенциометра. МК PIC16F, язык С
И еще...
эти процедуры с большой натяжкой можно назвать процедурами...

"...Built-in Routines
mikroC PRO for PIC compiler provides a set of useful built-in utility functions. Built-in functions do not require any header files to be included; you can use them in any part of your project.

Built-in routines are implemented as “inline”; i.e. code is generated in the place of the call, so the call doesn’t count against the nested call limit. The only exceptions are Vdelay_ms, Delay_Cyc and Get_Fosc_kHz which are actual C routines.

Note: Lo, Hi, Higher and Highest functions are not implemented in compiler any more. If you want to use these functions you must include built_in.h into your project..."

Перевод гугль:
"Встроенные подпрограммы
mikroC PRO для компилятора ПОС предоставляет множество полезных встроенных функций полезности. Встроенные функции не требует каких-либо файлы заголовков, которые должны быть включены, вы можете использовать их в любую часть вашего проекта.

Встроенные процедуры реализуются как "встроенные", т.е. код генерируется на место вызова, так что вызов не засчитываются вложенных ограничения стека. Исключение составляют лишь Vdelay_ms, Delay_Cyc и Get_Fosc_kHz, которые являются действительно процедурами C.

Примечание: Lo, Hi, Higher and Highest функции не реализованы больше в компиляторе. Если вы хотите использовать эти функции, вы должны включить built_in.h в ваш проект."
«Сон разума рождает чудовищ»
Аватара пользователя
Zeus
 
Сообщения: 862
Зарегистрирован: 28 июл 2009, 10:02
Откуда: Самара
ФИО: Павел Сергеевич

След.

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

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

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