Takže budu předpokládat, že spojení plošek 1-2 u propojky S1 zajistí trvalé napájení IR LED snímačů na OPT modulu (i když to neodpovídá schématu). To zatím stačí, sonaru se můžeme věnovat někdy později. Rozhodně by bylo užitečné to spojení Ucc a středu S1 "propísknout" multimetrem.
Ke zprovoznění sledovače čáry nám pak chybí dva body (podle návrhu z 25.2.2015):
3. Otestovat funkčnost OPT modulu programem pro čtení stavu snímačů a signalizací stavu pomocí LED. [OPT modul je snad funkční, ale nemáme SW]
4. Doplnit signalizaci o reálné ovládání motorů Yrobota a zprovoznit základní algoritmus sledování čáry. [algoritmus navržen, ale chybí funkční čtení OPT modulu]
Pro bod 3. potřebujeme:
- rozumně nadefinovat vhodné názvy (VLEVO, UPROSTRED, VPRAVO, OPT_DDR)
- nastavit správně piny portu, na kterém je připojen OPT modul
- napsat funkci "cara_je(snimac)", která určí, jestli je pod daným snímačem čára, nebo ne
- použít výsledku funkce "cara_je" k signalizaci stavu snímačů pomocí LED na Yrobotu (nebo pomocí LED sedmisegmentovek na Yrobotu)
Názvy jsou jasné a můžeme je nadefinovat např. takto:
Kód: Vybrat vše
#include "yellow_robot.h" // vlozeni HAL knihovny pro abstrakci od HW Yrobota (tim ziskame i radu uzitecnych funkci)
#define VLEVO PA0 // OPT snimac vlevo (vstup, ADC0)
#define UPROSTRED PA1 // OPT snimac uprostred (vstup, ADC1)
#define VPRAVO PA2 // OPT snimac vpravo (vstup, ADC2)
#define OPT_PORT PORTA // OPT modul je na portu A
#define OPT_DDR DDRA // registr pro nastaveni smeru pinu pro OPT modul
Pro správné nastavení pinů je třeba vědět, že pokud u AVR (atmega16) chceme nastavit pin jako vstupní, musíme příslušný pin jeho řídicího DDR registru nastavit na nulu. Přitom je vhodné nezměnit nastavení ostatních pinů řídicího registru. Toho lze dosáhnout používáním tzv. "přátelského kódu" ("friendly code"). Tento způsob využívá při přiřazování logické OR (|=), AND (&=) a negaci (~) pro opatrné a přesné ovládání jednotlivých bitů portu. Pokud tedy například chceme nastavit bit 1 registru OPT_DDR na nulu (a přitom zachovat nastavení ostatních bitů), tak použijeme zápis "OPT_DDR &= ~(0b00000010);" [bity se počítají zprava a od nuly, negace otočí hodnotu každého bitu a logické AND (&=) pak vynuluje jen ten bit, který je vpravo na nule, ostatní bity nechá bez změny]. Tento způsob zápisu je docela dobrý i proto, že je z něj jasné, který bit ovládáme (proto je tam ta negace). Dalším možným zápisem pro přehlednost je použití shift operátoru pro nastavení bitu podle jeho čísla, takže třeba zápis (1<<5) nastaví na jedničku 5. bit bytu (posune jedničku o 5 pozic vlevo, tedy výsledkem je 0b00100000). Místo čísla můžeme využít i definovaného nazvu, např. (1<<PA2) nastaví 2. bit bytu, protože PA2 je vlastně pojmenovaná "dvojka". Více bitů se nastavuje logickým OR (|). Třeba zápis (1<<0)|(1<<1) nastaví na jedničku bity 0 a 1, takže výsledkem je 0b00000011 (nebo v HEXA ... 0x03).
Jak tedy můžeme nastavit piny VLEVO, UPROSTRED a VPRAVO jako vstupní? To je "domácí úkol" pro zápis funkce "initOPT()":
Kód: Vybrat vše
void initOPT() { // funkce pro inicializaci portu pro OPT modul
// v prislusnem DDR registru nastavime nuly na bitech pro vstupy (0,1 a 2)
}
Po nastavení směru pinů budeme moci pokročit k funkci na čtení stavu snímačů. Původně jsem myslel, že zkusíme začít jednodušším binárním čtením, ale řekl bych, že přesnější a zajímavější bude rovnou zkusit analogové čtení hodnoty pomocí interního ADC převodníku v atmega16 (protože na to máme dobré funkce z vnořené knihovny "yellow_robot"). Nejprve ale musíme mít rozumně napsaný ten "initOPT()".