Stránka 2 z 3

Napsal: 19 lis 2008, 08:43
od Ragnol
Mega8 má jenom 1k paměti, ale nápad je to dobrej a šel by i použít, musela by se použít nějaká mega s větší pamětí.

Napsal: 19 lis 2008, 08:57
od Andrea
Ragnol píše:Mega8 má jenom 1k paměti, ale nápad je to dobrej a šel by i použít, musela by se použít nějaká mega s větší pamětí.
Nechápu co tu vymýšlíte za šílenosti, celé to jde udělat pomocí dvou přerušení, od UARTu a od Timeru a zvládne to i tina2313.

Napsal: 19 lis 2008, 09:46
od Návštěvník
celé to jde udìlat pomocí dvou pøerušení, od UARTu a od Timeru a zvládne to i tina2313
viz konec 1. strany

Napsal: 19 lis 2008, 12:34
od Andrea
Anonym píše:
celé to jde udělat pomocí dvou přerušení, od UARTu a od Timeru a zvládne to i tina2313
viz konec 1. strany
Myslela jsem generovat je softwarově, všech 8 najednou. Samotné generování bez nějaké brutální optimalizace spolkne 35% času procesoru, 65% zbývá na komunikaci, což je až až (v assembleru, ne v C).

Napsal: 19 lis 2008, 14:31
od piitr
A je vážně nutné, aby ty pulzy začínaly nastejně? Když je budu generovat po sobě, tak těch 8 pulzů po 2,5ms se mi do těch 20ms krásně vejde. A v každé chvíli hlídám jen jeden puls, na což mi 2us krásně stačí.

Napsal: 19 lis 2008, 14:49
od Andrea
piitr píše:A je vážně nutné, aby ty pulzy začínaly nastejně? Když je budu generovat po sobě, tak těch 8 pulzů po 2,5ms se mi do těch 20ms krásně vejde. A v každé chvíli hlídám jen jeden puls, na což mi 2us krásně stačí.
Krásně se tam vejdou teoreticky, bez režie. Není nutné aby začínaly nastejně, jen musí začínat vždy ve stejný okamžik, což na předchozí stránce uvedené řešení nesplňuje. Šly by použít dva čítače, jeden bude generovat přerušení po 2.5ms a druhým se bude měřit délka impulsu. Ale 8x 12.5% střída se tam nenacpe, možná 12.4% :)

Napsal: 19 lis 2008, 15:27
od AA
jen musí zaèínat vždy ve stejný okamžik
Ale to je, když dovolíte, omyl.
Postupné posílání impulsù do serv je bìžnì používáno u modeláøských RC souprav.
Pro servo je dùležité, aby každých cca 20 ms dostalo øídící impuls. Celkem ho nezajímá, jestli vedlejší servo dostává svùj impuls souèasnì s ním, nebo jindy.

V mém programu se mi procesor nezdá nijak moc zatížený.
Uart pøijme napø. každých 6 ms 24 bajtù.
Procedura v hlavním programu trvá asi 7 mikrosec a opakuje se nejdøíve za 1 ms.
(Uvažuji nejbìžnìjší rozsah serv 1 až 2 ms.)

Napsal: 19 lis 2008, 15:30
od Andrea
AA píše:
jen musí začínat vždy ve stejný okamžik
Ale to je, když dovolíte, omyl.
Postupné posílání impulsů do serv je běžně používáno u modelářských RC souprav.
Pro servo je důležité, aby každých cca 20 ms dostalo řídící impuls. Celkem ho nezajímá, jestli vedlejší servo dostává svůj impuls současně s ním, nebo jindy.
To jsme si asi nerozumněli. Impuls pro jedno servo musí začínat vždy ve stejný okamžik, jinak by se měnila střída.

Edit:
Ale teď koukám, že ty serva vlastně nekoukají na střídu, ale jen na délku impulsu, tak pak je to úplně jedno. Se omlouvám, dělala jsem s nima jen jednou a už je to nějaký pátek.

Napsal: 19 lis 2008, 15:42
od piitr
No, je fakt, že se to tam nevejde krásně, ale akorát. Muselo by se trošku někde slevit, ale asi ne moc. Kdyby se slevit nechtělo, tak mě napadlo ještě jedno řešení, ale je dost složité:
Pulzy by se překrývaly, ale nezačínaly by všechny nastejně. Jejich začátky a konce by se spočítaly tak, aby:
1) Délky pulzů byly správné.
2) Začátky a konce pulzů byly od sebe dostatečně daleko, aby se neměnily dva výstupy najednou, protože ta změna může zabrat tak 10-20 instrukcí.
Při daných hodnotách si myslím, že by to mělo být vždy spočitatelné.
Má to ale nevýhodu, že při změně hodnoty se bude pohybovat jak náběžná, tak sestupná hrana, ale to by snad až tak nevadilo.

Napsal: 19 lis 2008, 17:44
od K.Pavel
Serva samozrejme nemusi dostavat povel vsechna najednou, musim jenom vyzkouset, jak moc jim vadi rozdilna perioda ridiciho impulsu.
(u posledniho serva se muze dost menit)

Program si predstavuju nejak takto:
(fromat vysilanych dat bude 1byte adresa s MSB=1 a 16byte dat s MSB=0)
(data budou 10b rozdelenych na 3+7)

Kód: Vybrat vše

int vstup[8];
int vystup[9];
unsigned char adresa,prijem[16],prijmout,buff,servo;
//adresa - nastavena adresa tohoto ovladace
//prijem - prijate byte
//prijmout - pocet byte k prijeti
//buff - SW buffer pro RX buffer, ten se myslim po prvnim precteni smaze
//servo - index serva, servo[8] je doplnek do 2ms bez vystupu


Preruseni od UART RX:
{    
    buff=prijaty byte;                               //presunuti hodnoty z RX bufferu
    if(buff>127) prijmout=0;                         //prisla nejaka adresa
    if(buff==adresa) prijmout=15;                    //prisla moje adresa                                              
    if(prijmout>0)                                   //prijem pozic                   
    {
          prijem[15-prijmout]=buff;
          prijmout--;
    }
}

Preruseni citace1 CTC:
{
    PORTA=0;          
    OCR1A=vystup[servo];                             //nastaveni nove hodnoty do citace
    if (servo<8)                                     //servo existuje - yapnout vystup
    {
       PORTA=1<<servo;
       servo++;
    }
    else servo=0;                                    //doplnek, vynulovat index
}

Main:
{
     for (int i=0;i<=7;i++)                               //slepeni 3+7 bitu na 10b
     {
         vstup[i]=0;
         vstup[i]=prijem[2*i]<<7;
         vstup[i]=vstup[i]+prijem[2*i+1];    
     }     
 
     Prepocitat hodnoty z "vstup" do "vystup"             
     
     vystup[8]=40000-vystup[0]-...-vystup[7];             //doplnek do 2ms          
}     

Napsal: 20 lis 2008, 08:26
od piitr
Jo, to je super řešení. Tam se ta režie ani neprojeví. A je to jednoduchý.

Napsal: 20 lis 2008, 08:27
od piitr
Akorát budeš mít trochu problém, když pojede všechno naplno nebo skoro naplno. Pak ten poslední dorovnávací interval vyjde moc krátkej.

Napsal: 20 lis 2008, 11:55
od K.Pavel
piitr:
takze je to pouzitelny?

Toho problemu s poslednim intervalem jsem si vedom, bud prodlouzim o kousek periodu, nebo zkratim maximalni delku pulsu na 2,4ms.

Napsal: 20 lis 2008, 12:56
od piitr
Principielně je to bezva. Ten kód jsem nezkoumal do detailu, ale asi bych trošku upravil to přerušení od čítače. Nelíbí se mi tam to PORTA=0. Tím budeš mít mezi jednotlivými pulzy mezeru.

Kód: Vybrat vše

natahni casovac na vystup[servo]+cas posledniho preruseni;
if ( servo < 8 )
{
    PORTA = 1 << servo;
    servo++;
}
else
{
    PORTA = 0;
    servo = 0;
}
V praxi by to chtělo, aby zpoždění obou větví až k zápisu do PORTA bylo stejné, takže by to asi bylo lepší řešit v assembleru. Kdo ví, jak se přeloží to 1 << servo. S tím natažením timeru si budeš muset pohrát, nevím, jak se to v tom C řeší. Já to řešil u PICu instrukcí ADDWF TMR0 s tím, že je třeba si zjistit, jak se to chová, protože mezi čtením a zápisem do TMR0 se jeho hodnota ještě asi stihne změnit. Chce to kouknout do datasheetu.

Napsal: 20 lis 2008, 13:35
od K.Pavel
Mezera by nemusela byt az tak kriticka a hlavne bude mit nemennou delku, takze to nijak velky problem nebude, pripadne ji muzu zmerit a pridat jako korekci do prepocitavani hodnot.

Ten CTC rezim neustale porovnava hodnotu citace a hodnotou OCR1A a pri souhlasu se snuluje a provede preruseni.
Na ten zapis nove hodnoty bude vzdy minimalne 0,5ms, takze snad casu dost.

Jeste me napadlo, ze by bylo dobre tam pridat osetreni, ze kdyz neprijde vsech 16 datovych bytu, takze se hodnoty zahodi a pouziji se minule, ale to az nekdy.