Inkrementální enkodér
zpracování signálu
Pro kvalitní řízení robota potřebujeme vědět, jakou vzdálenost robot ujel a jak rychle se pohybuje. Nejpoužívanější metodou pro určení polohy robota je odometrie, která používá informace o otočení kol pro výpočet robotovy pozice (viz. průvodce Odometrie). Potřebujeme tedy snímač, který nám tuto informaci zajistí. Nejčastěji se používají optické inkrementální snímače, buď jako průchozí nebo reflexní optická závora. Bližší popis v průvodci kapitola Enkodéry.
Popis funkce
Výstupem inkrementálního (kvadraturního) enkodéru jsou dva fázově posunuté
signály A, B viz. obrázek. Díky tomu můžeme kromě počtu „tiků“ tj. pootočení
určit i směr pohybu.
|
Zpracování těchto signálů je možno realizovat hardwarově pomocí speciálních obvodů
nebo softwarově.
Hardwarové zpracování
se používá hlavně pro velmi rychlé signály (>10 kHz). Výstupem specializovaných
obvodů je jeden výstup generující impuls při „každé“ změně vstupních signálů
z enkodéru a druhý výstup určuje směr pohybu (tím určíme zda impulsy přičítat či odčítat).
Druhý typ poskytuje dva výstupy, kde jeden poskytuje impulsy při kladném směru pohybu
a druhý při záporném. Takto předzpracovaný signál se obvykle dále přivádí na vstup
rychlého čítače, který realizuje počítání impulsů (obvykle 8 bitů). Tento čítač
poskytuje informaci o změně polohy nadřízenému systému, který musí dostatečně často
vyčítat tuto informaci, aby nedošlo k přetečení hardwarového čítače.
Výhodou tohoto řešení je vysoká rychlost a minimální zatížení nadřazeného systému.
Nevýhodou je vyšší obvodová náročnost řešení a tudíž i cena.
Příkladem obvodů pro dekódování signálu z kvadraturních enkodérů jsou obvody LS708x,
které kromě zpracování signálu zajišťují i filtraci, která zamezuje zpracování
vstupních pulsů o šířce menší, než je nastavená hodnota. Kvadraturní dekodér LS7084
je určený k dekódování kvadraturních signálů A a B na pulsy a směr, LS7083 poskytuje
na jednom výstupu impulsy, které se přičítají, a na druhém impulsy, které se odečítají.
Komplexnější řešení poskytují např. obvody HCTL-2022/2032, které kromě dekódování
signálu obsahují i čítač. Jinou možností je realizace dekódování a následného čítaní
v programovatelných obvodech CPDL, …
Softwarové zpracování
Pro pomalejší signály lze provádět celé vyhodnocení softwarově v jednočipovém počítači.
Toto řešení je z hlediska obvodu jednodušší, levnější, ale přináší zvýšené výpočetní
zatížení mikroprocesoru. Vzhledem výkonu současných mikrokontrolerů a potřebnému výkonu
pro řízení malých robotů to však není problém.
Způsoby dekódování
Průběh výstupního signálu z enkodéru |
Při pohybu generuje výstup enkodéru během jedné periody 4 různé stavy, viz. obrázek.
Pokud provádíme zpracování pouze při jedné změně signálu A (např. při vzestupné hraně)
a signál B použijeme pouze pro určení směru pohybu, pak je rozlišení snímače přímo
rovno počtu štěrbin, či odrazových plošek.
Hlavně u amatérsky vyráběných enkodéru ovšem bývá základní rozlišení příliš nízké,
proto je možné využít dělení celé periody na části. Při využití obou hran kanálu A
získáme dvojnásobné rozlišení a při využití obou hran kanálu A i B dokonce čtyřnásobné
rozlišení.
Způsoby zpracování
Asynchronní
Při asynchronním zpracování je jeden nebo oba výstupní signály enkodéru připojeny
na vstup mikrokontroleru, který je schopen generovat přerušení. Přerušení je vyvoláno při vzestupné, sestupné nebo obou hranách signálů.
Pro dekódování s jednoduchým nebo dvojnásobným rozlišením stačí jeden přerušovací
vstup, pro čtyřnásobné rozlišení jsou nutné dva přerušovací vstupy.
Výhodou asynchronního zpracování je poměrně nízké zatížení procesoru, které však
ze zvětšující se rychlostí roste. Poměrně velkou nevýhodou je, že nelze jednoduše
realizovat filtraci proti zákmitům, které mohou nastat, pokud se enkodér zastaví
na rozhraní sousedních stavů. Tedy toto zpracovaní dobře funguje při pohybu, ale
při zastavení může generovat velké množství falešných tiků bez jednoduché
možnosti ošetření.
Synchronní
Při tomto způsobu zpracování se vyhodnocení provádí v daných časových okamžicích.
To je nejčastěji realizováno periodickým vyvoláváním přerušení od časovače.
Frekvence vzorkování musí být alespoň tak vysoká jako frekvence změn stavů enkodéru,
tj. čtyřnásobek frekvence výstupního signálu enkodéru (malou fintou při dekódování
lze tento požadavek zmírnit téměř na polovinu).
Nevýhodou synchronního zpracování je vyšší, ale stálé zatížení procesoru.
Výhodou je automatické filtrování impulsů, které mají kratší délku než je perioda
vzorkování. Tím je potlačen problém zákmitů výstupů enkodéru při zastavení na hraně.
Příklady realizace softwarového zpracování
Ukázky dékodování jsou psány v jazyku C a používají následující definice:
#define IRC_PORT ... port, na ktery jsou pripojeny vystupy enkoderu
#define PIN_A ... cislo pinu kanalu A enkoderu
#define PIN_B ... cislo pinu kanalu B enkoderu
#define MASK_PIN_A (1<<PIN_A)
#define MASK_PIN_B (1<<PIN_B)
#define MASK_PIN_AB (MASK_PIN_A | MASK_PIN_B)
volatile int Position; ... promenna, ve ktere je poloha enkoderu
#define GetPosition(x) cli(); x = Position; sei()
... cteni pozice musi byt pri zakazanem preruseni
(atomicka operace)
#define PIN_A ... cislo pinu kanalu A enkoderu
#define PIN_B ... cislo pinu kanalu B enkoderu
#define MASK_PIN_A (1<<PIN_A)
#define MASK_PIN_B (1<<PIN_B)
#define MASK_PIN_AB (MASK_PIN_A | MASK_PIN_B)
volatile int Position; ... promenna, ve ktere je poloha enkoderu
#define GetPosition(x) cli(); x = Position; sei()
... cteni pozice musi byt pri zakazanem preruseni
(atomicka operace)
Ukázky asynchronního zpracování jsou psány co nejjednodušším způsobem,
lze je samozřejmě optimalizovat.
Asynchronní dékodování se základním rozlišením
Nastaveno přerušení na vstupu kanálu A při vzestupné hraně
interrupt EXT_PIN_A;
{
if ((IRC_PORT & MASK_PIN_B) == 0) // Je-li při vzestupné hraně A,
Position++; // B = 0, pricti 1 tik
else
Position--; // B = 1, odecti 1 tik
}
{
if ((IRC_PORT & MASK_PIN_B) == 0) // Je-li při vzestupné hraně A,
Position++; // B = 0, pricti 1 tik
else
Position--; // B = 1, odecti 1 tik
}
Asynchronní dékodování s dvojnásobným rozlišením
Nastaveno přerušení na vstupu kanálu A při obou hranách
interrupt EXT_PIN_A;
{
unsigned char IRC;
IRC = IRC_PORT;
if ((IRC & MASK_PIN_A) == 0) // sestupna hrana A kanalu
{
if ((IRC & MASK_PIN_B) == 0)
Position--;
else
Position++;
}
else // vzestupna hrana na A
{
if ((IRC & MASK_PIN_B) == 0)
Position++;
else
Position--;
}
}
{
unsigned char IRC;
IRC = IRC_PORT;
if ((IRC & MASK_PIN_A) == 0) // sestupna hrana A kanalu
{
if ((IRC & MASK_PIN_B) == 0)
Position--;
else
Position++;
}
else // vzestupna hrana na A
{
if ((IRC & MASK_PIN_B) == 0)
Position++;
else
Position--;
}
}
Asynchronní dékodování se čtyřnásobným rozlišením
Nastaveno přerušení na vstupech kanálů A i B při obou hranách
interrupt EXT_PIN_A;
{
unsigned char IRC;
IRC = IRC_PORT;
if ((IRC & MASK_PIN_A) == 0) // sestupna hrana A kanalu
{
if ((IRC & MASK_PIN_B) == 0)
Position--;
else
Position++;
}
else // vzestupna hrana na A
{
if ((IRC & MASK_PIN_B) == 0)
Position++;
else
Position--;
}
}
interrupt EXT_PIN_B;
{
unsigned char IRC;
IRC = IRC_PORT;
if ((IRC & MASK_PIN_B) == 0) // sestupna hrana B kanalu
{
if ((IRC & MASK_PIN_A) == 0)
Position++;
else
Position--;
}
else // vzestupna hrana na B
{
if ((IRC & MASK_PIN_A) == 0)
Position--;
else
Position++;
}
}
{
unsigned char IRC;
IRC = IRC_PORT;
if ((IRC & MASK_PIN_A) == 0) // sestupna hrana A kanalu
{
if ((IRC & MASK_PIN_B) == 0)
Position--;
else
Position++;
}
else // vzestupna hrana na A
{
if ((IRC & MASK_PIN_B) == 0)
Position++;
else
Position--;
}
}
interrupt EXT_PIN_B;
{
unsigned char IRC;
IRC = IRC_PORT;
if ((IRC & MASK_PIN_B) == 0) // sestupna hrana B kanalu
{
if ((IRC & MASK_PIN_A) == 0)
Position++;
else
Position--;
}
else // vzestupna hrana na B
{
if ((IRC & MASK_PIN_A) == 0)
Position--;
else
Position++;
}
}
Synchronní dékodování se čtyřnásobným rozlišením
U synchronního zpracování je nutné kromě aktuálního stavu hodnot kanálů A a B
enkodéru znát i předchozí stav signálů. Dekódování lze realizovat různými způsoby:
vyhodnocením sekvenční logické funkce, stavovým automatem nebo dekódováním grayova kódu.
Příklad ukáže nepříliš často používanou metodu, která vychází z dekódování grayova kódu.
Tento postup lze velmi dobře optimalizovat a dosáhnout tak, velmi nízkého zatížení
procesoru, resp. vysoké frekvence zpracování.
Princip dekódování
Pohyb vpřed |
Pohyb vzad |
První fází zpracování je tedy záměna
hodnot 2 → 3 a 3 → 2. Tím získáme posloupnosti 0, 1, 2, 3, 0, ..., resp.
0, 3, 2, 1, 0,... Nyní pokud tato čísla bereme jako 2-bitová, tak při pohybu
vpřed je jejich rozdíl vždy 1 (1-0=1, 2-1=1, 3-2=1, 0-3=1 s přetečením) a
podobně při pohybu vzad -1. To vše za předpokladu, že jsou výstupy enkodéru
připojeny na piny 0 a 1 vstupního portu mikroprocesoru. Princip lze rozšířit
na libovolné piny, s tím že rozdíl sousedních stavů není ±1 ale ±x.
Jedinou podmínkou je, že kanál A je připojen na nižší pin než kanál B.
Příklad zjednodušené implementace v jazyce C, nastaveno přerušení od časovače.
Není ošetřen stav, kdy dojde ke ztrátě kroku, tj. dojde k posunu o dva stavy a
nelze určit směr pohybu.
unsigned char LastIRC;
interrupt CTC;
{
unsigned char IRC, temp;
IRC = IRC_PORT & MASK_PIN_AB; // cteni stavu enkoderu
if ((IRC & MASK_PIN_B) != 0) // dekodovani grayova kodu, tj.
IRC ^= MASK_PIN_A; // zamena druheho a tretiho stavu
// rozdil soucasneho a predchoziho stavu, maskovani
temp = (IRC – LastIRC) & MASK_PIN_AB;
if (temp == MASK_PIN_A) // test zda je rozdil stavu kladny (+1)
Position++;
else if (temp == MASK_PIN_AB) // nebo zaporny (-1)
Position--;
LastIRC = IRC; // uschovani soucasneho stavu
}
interrupt CTC;
{
unsigned char IRC, temp;
IRC = IRC_PORT & MASK_PIN_AB; // cteni stavu enkoderu
if ((IRC & MASK_PIN_B) != 0) // dekodovani grayova kodu, tj.
IRC ^= MASK_PIN_A; // zamena druheho a tretiho stavu
// rozdil soucasneho a predchoziho stavu, maskovani
temp = (IRC – LastIRC) & MASK_PIN_AB;
if (temp == MASK_PIN_A) // test zda je rozdil stavu kladny (+1)
Position++;
else if (temp == MASK_PIN_AB) // nebo zaporny (-1)
Position--;
LastIRC = IRC; // uschovani soucasneho stavu
}
Kompletní optimalizovaná varianta implementace pro mikroprocesory AVR a
překladač AVR-GCC, obsluha přerušení psána v asembleru. Důvodem je neefektivní
implementace obsluh přerušení v C jazyce, kde jsou ukládány „všechny“ i
nepoužité registry. To představuje téměř zdvojnásobení doby zpracování přerušení.
Optimalizovaná varianta obsluhy přerušení trvá maximálně 55 taktů, což při
taktovací frekvenci 16MHz umožňuje teoreticky vzorkovací frekvenci více než 250 kHz.
Tato hodnota je více než dostatečná pro běžné enkodéry. Je ošetřen i stav
ztráty stavu, který může nastat, je-li frekvence signálu z enkodéru vyšší než
frekvence vzorkování.
Informační zdroje:
- inspirace pro dekódování IRC jako grayova kódu a velice zajímavě řešený kaskádní PID regulátor