Před několika lety běžel na serveru HW.cz seriál o využití modulů IQRF. V článcích jsem se soustředil především na popis základních vlastností modulů a jednoduché praktické ukázky. S odstupem času bych rád na seriál navázal a představil několik praktických aplikací modulů IQRF, ale i jiných, k nim připojených zajímavých součástek. V dnešním článku půjde o aplikaci IO expandéru připojeného k modulu IQRF, a to ve funkci dálkového ovladače s více tlačítky.
Úvod
Dálkovými ovladači se to na webových stránkách jen hemží. I na HW serveru už bylo publikováno několik ukázek bezdrátových ovladačů a to i s moduly IQRF. Vždy jsem se omezil pouze na menší počet tlačítek. Provedení v SIM konektoru nám totiž nabízí pouze 6 vstupně-výstupních bran pro jejich připojení. Řešením by bylo využít maticového zapojení anebo dnes již dostupných variant IQRF modulů pájených přímo do DPS. I tam jsme ale počtem vstupů/výstupů limitováni.
Klasickým řešením tohoto problému v mikroprocesorové technice je využití IO Expandérů, velmi často se jedná o expandéry připojené přes rozhraní I2C nebo SPI. Velmi oblíbeným (historicky) je obvod fy NXP PCF8574, lze ho nalézt téměř v každé aplikaci, která se potýká s nedostatkem vstupně/výstupních bran a jejímž základem je nějaký mikroprocesor. Dnes už je ale nabídka podobných obvodů výrazně širší. NXP nabízí mnoho obvodů, které PCF8574 spolehlivě nejen nahradí, ale které nabídnou mnohem víc. Mezi takové patří například obvody PCA9535, PCA9555 a další. Velmi zajímavý je také konkurenční obvod Microchipu MCP23017 (I2C) a jeho SPI ekvivalent MCP23S17. Výrobců a obvodů je samozřejmě víc, ale o tom dnešní článek není.
Bezdrátový ovladač
Bezdrátový ovladač dle níže uvedených parametrů by jistě bylo možné realizovat mnoha způsoby. V mém případě šlo o vytvoření dálkového ovladače pro zemědělské stroje, jejichž produkce nepřesáhne desítky kusů ročně. V takové případě bylo nutné snížit vývojové náklady na minimum, aby byla periferie vůbec pro zákazníka ekonomicky zajímavá.
- Bezdrátový ovladač v pásmu ISM.
- 10 tlačítek.
- Indikace vybité baterie.
- Nízká spotřeba.
Volba padla na moduly IQRF, se kterými jsem už něco podobného realizoval. Jako IO expandér jsem se rozhodl použít již uvedený obvod PCA9535PW připojený k modulu IQRF přes rozhraní I2C. Základ SW byl převzat z hotových příkladů pro vývojové kity (DDC) fy Microrisc a nebylo tedy nutné řešit žádný základní výzkum. Nevýhodou uvedeného řešení je, že obvod PCA9535 nemá integrované pull-up rezistory. NXP ale nabízí varianty i s pull-up, například u PCA9555 tento problém mít nebudete.
Mechanicky se jedná o konstrukci vestavěnou do plastové krabičky Hammond 1553BBKBAT s kontakty na dva články velikosti AA nebo 9V baterii. Napájecí napětí dvou tužkových alkalických baterií je sice dost na hraně (alespoň dle katalogového listu). Praktická měření ale ukázala, že si s tím IQRF modul poradí.
Ze schématu je patrné, že nejsou ošetřeny všechny „vstupy“ expandéru. Tato skutečnost je vyřešena softwarově, kdy jsou nepoužité IO nastaveny jako výstupy do 1 a registry pro čtení stavu vstupních pinů jsou invertovány. Tak lze jednoduše stav „1“ vyčíst pouze pro vstupy uzemněné tlačítky.
Software
Aplikace pro modul IQRF byla psána pro moduly TR-52D a OS verze 3.03. Pokud jste zvyklí na 52B, máte vše potřebné nainstalováno, není důvody tyto moduly nepoužít, ovšem musíte počítat s tím, že je třeba si přečíst dokumentaci a SW upravit. Pokud začínáte, doporučil bych, vzhledem k budoucímu vývoji, začít rovnou na „D-čkových“ modulech (i přes nepatrně vyšší cenu).
Kód vychází z ukázkových příkladů pro moduly DDC, které si stáhnete jako součást softwarového balíčku ze stránek iqrf.org. Jde o soubor „DDC-SE-01-i2c.c“ \DDC\“. Konkrétně se jedná o rutiny pro inicializaci a práci s I2C, ty byly přebrány téměř beze změn. K těmto rutinám byly vytvořeny dvě další, které nastavují IO expandér a vyčítají stav vstupních portů. Celý kód je ke stažení na konci článku, dále budu uvádět pouze významnější pasáže.
void read_IO() // přečte stav vstupních pinů
{
uns16 tlacitka = 0;
i2c_start();
i2c_write(I2C_ADR_W);
i2c_write(PCA9535_InputPort1);
i2c_repStart();
i2c_write(I2C_ADR_R);
btns_H = i2c_read(ACK);
btns_L = i2c_read(NO_ACK);
i2c_stop();
}
Tato rutina dle specifikace protokolu uvedeného v katalogovém listu odešle adresu obvodu (na DPS jsou adresní bity uzemněny). Dále odešle příkaz na čtení registru vstupního portu 0 a registry vyčte (oba). V PCA9535 totiž registry fungují párově. Pokud je nastavena adresa jednoho z nich, je v následující operaci pracováno s registrem druhým. To je dobře vidět i v následujícím kódu.
void cnf_IO() // nakonfiguruje porty
{
i2c_start();
i2c_write(I2C_ADR_W);
i2c_write(PCA9535_PortCfg0);
i2c_write(0b01100111);
i2c_write(0b01110011);
i2c_stop();
waitDelay(5);
i2c_start();
i2c_write(I2C_ADR_W);
i2c_write(PCA9535_InvertPol0);
i2c_write(0xFF);
i2c_write(0xFF);
i2c_stop();
}
Zde jsou v první části kódu nastaveny vstupní (log. 1) a výstupní (log. 0) porty, v další části je pak nastavena inverze pro všechny vyčítané bity. Důvodem je ošetření nezapojených vstupů a jejich maskování.
Hlavní smyčka
Úkolem kódu hlavní smyčky je cyklické vyčítání stavu tlačítek, přesunutí stavu tlačítek do RF bufferu a odeslání dat. V té nejjednodušší variantě ovladače není řešena jeho spotřeba, a proto není v kódu použita funkce pro uspávání obvodu. Aby modul nevysílal neustále, je vysíláno pouze tehdy, je-li smáčknuto tlačítko a dalších 10 zpráv po uvolnění posledního tlačítka.
void APPLICATION()
{
uns8 timeout = 0;
btns_H = btns_L = 0;
disableSPI();
waitDelay(5);
i2c_init();
waitDelay(5);
cnf_IO();
waitDelay(5);
while (1) // Hlavní cyklus
{
//clrwdt(); // nemusí být u "D" modulů, WDT vypnut
if (buttonPressed) // pokud přijde přerušení od změny stavu tlačítka
timeout = 10; // do další změny 10 zpráv
if (timeout > 0) // pokud ještě neodešel dostatečný počet zpráv
{
read_IO(); // přečte stav tlačítek
bufferRF[0] = btns_L;
bufferRF[1] = btns_H;
if ((btns_L) || (btns_H)) timeout = 10;
pulseLEDR(); // blikne LED
PIN = 0; // nastaví nesíťový paket
DLEN = 2; // nastaví délku odesílaných dat
RFTXpacket(); // odešle data
waitDelay(5); // počká 50 ms
timeout -= 1; // sníží počítadlo zpráv
}
}
}
Podmínka „buttonPressed“ je splněna vždy při změně stavu vstupního portu na expandéru, ten totiž vygeneruje přerušení na výstupu INT, který je připojen ke vstupu C5 (SS). V této chvíli by bylo ještě vhodné uspávat modul po dobu, kdy není vysíláno nic. Ze spánku bude probouzen právě vstupem SS. Spotřebu je také možné řídit nastavením vysílacího výkonu.
Řídíme spotřebu
IQRF moduly s OS v3.3 je možné provozovat ve třech režimech spotřeby:
- STD
- V roli přijímače ve funkci RFRXpacket je modul stále na příjmu, spotřeba 13 mA.
- V roli vysílače modul vysílá pakety s hlavičkou o délce 3 ms.
- LP
- V roli přijímače ve funkci RFRXpacket modul cyklicky přechází mezi režimem spánku a kontrolou příchozího paketu. Perioda je 46 ms, průměrná spotřeba 330 uA.
- V roli vysílače modul vysílá pakety s hlavičkou o délce 50 ms.
- XLP
- V roli přijímače ve funkci RFRXpacket modul cyklicky přechází mezi režimem spánku a kontrolou příchozího paketu. Perioda je 770 ms, průměrná spotřeba 25 uA.
- V roli vysílače modul vysílá pakety s hlavičkou o délce 900 ms.
Z výše uvedeného vyplývá, že režimy s nízkou spotřebou se hodí zvláště do těch aplikací, kde není třeba vysílat velké množství dat, anebo nám zas tolik nezáleží na reakční době (zvláště pak v XLP režimu). Na oplátku pak můžeme moduly v roli přijímače provozovat měsíce například z knoflíkové baterie. V roli vysílače tyto režimy nehrají roli a spotřebu nám spíše zvyšují, proto je v tomto článku využívat nebudeme.
Pro moduly v roli vysílače se nám hodí přecházet v době nečinnosti do režimu spánku se spotřebou 1,9 uA (+0,8 pro watchdog). K tomu slouží funkce iqrfSleep(), která zajistí vypnutí všech periferií a zastaví vykonávání instrukcí procesorem. Z režimu spánku je naopak možné vystoupit přetečením čítače WDT, změnou stavu na vstupním pinu (v našem případě INT na C5) nebo resetem modulu. Následující kód je ukázkou toho, jak lze snížení spotřeby dosáhnout.
void APPLICATION()
{
uns8 timeout = 0;
btns_H = btns_L = 0;
disableSPI();
waitDelay(5);
i2c_init();
waitDelay(5);
cnf_IO();
waitDelay(5);
while (1) // Hlavní cyklus
{
//clrwdt(); // nemusí být u "D" modulů
if (buttonPressed) // pokud přijde přerušení od změny stavu tlačítka
timeout = 10; // do další změny 10 zpráv
if (timeout > 0) // pokud ještě neodešel dostatečný počet zpráv
{
read_IO(); // přečte stav tlačítek
bufferRF[0] = btns_L;
bufferRF[1] = btns_H;
if ((btns_L) || (btns_H)) timeout = 10;
pulseLEDR(); // blikne LED
PIN = 0; // nastaví nesíťový paket
DLEN = 2; // nastaví délku odesílaných dat
RFTXpacket(); // odešle data
waitDelay(5); // počká 50 ms
timeout -= 1; // sníží počítadlo zpráv
} else
{
GIE = 0; // Disable all interrupts
writeToRAM(&IOCBN, IOCBN | 0x10); // Negative edge active.
IOCBP.4 = 1; // Positive edge active
IOCIE = 1; // Interrupt on change enabled
SWDTEN = 0; // Watchdog disabled
iqrfSleep(); // Sleep
writeToRAM(&IOCBF, IOCBF & 0xEF); // Clear interrupt on change flag.
}
}
}
Po delší nečinnosti (není stisknuto tlačítko) se postupně:
- zakáže globální přerušení,
- povolí přerušení na sestupnou hranu,
- povolí přerušení na vzestupnou hranu,
- povolí přerušení na změnu stavu,
- zakáže WDT,
- uvede modul do režimu spánku,
- po probuzení (způsobeném přerušením z INT) vymaže flagy.
Na spotřebu má vliv samozřejmě i použitý vysílací výkon. Ten se řídí funkcí setTXpower (0-7). Čím častěji budeme vysílat, tím větší bude mít nastavení vliv.
Snížit spotřebu můžeme i vynecháním indikace vysílání (červená LED).
Závěr
Výše uvedený text stručně popisuje možnosti, jak využít rozhraní I2C, režimy spotřeby a režim spánku. Výsledkem je desetikanálový dálkový ovladač. Kompletní zdrojové kódy pro modul IQRF najdete v odkazech pod článkem. V příštím článku si ukážeme, jak vytvořit dva přijímače. V prvním případě půjde o jednoduchý převod přijaté zprávy na sériovou linku, v druhém pak o desetikanálový programovatelný spínač s relé. Do vysílače si doplníme měření stavu baterie.
Odkazy
- Aplikace IO Expandéru s moduly IQRF II.
- Domovské stránky platformy IQRF
- Zdrojový kód ke stažení
- Záznam SOS webináře: IQRF - Bezdrátové sítě