Форум по Роботика
Технически форум => Общ форум => Темата е започната от: hunter в Юли 18, 2009, 05:14:58 pm
-
Здравейте, имам следния въпрос за контрол на серво понеже несъм се занимавъл и не съм писъл код за контрол на серво а си бях закупил от spp 4 броя и ми се иска вече да ги подкарам идеята е, че искам да се върти напред и на зад искам и да му запазя електрониката в него разбра че със премахване на потенциометъра и ако го имитиръм с два резистора го лъжа в оправлението че е винаги в средата дотук добре но как да му задам да върти напред и как за назад в програмата командването било от 1 до 2 милисекунди мисля че така беше но не ми е много ясно малко помощ ако може ще се радвам :) И като цяло даите да развиеме тази тема за серва контрола им с примери снимков матерял за по нагледно и за хора като мен които сега прохождат в управлението на серва :) Междудругото попаднах на това но като незная английски спичам и само картинки а те не са достатъчни ето линк
http://www.seattlerobotics.org/guide/servos.html
-
Някй някъде във форума беше споменал че управлението става не само с милисекунди но и с някъква честота тази честота съдейки по картинкита на линка дето дадох в какво се изразява тоест единицата ли е с честота и времетраене или нулата е с честота а еденицата само с времетраене?
-
Здравей :)
Периода на високо ниво на импулсите към сервото е от 1 до 2ms, като честота трябва да е около 50Hz. Като махнеш потенциометъра и сложиш двата резистора лъжеш сервото, че се намира в централно положение. Ако ме подадеш 1ms, то ще тръгне да се върти с максимална скорост в една посока, а при 2ms в другата. А ако му пращаш 1.5ms няма да се върти. Ако се занимаваш с PIC и С мога да ти напиша пример :)
-
sv_shady много благодаря за отговора занимавам се с PIC но на Асемблер за жалост, ти ми беше пращал програми за С по скайпа мисля беше компилатор но ме няма в С-то на Асемблера си чета от книгата на млад конструктор и се справям просто ми трябваха обяснения но не е излишно да се драсне примерен код дори и на С за други любители които проявяват интерес съдейки по това което писа че при 1мс сервото ще тръгне с максимална скорост да разбирам ли че може и да му се влияе на скороста :)
-
Ами на повечето сервота може, само най-най-евтините нямат заложена тази възможност.
-
Ми моите не ги знам какви са но маи са такива
http://robotics-bg.com/forum/viewtopic.php?t=585
дето ги предлага spp
-
Така нищо не мога да ти кажа, просто трябва да ги пробваш :)
-
А може ли да направиш нещо като диаграма за по-голяма яснота по отношение на високото ниво и честотата примерно като това
-
Ще пуснете ли кодове за Atmega (за която можете)?
-
Линка, който си дал не работи, но предполагам, че ти трябва нещо такова:
http://upload.robotics-bg.com/files/ServoControl.png
За по лесно може Toff винаги да е равно на 20ms, като така честотата ще е около 50Hz, което в повечето случаи не е проблем.
-
Е браво точно за това говорех :) А това което бях дал на линка е почти същото.
-
Така ето и една съвсем семпла функция на 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 пъти и от там разчитаме електрониката на сервото да пази желания ъгъл на завъртане, при външно въздействие (което е вградено вече в почти всички серва). Надявам се функцийката да бъде полезна и да демонстрира, как на пръв поглед сложни неща, могат да бъдат семпло реализирани.
-
Знам че темата е стара, но се зачетох. Само да попитам. Ако искаме да постигнем това - 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));
}
}
?
-
По горе съм го обяснил:
За по лесно може Toff винаги да е равно на 20ms, като така честотата ще е около 50Hz, което в повечето случаи не е проблем.
Общо взето електрониката на сервото не е толкова чуствителна, че да усети разликата. Но ако контролера няма с какво друга да се занимава винаги може да прави още едно изваждане допълнително :)
-
Здравейте,
Искам да се вкюча само с една забелжка. Няма период на ниско или на високо ниво. Период има на сигнала (на поредицата от импулси). А това, за което говорите е продължителност. Казвам го, защото лично аз се заблудих отначало и взех да се чудя какъв е тоя период на високото ниво и как при 2ms период имаме 50Hz честота. След като видях диаграмите разбрах за какво става въпрос, но мисля че е редно да се изказваме, както си трябва.
П.С. Не искам никой да обидя или да се заяждам, просто пояснение, защото стават обърквания Smile
Поздрави!
_____________
-
Ами да може би е по-правилно се нарече продължителност, за да не се бърка с термина "период". Хубавото е поне, че от диаграмата са се изчистили неяснотите. Ако трябва да бъдем най-точни трябва да говорим за коефициент на запълване, но тогава има разни сметки и ако го видиш за първи път далеч няма да ти е ясно.
-
Съгласен съм с теб, че най-точно е да се каже коефициент на запълване, но ако наистина не разбираш от тези неща ще се чудиш за какво става върпос :)
-
Ето и един код (отново на 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' и другият обработваше информацията така, като трябва).