Zaslal: po listopad 07 2011, 12:38 Předmět: Problem riadenie serva
Zdravim Vás, mám taký menší problém. Rozhodol som sa riadiť servá z PC pomocou mojej Atmegy8. No problém je v tom, že keď servo pripojím, tak prvý príkaz mi vykoná a natočí sa na požadovanú pomohu, no to je všetko. Na ďalšie príkazy nereaguje. Kód prikladam. Servá neriadim cez ORC port, ale jednotlivé piny. PWM je tvorené softvérovo cez CTC. V prerušení počítam 20ms. Malo by to byť všetko OK, osciloskop bohužiaľ nemám, takže neviem zistiť či to je na 100% tak.
Tak Vás týmto prosím o pomoc. Či som náhodou niekde niečo neprehliadol, stať sa môže všetko
problem vyrieseny. napisal som si to odznova a chyba bola v navratovej hodnote funkcie.
Ale chcel by som sa opýtať na Váš názor. Či mi zvládne procesor ešte niekoľko operácií, ako nejaké AD prevody + odosielanie všetkých dát do PC, bez ovplyvnenia chodu serv? Alebo by bolo idálnejšie ísť s frekvenciou ešte vyššie pre istotu? Teraz tam mam 8MHz
Založen: Oct 30, 2010 Příspěvky: 6661 Bydliště: Praha
Zaslal: po listopad 07 2011, 17:17 Předmět:
Čekat 20 ms v přerušení je špatně. V přerušení jen nastav timer a vrať se do programu. Po uplynutí času přijde přerušení od timeru, obsloužíš ho, znovu nastavíš timer a tak stále dokola a máš téměř veškerý výpočetní čas k dispozici.
Michal
ono je to cez prerusenie, ibaze prerusenie nastava kazdu 1ms, a jeden cyklus je konecny ked prejde 20 preruseni. Iny sposob na ovladanie dvoch serv ma ani nenapada.
mna by len zaujimalo, ci sa da nejak spocitat, ako dlho trva to jedno prerusenie. respektive ci by to niekto vedel. mam taky pocit ze by sa to malo dat cez pocet instrukcii ktore sa vykonavaju nie?
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: po listopad 07 2011, 18:50 Předmět:
Vidím tam vícero věcí. Například se funkce smer() volá jak z main(), tak z rutiny přerušení. Přitom smer() pracuje s globálními proměnnými slovo1 a pohyb. To není dobrý postup. Například na řádku
else if(!strcmp(slovo1,dozae)
v rutime smer()
se slovo 1 otestuje, a než se stačí provést kód na podmínce závislý, tak se může stát, že rutina
ISR(USART_RXC_vect)
to slovo1 přepíše:
slovo1[x]=recchar();
Takže rutina smer() okracuje s hlediska podmínky s vadnými daty.
Obdobně pro data pohyb. Navíc, proč smer() vrací hodnotu pohyb, když tuto hodnotu rovnou nastavuje?
Tvůj kód není moc dobrý.
Při předděliči 1024 trvá jeden krok čítače 128 us.
Pro OCR2 = 8 vychází impuls 8*128 = 1024 us.
Pro OCR2 = 16 vychází impuls 16*128 = 2048 us.
Takže můžeme nastavit jenom 8 nebo 9 poloh serva.
Hodnota OCR2 = 20 v kódu je už mimo rozsah serva.
Nejlépe je použít osvědčený režim Fast pwm a čítač1.
Mimo jiné pak nepotřebujeme přerušení.
kód:
// servo2.c
// Řízení dvou serv, připojených k PB1, PB2
// Atmega8, F_CPU = 8 MHz
// Avr-gcc
mtajovsky:
Takže ak som pochopil dobre, je lepšie hodnotu premennej slovo1 najprv zapísať vo funkcii smer(); do nejakej premenej, napr. temp, definovanej v tejto funkcii a potom túto porovnávať v if?
A to, že vracia funkcia smer(); pohyb je už opravené.
AB1:
Preddeličku mám ale nastavenú na 32. Tak jedno prerušenie pri hodnote OCR=250 je presne 1ms.
V tomto prípade sa strednej hodnote serva rovná OCR 125, a u krajných hodnôt je to 0 a 250. Tam je podľa môjho názoru clekom dostačujúci krok.
Tvoj príklad ma tiež napadol, no vylučuje použitie ďalších serv. No na riadenie auta je určite výhodnejší.
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: út listopad 08 2011, 19:10 Předmět:
pokrivnik napsal(a):
mtajovsky:
Takže ak som pochopil dobre, je lepšie hodnotu premennej slovo1 najprv zapísať vo funkcii smer(); do nejakej premenej, napr. temp, definovanej v tejto funkcii a potom túto porovnávať v if?
To by mohlo být lepší. Musíte ale předpokládat, že přerušení může přijít kdykoliv. Ten problém je obecnější a chce to trochu teorie. V podstatě jde o to, že pokud existuje více úseků programu, které pracují s stejnými proměnnými a mohou být vykonávány asynchronně (z hlediska programu), třeba na základě asynchronního přerušení, tak je potřeba přístup k těm proměnným nějak ošetřit - serializovat. V principu byste měl na dobu, co trvá jak otestování proměnné, tak vykonávání kódu, který je na této proměnné závislý, zakázat přerušení té rutině, která by chtěla proměnnu měnit. Jelikož je nanejvýš žádoucí zakazovat přerušení na nejkratší možnou dobu, je celý program třeba navrhovat s ohledem na tuto potřebu. Vazeb mezi rutinu přerušení a kódem na popředí by mělo být co nejméně, například rutina příjmu znaku by mohla někde uložit znak nebo řetězec a jen signalizovat událost příchodu dat pro běh na popředí, který by měl data co nejrychleji někam převzít a po tuto dobu zakázat přerušení, aby se mu data nezměnila pod rukama. Složitější možnost je jen signalizovat, že si přebírám data, ale potom musí být driver schopen odložit rozpracovanou IO operaci do fronty a ve spolupráci s během na popředí se k ní vrátit po uvolnění dat. Tahle technika byla poprvé uvedena na OS RSX11 firmou DEC a dočtete se o ní na
Několik poznámek:
1. Proměnné, které jsou použity v hlavním programu i v přerušení musí být deklarovány jako volatile.
2. Kód přerušení má být co nejkratší, mimo jiné v něm nemá být volání funkcí.
3. V přerušení COMP nemusíš dorovnávat čas impulsů do 2 ms. Servu je jedno, jestli je mezera mezi impulsy 18, 20 nebo 22 ms.
4. Jestli dobře rozumím, tak z PC chceš jenom testovat pohyb serva doleva nebo doprava.
Potom je lepší posílat servu jednobajtové příkazy, ne stringy které pak musíš pracně dekódovat.
//----- end main -----------------------------------------
ISR(TIMER2_COMP_vect)
{
static uint8_t count;
count++;
switch (count)
{
case 1:
{
SERVO1_ON;
OCR2 = 250;
break;
}
case 2:
{
OCR2 = servo1_puls;
break;
}
case 3:
{
SERVO1_OFF;
SERVO2_ON;
OCR2 = 250;
break;
}
case 4:
{
OCR2 = servo2_puls;
break;
}
case 5:
{
SERVO2_OFF;
OCR2 = 250;
break;
}
case 22:
{
count = 0;
break;
}
}//switch
}
//---------------------------------------------------------------------------
/*
Klávesami A a S posunujeme servo1 na jednu nebo druhou stranu.
Klávesami Q a W řídíme podobně druhé servo.
*/
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.