Форум по Роботика

Технически форум => Общ форум => Темата е започната от: hunter в Юли 18, 2009, 05:14:58 pm

Титла: Серво контрол
Публикувано от: hunter в Юли 18, 2009, 05:14:58 pm
Здравейте, имам следния въпрос за контрол на серво понеже несъм се занимавъл и не съм писъл код за контрол на серво а си бях закупил от spp 4 броя и ми се иска вече да ги подкарам идеята е, че искам да се върти напред и на зад искам и да му запазя електрониката в него разбра че със премахване на потенциометъра и ако го имитиръм с два резистора го лъжа в оправлението че е винаги в средата дотук добре но как да му задам да върти напред и как за назад в програмата командването било от 1 до 2 милисекунди мисля че така беше но не ми е много ясно малко помощ ако може ще се радвам :) И като цяло даите да развиеме тази тема за серва контрола им с примери снимков матерял за по нагледно и за хора като мен които сега прохождат в управлението на серва :) Междудругото попаднах на това но като незная английски спичам и само картинки а те не са достатъчни ето линк
http://www.seattlerobotics.org/guide/servos.html
Титла: Серво контрол
Публикувано от: hunter в Юли 18, 2009, 05:41:38 pm
Някй някъде във форума беше споменал че управлението става не само с милисекунди но и с някъква честота тази честота съдейки по картинкита на линка дето дадох в какво се изразява тоест единицата ли е с честота и времетраене или нулата е с честота а еденицата само с времетраене?
Титла: Серво контрол
Публикувано от: sv_shady в Юли 18, 2009, 11:03:19 pm
Здравей :)
Периода на високо ниво на импулсите към сервото е от 1 до 2ms, като честота трябва да е около 50Hz. Като махнеш потенциометъра и сложиш двата резистора лъжеш сервото, че се намира в централно положение. Ако ме подадеш 1ms, то ще тръгне да се върти с максимална скорост в една посока, а при 2ms в другата. А ако му пращаш 1.5ms няма да се върти. Ако се занимаваш с PIC и С мога да ти напиша пример :)
Титла: Серво контрол
Публикувано от: hunter в Юли 18, 2009, 11:37:27 pm
sv_shady много благодаря за отговора занимавам се с PIC но на Асемблер за жалост, ти ми беше пращал програми за С по скайпа мисля беше компилатор но ме няма в С-то на Асемблера си чета от книгата на млад конструктор и се справям просто ми трябваха обяснения но не е излишно да се драсне примерен код дори и на С за други любители които проявяват интерес съдейки по това което писа че при 1мс сервото ще тръгне с максимална скорост да разбирам ли че може и да му се влияе на скороста :)
Титла: Серво контрол
Публикувано от: sv_shady в Юли 18, 2009, 11:47:45 pm
Ами на повечето сервота може, само най-най-евтините нямат заложена тази възможност.
Титла: Серво контрол
Публикувано от: hunter в Юли 18, 2009, 11:53:37 pm
Ми моите не ги знам какви са но маи са такива
http://robotics-bg.com/forum/viewtopic.php?t=585
дето ги предлага spp
Титла: Серво контрол
Публикувано от: sv_shady в Юли 19, 2009, 01:07:27 am
Така нищо не мога да ти кажа, просто трябва да ги пробваш :)
Титла: Серво контрол
Публикувано от: hunter в Юли 19, 2009, 09:14:40 am
А може ли да направиш нещо като диаграма за по-голяма яснота по отношение на високото ниво и честотата примерно като това
Титла: Серво контрол
Публикувано от: kristiman в Юли 19, 2009, 08:17:10 pm
Ще пуснете ли кодове за Atmega (за която можете)?
Титла: Серво контрол
Публикувано от: sv_shady в Юли 20, 2009, 10:42:28 am
Линка, който си дал не работи, но предполагам, че ти трябва нещо такова:
http://upload.robotics-bg.com/files/ServoControl.png
За по лесно може Toff винаги да е равно на 20ms, като така честотата ще е около 50Hz, което в повечето случаи не е проблем.
Титла: Серво контрол
Публикувано от: hunter в Юли 20, 2009, 10:52:39 am
Е браво точно за това говорех :) А това което бях дал на линка е почти същото.
Титла: Серво контрол
Публикувано от: sv_shady в Юли 20, 2009, 10:02:05 pm
Така ето и една съвсем семпла функция на C, която може да сложите във вашия код и да управлявате серво. Първо трябва да кажа, че функцията е компилирана и тествана на CCS 4.084.
void rotate_servo(int angle) // -90 < angle < 90
{
   int i, us;
   us = 1000 + ((90 + angle)/180) * 1000;
   for(i = 0; i < 10; i++)
   {
      output_bit(PIN_A0, 1);
      delay_us(us);
      output_bit(PIN_A0, 0);
      delay_ms(20);
   }
}


angle е стойността на ъгъла, на който желаете завъртане.
Приел съм, че сервото е свързано с PIN_A0, но може да го промените, дори и като аргумент да бъде ако желаете. Попринцип е желателно сигналите към сервото да се пращат постоянно, но тъй като е хубаво контролера да не се занимава само с тази задача, за това импулсът се изпраща 10 пъти и от там разчитаме електрониката на сервото да пази желания ъгъл на завъртане, при външно въздействие (което е вградено вече в почти всички серва). Надявам се функцийката да бъде полезна и да демонстрира, как на пръв поглед сложни неща, могат да бъдат семпло реализирани.
Титла: Серво контрол
Публикувано от: Raev в Ноември 12, 2009, 08:11:49 pm
Знам че темата е стара, но се зачетох. Само да попитам. Ако искаме да постигнем това - http://upload.robotics-bg.com/files/ServoControl.png не би ли трябвало кода да е така:
void rotate_servo(int angle) // -90 < angle < 90
{
   int i, us;
   us = 1000 + ((90 + angle)/180) * 1000;
   for(i = 0; i < 10; i++)
   {
      output_bit(PIN_A0, 1);
      delay_us(us);
      output_bit(PIN_A0, 0);
      delay_ms(20-(us/1000));
   }
}

?
Титла: Серво контрол
Публикувано от: sv_shady в Ноември 13, 2009, 04:02:09 pm
По горе съм го обяснил:
Цитат
За по лесно може Toff винаги да е равно на 20ms, като така честотата ще е около 50Hz, което в повечето случаи не е проблем.

Общо взето електрониката на сервото не е толкова чуствителна, че да усети разликата. Но ако контролера няма с какво друга да се занимава винаги може да прави още едно изваждане допълнително :)
Титла: Серво контрол
Публикувано от: IbT в Ноември 20, 2009, 01:27:54 pm
Здравейте,
Искам да се вкюча само с една забелжка. Няма период на ниско или на високо ниво. Период има на сигнала (на поредицата от импулси). А това, за което говорите е продължителност. Казвам го, защото лично аз се заблудих отначало и взех да се чудя какъв е тоя период на високото ниво и как при 2ms период имаме 50Hz честота. След като видях диаграмите разбрах за какво става въпрос, но мисля че е редно да се изказваме, както си трябва.

П.С. Не искам никой да обидя или да се заяждам, просто пояснение, защото стават обърквания Smile

Поздрави!
_____________
Титла: Серво контрол
Публикувано от: sv_shady в Ноември 20, 2009, 04:08:37 pm
Ами да може би е по-правилно се нарече продължителност, за да не се бърка с термина "период". Хубавото е поне, че от диаграмата са се изчистили неяснотите. Ако трябва да бъдем най-точни трябва да говорим за коефициент на запълване, но тогава има разни сметки и ако го видиш за първи път далеч няма да ти е ясно.
Титла: Серво контрол
Публикувано от: IbT в Ноември 20, 2009, 06:42:37 pm
Съгласен съм с теб, че най-точно е да се каже коефициент на запълване, но ако наистина не разбираш от тези неща ще се чудиш за какво става върпос :)
Титла: Серво контрол
Публикувано от: Alternative в Ноември 24, 2009, 07:04:34 pm
Ето и един код (отново на CCS) за управляването на серво чрез adc модула на микроконтролера


#device adc=8 // ako adc=10, то долу трябва да е разделено на 1024
#define min_pulse 500
#define max_pulse 2400

void main(){
int i;
/*
code
*/
set_adc_channel(0); // PIN_A0

for (;;)
     for (i=0;i<50;i++){
          k=read_adc();
          pulse_width=min_pulse + (max_pulse-min_pulse)/256*k;
          output_bit(PIN_A1,1);  //Servo pin High - Pulse Start
          delay_us(pulse_width);
          output_bit(PIN_A1,0); //Servo pin Low - Pulse End
          delay_us(20000-pulse_width);
      }  
}


Но имам въпрос- Когато искам да изпратя от друг микроконтролер на къде да се върти, се получава така, че сервото всъщност не реагира на промяната на тримера и "държи" в първоначалната позиция.

Кодът на получаващият микроконтролер :

unsigned char k;
for(;;){
       for(i=0;i<50;i++){
          k=getc();
          pulse_width=min_pulse + (max_pulse-min_pulse)/256*((int)k);
       
          output_bit(PIN_A1,1);
          delay_us(pulse_width);
          output_bit(PIN_A1,0);
          delay_us(20000-pulse_width);
      }  
   
  }


Кодът на изпращащият микроконтролер :

set_adc_channel(0);
for(;;){
      data=read_adc();
      putc(data);
      delay_ms(20); //да изчака др. микроконтролер да бъде готов
   }



RS-232 работи до колкото знам добре (тествах го да изпраща 'A' или 'B' и другият обработваше информацията така, като трябва).