Ardubot

V tomto článku se budeme zabývat praktickým použitím Arduina Duemilanove jako mozku pro malého robota na pásovém podvozku. Konstrukce Ardubota není náročná a měl by ji zvládnout i úplný začátečník bez speciálního vybavení. Nebude nutné řezat vlastní díly, vystačíme si s dostupnými, ani vyrábět plošné spoje, protože pro několik málo součástek použijeme malé nepájivé kontaktní pole. Předvedeme si základní program, který zajistí, aby se náš robot uměl vyhnout překážkám, a budeme jej také dálkově ovládat z PC pomocí bluetooth modulu.

Stavba

Celý robot bude postaven na podvozku Tank-02 z e-shopu Snail Instruments, který pouze rozšíříme o horní palubu. Na tu přišroubujeme Arduino, regulátor motorů SaberTooth 2x5, malý informační displej 2x8 znaků (vybavený řadičem HD44780 nebo ekviv.), nepájivé kontaktní pole, IR senzor SHARP GP2Y0A21 pro měření vzdálenosti a nakonec také bluetooth modul OEMSPA310, který prodává firma Spezial Electronic. Poloha jednotlivých komponentů není až tak důležitá, nicméně pokud se chcete vyhnout menšímu hlavolamu co kam dát, použijte uspořádání jako na obrázcích. Rozteče montážních otvorů (například u Arduina a regulátoru) totiž nesouhlasí s předvrtanými otvory v horní palubě a i přes veškerou snahu budete mít něco nakřivo nebo musíte vyvrtat otvory nové. Každopádně s robotem nehodláme vyhrát soutěž krásy a při troše snahy lze dosáhnout uspokojivého výsledku.

Pouze IR senzor musí být pochopitelně kousek za přední hranou a nejlépe na vyvýšeném místě, aby se do zorného pole nepřipletl nějaký odstávající kabel. Připevnil jsem ho pomocí distančních sloupků a dvou dílů ze stavebnice LEGO. Na horní palubu, ovšem z dolní strany, přišroubujeme také dva mikrospínače s dlouhou páčkou, které poslouží jako dotykové nárazníky. Na spodní palubu před převodovku a motory umístíme akumulátory, buď pětičlánkovou sadu, tak jako na obrázku nebo stejný počet mikrotužkových akumulátorů v držáku. Všechny komponenty zapojíme podle schématu.

Regulátor motorů SaberTooth 2x5

Stavbu máme za sebou ale ještě než začneme programovat, musíme se podrobněji seznámit s jednotlivými komponenty robota, začneme regulátorem. Ten je schopen obsluhovat dva motory s maximálním odběrem 2 x 5A, při napájení 6 až 18V. Lze použít i lithiové akumulátory, protože má integrovanou ochranu proti jejich zničení nadměrným vybitím. Dále regulátor nabízí slušný výběr vstupních signálů, kterými můžeme motory řídit:

  • Analogové napětí – ke vstupům S1 a S2 připojíme potenciometry jako děliče napětí a můžeme jimi řídit otáčky motorů
  • Servopuls 1-2 ms – využívá stejný způsob řízení jako modelářská serva nebo regulátory, každých 20 ms se opakuje řídicí puls, jehož délka určuje otáčky motorů. Je to velmi užitečné v případě, že chceme libovolné vozítko řídit přímo pomocí RC soupravy nebo prostě jen vyzkoušet mechanické a jízdní vlastnosti.
  • Sériové rozhraní

My použijeme poslední jmenované, po sériové lince budeme posílat jednobytové instrukce, hodnotu od 0 do 255. Rozsah 1 – 127 ovládá první motor, 128 – 255 druhý motor. Přehledně by to měla objasnit následující tabulka. Hodnotě 0 odpovídá zvláštní instrukce – zastavení obou motorů. Je jasné, že který motor bude levý nebo pravý, a které hodnoty odpovídají jízdě vpřed nebo vzad záleží na tom, jak motory s regulátorem propojíme, změnu lze provést prohozením vodičů. Zároveň je nutné regulátor nejprve naprogramovat pomocí pole spínačů. Podrobný popis nastavení a použití regulátoru najdete v dokumentaci výrobce, nicméně stačí použít kombinaci z obrázku.

Přehled hodnot pro řízení motorů a konfigurace spínačů

IR senzor vzdálenosti

Jak jsem psal výše, zvolil jsem senzor GP2Y0A21, který umožňuje detekci překážky na vzdálenost 10 - 80cm. Což je na tak malého robota velký rozsah, zejména proto, že měření na vzdálenost menší než 10 cm bude vracet stejné hodnoty jako pro vzdálenost mnohem větší. Vše je patrné z grafu, který jsem převzal z datasheetu výrobce čidla. Proto lze jako alternativu použít čidlo GP2Y0A41 s rozsahem 4 – 30cm. Zjištění překážky vzdálené 30 cm vzhledem k velikosti a rychlosti robota stačí a měření na kratší vzdálenost než 4 cm zabrání umístění za hranu horní paluby. Každopádně i s čidlem GP2Y0A21 se robot vyhýbal překážkám poměrně úspěšně a v případě selhání detekovaly překážku nárazníky. Pravděpodobně nejjednodušším způsobem jak čidlo použít je postavit před robota předmět do vzdálenosti, ve které se mu má vyhnout, a zjistit hodnotu z A/D převodníku, na kterém je čidlo připojeno. S touto hodnotou pak dále pracovat při programování robota.

Bluetooth modul OEMSPA310

Přesněji řečeno se jedná o Serial Port Adapter, který stačí pouze připojit k napájení a k sériové lince (v případě Arduina piny RX a TX) a sériová komunikace může probíhat dále přes bluetooth. Samozřejmě za předpokladu, že druhé zařízení je buď přímo vybaveno vlastním bluetooth zařízením (notebook, mobil) nebo také Serial Port Adapterem. Aby modul fungoval, musí být také správně nastaven, což lze vyžádat u dodavatele – firmy Spezial electronic. Pro komunikaci s Arduinem jsem použil konfiguraci 8N1 (8 datových bitů, bez parity, 1 stop bit) a baudrate 9600. Další nastavení můžeme sami provést pomocí speciálního programu od výrobce. Vzhledem k tomu, že modul bez dalšího adaptéru nejde k PC připojit jinak než opět s využitím bluetooth, je třeba si nechat povolit také bezdrátové nastavování. Podrobnosti o zapojení modulu najdete samozřejmě v datasheetu. Rád bych ještě upozornil na malý zádrhel, který jsem objevil. Pokud chcete nahrát do Arduina nový program, je třeba odpojit od pinů RX a TX vodiče vedoucí k bluetooth modulu. Jinak komunikace s Arduinem pomocí USB nefunguje a vždy končí chybou.

Bluetooth modul OEMSPA310

První program – vyhýbáme se překážkám

Před studiem následujícího vzorového programu doporučuju alespoň v rychlosti pročíst Language Reference, protože kompletní vysvětlení programovacího jazyka by se do tohoto článku rozhodně nevešlo. Nicméně i tak se budu snažit struktury programu objasnit a snad pomohou i komentáře.

1) V první části kódu musíme uvést použité knihovny a definovat konstanty, se kterými budeme později pracovat. Je jich tam poměrně dost, dokážou totiž celý program výrazně zpřehlednit, zejména řízení motorů probíhá výhradně pomocí konstant. Například samotný příkaz ST.print(88, BYTE); (odeslání hodnoty 88 po sériové lince regulátoru Sabertooth) působí vcelku záhadně a musíme vyhledat v tabulce, jakou instrukci vlastně daná hodnota reprezentuje. Proto je daleko lepší jej nahradit, LMOT_F – left motor forward už naprosto jednoznačně prozrazuje, co daný příkaz provede. Stejně tak je vhodné nahradit čísla pinů s připojenými senzory slovem, ze kterého bude hned jasné, o který konkrétní senzor jde, například #define LN 8 // Levý nárazník. Následují už jednotlivé funkce programu, ty jsou uvozeny klíčovým slovem void.

/*
Vzorový program - Ardubot
Vyhýbání se překážkám, použití IR senzoru, nárazníků
a zobrazení informací na LCD displeji
*/

// použité knihovny
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>

// definujeme piny pro 
// sériovou komunikaci 
#define rxPin 11
#define txPin 12

// vytvoření sériového portu pro SaberTooth
SoftwareSerial ST =  SoftwareSerial(rxPin, txPin);

// definujeme konstanty pro ovládání motorů
// Levý motor
#define LMOT_F ST.print(88, BYTE);  // Vpřed (Forward)
#define LMOT_S ST.print(64, BYTE);  // Stop
#define LMOT_R ST.print(40, BYTE);  // Vzad (Reverse)

// Pravý motor
#define RMOT_F ST.print(214, BYTE); // Vpřed
#define RMOT_S ST.print(192, BYTE); // Stop 
#define RMOT_R ST.print(168, BYTE); // Vzad

// definujeme piny senzorů
#define TLAC 10 // Ovládací tlačítko - start robota
#define LN 8 // Levý nárazník
#define PN 9 // Pravý nárazník
#define IR 0 // IR senzor

// připojení LCD
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
 

2) Funkce setup() proběhne vždy při startu programu a proto je vhodná k provedení nastavení, která jsou nutná pro další chod programu. Například musíme Arduinu sdělit, které piny budou použity jako vstupy a které jako výstupy, inicializovat sériovou komunikaci a LCD displej. Na konci funkce robot počká na stisknutí tlačítka (a pak ještě sekundu), aby nám neujel z pod rukou hned po připojení napájení, protože všechny předchozí příkazy jsou provedeny během okamžiku.

      
void setup()
{
// nastavení módu pinů (vstup/výstup)   
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
pinMode(IR, INPUT);
pinMode(TLAC, INPUT);
pinMode(LN, INPUT);
pinMode(PN, INPUT);

// start sériové komunikace
ST.begin(9600); // Baudrate 9600

// inicializace LCD a zobrazení nápisu Ardubot
lcd.begin(8, 2); // 8 znaků, 2 řádky
lcd.print("Ardubot");

// před startem počká na stisknutí tlačítka
while(digitalRead(TLAC) == 0) {delay(20);} 
delay(1000);
lcd.clear(); // mazání LCD
}

3) Funkce loop() neboli smyčka pak probíhá stále dokola, dokud je Arduino připojeno k napájení. V našem programu pouze kontroluje stav svých vstupů, zda je stisknuto tlačítko, nějaký nárazník nebo zda IR senzor zaregistroval případnou překážku. Na eventuální událost pak zareaguje voláním funkce couvat_vpravo() nebo couvat_vlevo(). Ty už provedou přímo požadovaný manévr, tedy zacouvají a zatočí doprava nebo doleva a zároveň zobrazí informaci o manévru na LCD. Tento algoritmus je samozřejmě velmi primitivní a rozhodně nepřipraví našeho Ardubota na všechny nástrahy reálného světa, nicméně jako úvod do práce s Arduinem a praktický příklad snad postačí. Vyzkoušíme sériovou komunikaci s BT modulem i regulátorem, obsluhu LCD a čtení dat ze senzorů na vstupech.

void loop()
{
LMOT_F;
RMOT_F;

// při dalším stisknutí tlačíka zastaví
if(digitalRead(TLAC) == 1) 
  {
  LMOT_S;
  RMOT_S;
  while(true){}
  }
 
// IR senzor: překážka blíže než cca 15 cm
// zastaví, zacouvá a otočí se doprava
if(analogRead(IR) > 300){couvat_vpravo();}

// levý nárazník = 1 (je stisknutý)
// zastaví, zacouvá a otočí se doprava
if(digitalRead(LN) == 1) {couvat_vpravo();}

// pravý nárazník stisknutý
// zastaví, zacouvá a otočí se doleva
if(digitalRead(PN) == 1) {couvat_vlevo();}

delay(50);  
}

void couvat_vpravo()
{
lcd.print("Prekazka"); // zobrazení na LCD  
lcd.setCursor(0, 1); // kurzor na 1. znak 2. řádek
lcd.print("c-vpravo");
LMOT_S;
RMOT_S;
delay(500);
LMOT_R;
RMOT_R;
delay(400);
LMOT_S;
delay(750);
RMOT_S;
delay(500);
lcd.clear(); // mazání LCD
}

void couvat_vlevo()
{
lcd.print("Prekazka"); // zobrazení na LCD
lcd.setCursor(0, 1); // kurzor na 1. znak 2. řádek
lcd.print("c-vlevo");
LMOT_S;
RMOT_S;
delay(500);
LMOT_R;
RMOT_R;
delay(400);
RMOT_S;
delay(750);
LMOT_S;
delay(500);
lcd.clear(); // mazání LCD
}

Bluetooth dálkové ovládání

Abychom mohli Ardubota ovládat z PC nebo notebooku pomocí bluetooth, potřebujeme pochopitelně program, který na daném PC bude běžet a instrukce robotovi odesílat. Stránky www.arduino.cc často zmiňují spolupráci Arduina s programovací jazykem Processing. Rozhodl jsem se to osobně vyzkoušet a napsal jsem program Ardubot Control právě v Processingu. (v Processingu se pro program používá označení skeč, takže i já se ho budu nadále držet) Aby bylo možné se skečem pracovat, je nutné nejdříve stáhnout a nainstalovat programovací prostředí. Já pak ke stažení nabízím dvě verze mého skeče, jedna využívá k řízení Ardubota myš a druhá joystick.

Před použitím skečů je nutné nejdříve vaše PC s Ardubotem spárovat a zjístit, ke kterému portu bude připojen. V mém případě se jedná o COM40, ale téměř jistě se to bude lišit. Zdrojový kód skeče pak musíte lehce upravit právě zadáním daného portu. Tím je vše hotovo v případě verze Ardubot Control - myš. Pokud máte k PC připojený joystick a chcete pomocí něj řídit Ardubota, použijte skeč Ardubot Control - joystick a upravte v něm název joysticku

  •  Ve zdrojovém kódu stačí přepsat COM40 označením portu na vašem PC
  •  V připadě verze Ardubot Control - joystick ještě zapsat název vašeho joysticku připojeného k PC. Zjístíte ho v ovládacích panelech po kliknutí na položku Herní zařízení.

Zapínáme vždy nejdříve Ardubota a pak spouštíme skeč! V případě, že tak neučiníte, skeč hned na začátku nebude schopen Ardubota připojit, dojde k chybě a pravděpodobně se ani nespustí. Pokud je vše v pořádku, práce se skečem je pak už velmi jednoduchá, držení levého tlačítka a pohyb myši ovládá joystick na obrazovce, jeho poloha je pak přepočtena na hodnoty pro regulátor Sabertooth a odeslána přes bluetooth. U verze joystick myš nefunguje a plně ji nahrazuje připojený USB joystick. Funkci jsem otestoval se základním a poměrně levným joystickem Genius MaxFighter F-23U, který na daný účel stačí.

Obsluhu programu už snad není třeba dlouze popisovat. Pohybem myši nebo joysticku ovládáme virtuální joystick na obrazovce, jeho pozice je pak přepočtena na hodnoty přímo pro regulátor Sabertooth a odeslána pomocí bluetooth. Veškeré výsledky mezivýpočtů jsou dostupné v okně programu, stejně jako indikátory obou motorů.

Arduino Duemilanove

Pochopitelně je nutné napsat řídicí program i pro Arduino, které bude přijímat instrukce pomocí bluetooth a předávat je regulátoru motorů. Ačkoliv je následující kód velmi jednoduchý, v praxi se osvědčil.

// Ovládání Ardubota z PC pomocí bluetooth

// použité knihovny
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>

// definujeme piny pro sériovou 
// komunikaci s regulátorem Sabertooth
#define rxPin 11
#define txPin 12

// vytvoření sériového portu pro SaberTooth
SoftwareSerial ST =  SoftwareSerial(rxPin, txPin);

// připojení LCD
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

void setup()
{
// nastavení módu pinů (vstup/výstup)
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);

// start sériové komunikace, baudrate 9600
ST.begin(9600); // sabertooth
Serial.begin(9600); // BT modul

// inicializace LCD a zobrazení nápisu: 
// Ardubot a BTctrl
lcd.begin(8, 2);
lcd.print("Ardubot");
lcd.setCursor(0,1); // kurzor na 1. znak 2. řádku
lcd.print("BTctrl");
}

void loop()
{
// pokud přichází z BT modulu data,
// jsou přeposlány regulátoru
if (Serial.available()) 
    {
    ST.print(Serial.read(), BYTE);
    delay(20);  
    }
}

Pokud máte připraveného Ardubota a skeč Ardubot Control podle instrukcí z mých stránek, zapněte u Ardubota napájení a spusťte skeč. Ardubot by měl celkem svižně reagovat na povely z PC. Tímto pokusem jsme také pouze nakousli, co všechno je s bluetooth modulem možné. Komunikaci lze samozřejmě využít oboustranně a posílat zpět například informace ze senzorů. Ale o tom snad někdy příště.

- Stránka vytvořena 10. září 2010 -