Picaxe a více serv

Je možné ovládat jedním mikrokontrolérem Picaxe více modelářských serv? I když odpověď lze nalézt v příručkách, někteří v tom mají stále nejasno.

Příklady budou uváděny pro mikrokontrolér Picaxe 20M2, který se stal víceméně standardem. Budeme předpokládat jednoduché modelářské servo ovládané kladnými pulzy s proměnlivou šířkou od 1,0 do 2,0 ms a opakované přibližně po 20 ms. Ve všech případech se budeme snažit, aby servo plnou rychlostí přejíždělo mezi krajními polohami s dostatečnou prodlevou na jízdu i zastavení. Programy obsahují jen nejnutnější povely, ošetření dalších věcí (aby si program nastavil typ mikrokontroléru, aby se zbytečně nepřepisovala obsah eeprom, …. ) zanedbávají, pokud je to možné, budou pracovat při výchozím kmitočtu hodin (v našem případě 4 MHz).


Nejprve budeme chtít ovládat jen jedno servo. Řízení serva je připojené na výstup B.0. Máme dvě základní možnosti.

1/ Využijeme příkazy SERVO pro inicializaci a SERVOPOS pro následné změny polohy serva. Výhodou je, že signál pro servo bude generován časovačem velmi přesně a náš program se může věnovat čemukoli jinému, není nutné sledovat časování. Nezabýváme se vznikem jednotlivých pulzů, jen měníme jejich délku (polohu serva) když je potřeba. Nevýhodou je, že tím obsadíme časovač a nelze tedy souběžně používat třeba povel PWM, který by časovač také vyžadoval.

REM Picaxe 20M2, jedno servo přes časovač
servo B.0,100        ;inicialize na pin B.0, výchozí pulzy 1,00 ms
do
  servopos B.0,100   ;nastavit pulzy na 1,00 ms
  pause 3000         ;dělám cokoli, trvá to 3 s
  servopos B.0,200   ;nastavit pulzy na 2,00 ms
  pause 3000         ;dělám cokoli, trvá to 3 s
  loop

2/ Využijeme přílaz PULSOUT pro generování každého jednotlivého pulzu pro servo, musíme sami v programu zajistit přesné časování, aby pulzy byly generovány každých 20 ms (naštěstí to není nijak moc kritické, když to bude 15 nebo až 25 ms, na chodu serva se to projeví jen málo). Časovač se dá použít k libobolnému jinému účelu. Mikrokontolér se musí generování pulzů věnovat přednostně a víceméně zcela, časování ostatního běhu programu musí být generování pulzů podřízeno! Ani tak nebudou pulzy naprosto přesné a stabilní.

REM Picaxe 20M2, jedno servo bez časovače
do
  for b0 = 1 to 150    ;150 cyklů = 3 s
    pulsout B.0,100    ;generovat jeden pulz 1,00 ms
    pause 16           ;počkat přesně 16 ms
    next b0            ;3 ms trvá provedení ostatních povelů    
  for b0 = 1 to 150    ;150 cyklů = 3 s
    pulsout B.0,200    ;generovat jeden pulz 2,00 ms
    pause 16           ;počkat přesně 16 ms
    next b0            ;3 ms trvá provedení ostatních povelů
  loop

Budeme chtít ovládat více serv, například 8. Jejich ovládací pulzy budou na pinech B.0 až B.7.  Pozor na to, že když používáme širší pulzy než 2,00 ms (respektive 2,5 ms), nemusí se vejít do opakovacího rámce 20 ms! Opět máme dvě možnosti podobně jako v předchozím případě.

1/ Pomocí časovače, ale to lze využít jen na pinech B.0 až B.7, na pinech portu C ne. 8 serv je maximum, které takto lze řídit. Program se stará jen o změny, jednotlivé pulzy obslouží časovač.

REM Picaxe 20M2, 8 serv přes časovač
servo B.0,100          ;inicializace pulzů na piny B.0 až B.7 a pulzy 1,0 ms
servo B.1,100
servo B.2,100
servo B.3,100
servo B.4,100
servo B.5,100
servo B.6,100
servo B.7,100

do                     ;další část progranu se stará o změny - kývání servy
  servopos B.0,200     ;servo 0 na 3s vychýlit
  servopos B.7,100     ;současně předchozí servo vrátit do původní polohy
  pause 3000
  servopos B.1,200     ;servo 1 ...
  servopos B.0,100
  pause 3000
  servopos B.2,200     ;servo 2 ...
  servopos B.1,100
  pause 3000  
  servopos B.3,200     ;servo 3 ...
  servopos B.2,100
  pause 3000
  servopos B.4,200     ;servo 4 ...
  servopos B.3,100
  pause 3000
  servopos B.5,200     ;servo 5 ...
  servopos B.4,100
  pause 3000
  servopos B.6,200     ;servo 6 ...
  servopos B.5,100
  pause 3000
  servopos B.7,200     ;servo 7 ...
  servopos B.6,100
  pause 3000        
  loop

2/ Podobně jako v předchozím případě můžeme pulzy generovat programem bez časovače, který může být použit na jinou činnost (ale ne úplně libovolně, to se ukáže v následujícím příkladu). Budeme opět vázáni na piny portu B, abychom mohli použít zjednodušené adresování pinů přes proměnnou v cyklu, obecně by šlo použít kterýkoli výstup. Pro 8 serv to už bude docela honička, mikrokontrolér nic jiného zvládat nebude, dokonce je nezbytné zkrátit chod programu na minimum, takže nastavíme hodinový kmitočet 32 MHz.

Poloha jednotlivých serv bude uložena v RAM paměti od adresy 50. První krátká část programu odesílá podle stavu v RAM pulzy na všechna serva, druhá část se stará o postupné kývání všemi servy. Všimněte si, že na konci zbylo ještě asi 5 ms času, který musíme počkat. Funguje to, ale signál není přesný ani nemá stabilní opakovací kmitočet, ten je závislý na délce všech pulzů (poloze serv).

REM Picaxe 20M2, 8 serv bez časovače
setfreq m32         ;nastavení frekvence 32 MHz
poke 50,100,100,100,100,100,100,100,100 ;počáteční polohy do RAM

do                  ;začátek hlavní smyčky programu
  for b0=0 to 7     ;obsluha 8 serv po řadě 
    b1=b0+50        ;adresa v RAM s daty pro dané servo
    peek b1,w2      ;načíst délku pulzu z RAM
    w2=w2*8         ;upravit podle hodin 32 MHz
    pulsout b0,w2   ;generovat pulz pro dané servo na jeho výstup
  next b0           
  
  select w3         ;část pro postupné kývnutí všemi 8 servy
  case 0            ;každé servo 100 cyklů tj. 2 sekundy
    poke 50,200
    poke 57,100
  case 100          ;servo 1 
    poke 51,200
    poke 50,100
  case 200          ;servo 2
    poke 52,200
    poke 51,100
  case 300          ;servo 3
    poke 53,200
    poke 52,100          
  case 400          ;servo 4 
    poke 54,200
    poke 53,100
  case 500          ;servo 5
    poke 55,200
    poke 54,100
  case 600          ;servo 6
    poke 56,200
    poke 55,100
  case 700          ;servo 7
    poke 57,200
    poke 56,100
  endselect
  inc w3            ;čítač průběhu tedy čítač času v 1/50 s
  if w3>=800 then let w3=0 endif  ;po všech servech vynulovat 
  pause 40          ;ještě nám zbylo skoro 5 ms času, tak počkat
      
  loop              ;konec smyčky programu

Bylo by reálné obsloužit víc než 8 serv jedním mikrokontrolérem 20M2? Nabízí se myšlenka zkombinovat oba uvedené způsoby, 8 serv ovládat přes časovač a několik dalších programově. Teoreticky by to šlo, bohužel to nefunguje. Serva sebou škubou, signál je nepravidelný a nestabilní. Ono to totiž s tou nezávislostí ovládání časovačem a programem není tak ideální, ve skutečnosti máme k dispozici jen jedno jádro mikroprocesoru a i obsluha časovače a jeho přepínání na více výstupu vyžaduje nějaký čas, takže se oba „procesy“ vzájemně ovlivňují.

Jak to dopadne i v jednoduchém případě si můžeme vyzkoušet na obsluze 10 serv, přitom s nimi ani nebudeme hýbat, jen se pokusíme držet je v klidu ve střední poloze.

REM Picaxe 20M2, 10 serv kombinací
servo B.0,150           
servo B.1,150
servo B.2,150
servo B.3,150
servo B.4,150
servo B.5,150
servo B.6,150
servo B.7,150

do
  pulsout C.0,150
  pulsout C.1,150
  pause 15
  loop

Není dobré jednotlivý mikrokontrolér Picaxe příliš přetěžovat a snažit se jím vytvářet více složitějších  přesně časovaných signálů. Vhodnější cestou, která spíše vede k úspěšnému výsledku, je rozdělit úlohu na jednodušší, a každou z částí nechat zpracovávat samostatným mikrokontrolérem. Ty pak podléhají jednomu, který se věnuje jen určení cílů, nemusí řešit třeba generování jednotlivých řídících pulzů. Většinou dokonce stačí rozdělení na dvě části, na část řídící (určení cílů, výpočty, logické vazby, …) a druhou pro přesné generování signálů.