Ovladani osmi serv pomoci UARTu

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
Ragnol
Příspěvky: 232
Registrován: 09 lis 2005, 01:00
Kontaktovat uživatele:

#16 Příspěvek 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í.

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#17 Příspěvek 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.

Návštěvník

#18 Příspěvek 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

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#19 Příspěvek 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).

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#20 Příspěvek 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čí.

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#21 Příspěvek 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% :)

AA

#22 Příspěvek 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.)

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#23 Příspěvek 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.

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#24 Příspěvek 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.

K.Pavel

#25 Příspěvek 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          
}     

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#26 Příspěvek od piitr »

Jo, to je super řešení. Tam se ta režie ani neprojeví. A je to jednoduchý.

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#27 Příspěvek 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.

K.Pavel

#28 Příspěvek 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.

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#29 Příspěvek 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.

K.Pavel

#30 Příspěvek 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.

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“