Jste zde

IQRF Prakticky IV – Sledujeme teplotu, komunikujeme

V minulém díle jsme začali využívat sítě IQMESH. Protože se jednalo o velmi jednoduchý příklad bez praktického využití, dnes to napravíme. Vytvoříme sestavu pro sběr údajů o teplotě v různých místech domu nebo jiného prostředí. Jednoduše nám k tomu poslouží jakákoliv vývojová deska, kterou jsme si v průběhu seriálu postavili a samozřejmě programátor. Ten bude sloužit pro komunikaci s ladícím prostředím IQRF IDE.

Opakujeme z minulého dílu

V minulém díle byla uvedena dvojice programů pro jednoduchý test síťové komunikace. V uvedených zdrojových kódech jsem se dopustil chyby, která nemusela být na první pohled patrná a za určitých okolností nemusela pokusy se sítěmi nijak ovlivnit. Před nastavením komunikace a odesláním dat v koordinátoru je vhodné vynulovat bajt PIN.

                    RX = bufferCOM[1] - '0';  
                    // cilem (RX) je modul uvedeny po prikazu "m"... 
                    PIN = 0;
                    // pro jistotu                      
                    DLEN = 0;

A to proto, že mohou být nastaveny některé bity ovlivňující nastavení komunikace. Ve zdrojových kódech uvedených na konci dnešního článku je již tento řádek doplněn.

Koordinátor – změny

Ve zdrojovém kódu koordinátora nás kromě výše uvedeného řádku čeká doplnění kódu pro příjem RF dat od nodů (teploměrů):

                    toutRF = 6;				// nastaví RF timeout na 60 ms
                    clrwdt();
                    for (pomj=0;pomj<9;pomj++)	// desetkrát se podívá jestli jsou na RF data
                    {
                        if (RFRXpacket())			// dívá se 60 ms, pokud jsou projde blokem
                        {
                            waitDelay(20);
                            pulseLED();
                            stopSPI(); 
                            copyBufferRF2COM(); 		// pokud RF data jsou, překopíruje je na SPI
                            startSPI(DLEN);			// a odešle
                            waitDelay(25);
                            goto mainloop;			// skočí na mailloop – nutno doplnit před hlavní smyčku
                        }
                        pomj++;
                    }

Přenosný teploměr – změny

Zdrojový kód pro node, vychází víceméně z minulého dílu. Jestliže node příjme data, změří teplotu, údaje o teplotě vloží do bufferu RF a data odešle:

      if (RFRXpacket())       // sem tam se podivam, zda mi neprisel paket
      {
            if (RX==0xFF)
                    continue;                    
            clrwdt(); 
            getNetworkParams();           // do param2 si presuneme cislo nodu
            bufferRF[0] = '0'+param2;     // presuneme ho do RFBufferu
            bufferRF[1] = ':'; 
            bufferRF[2] = ' ';
            RX = 0;                       // nastavime si jako prijemce coordinatora
            PIN = 0;                      // pro jistotu smazeme byte PIN !!!
            DLEN = 6;                     // nastavime delku zpravy na 6 byte

            // zde zacina mereni teploty tak, jak jsme to již dělali
            getTemperature();
            teplota.high8 = ADRESH&0x03;
            teplota.low8  = ADRESL;
            teplota *= 75;
            teplota >>= 8;
            teplota -= 50;
            bufferRF[3] = teplota.low8/10;
            bufferRF[3] += '0';
            bufferRF[4] = teplota.low8%10;
            bufferRF[4] += '0';
            bufferRF[5] = 'C';
            // zde končí měření teploty            
            RFTXpacket();
            pulseLED();       // pokud ani, dat to na vedomi
      }

Teploměr máme hotový, pro praktické využití by bylo dobré přestavět komunikaci na některé z vhodnějších rozhraní, například UART, které nechybí téměř u žádného PC (I když například pouze prostřednictvím převodníku). Troufám si říci, že rozhraním SPI nedisponuje téměř žádný počítač třídy PC.

Komunikujeme tam i zpět

Trochu netradiční název kapitoly měl uvést téma obousměrné komunikace prostřednictvím UARTU. Jak vysílat jsme si již ukázali v předchozích dílech seriálu. Jak zpracovávat přijaté bajty, o tom řeč nebyla. Protože systém IQRF neumožňuje využít přerušení vyvolané znakem přijatým prostřednictvím sériové linky, jedinou možností jak obsloužit příjem dat, je neustálé testování příznaku RCIF registru PIR1. Na jednoduchém příkladě si tedy ukážeme jak na to.

#include "includes/template-basic.h"
uns8 data;
void openUART_9600();
void SendByteUART(uns8);

void APPLICATION(void)
{ 
    do { GIE = 0; } while (GIE);            // vypne přerušeni
    clrwdt();
    disableSPI();
    openUART_9600();
    while (1)
        {
	clrwdt();
	if ((readFromRAM(0x0C)&0x20) == 0x20)	// když bylo neco prijato na UART
	{
                    data = RCREG;	     	 	// přečte znak z UARTu
                    SendByteUART(data+1); 	// zopakuje znak + posune o +1
	}
       }
}

Tento jednoduchý příklad nedělá nic jiného, než že čeká na znak přijatý UARTem, zvětší ho o jedničku a odešle zpět. Zajímavá je především tato pasáž:

if ((readFromRAM(0x0C)&0x20) == 0x20)	// když bylo neco prijato na UART

Zajistí čtení stavu příznaku RCIF registru PIR1. Příznak není možné od vyšších verzí systému číst přímo a proto je nutné využívat funkce readFromRAM.

Nyní zbývá uvést funkce openUART a SendByteUART:

void openUART_9600()	
{
	TRISB.2 = 1;		// RX – vstup
	TRISB.5 = 0;		// TX – výstput
	SPBRG = 51;		// 9600 baud @ 8MHz
	TXSTA = 0b00100100; // povolí vysílání, 8 bitů 
	RCSTA = 0b10010000; // povolí příjem, 8 bitů 
}

Funkce se nijak neliší od té, kterou jsme již používali.

void SendByteUART(uns8 data) 
{
	TXREG = data;
	RP0 = 0;
	RP1 = 0;
	while ((readFromRAM(0x0C)&0x10) == 0);
}

Zde je opět využita kopie příznaku TXIF. Příklad je možné samozřejmě rozšířit na práci s řetězci. Je však nutné pamatovat na to, že není možno využívat přerušení a s ním související výhody. Dnes bychom tímto skončili. Příště se podíváme na komunikaci prostřednictvím SPI. Spolu s popisem použitého protokolu bude uvedena knihovna pro AVR vyvinutá speciálně pro použití s moduly IQRF.

DOWNLOAD & Odkazy

Hodnocení článku: 

Komentáře

Dobry den. Procitam vase clanky o IQRF. Precetl jsem je nejednou a mám dotaz jestli mohu.
Jak rozpoznam v coordinatoru, ze ktereho nodu mi dosla zprava? Podle jake adresy? Kde ji nastavim? Nebo se prideluje nejaka defaultni?
Snad jsem vycetl, ze v tomto priklade (clanek IV) je node 0xFF a cordinator 0x00. ALe nikde jsem nevidel, ze by se to nastavovalo. Jakou adresu pak bude mit druhy node, kdyz jej pridam?

Snad rozumite me otazce.
Dekuji za odpoved. LG

Adresy se přidělují při párování. Je to už dlouho co jsem článek psal, takže si přesně nepamtuji, ale myslím, že to bylo automaticky. Pokud si ale koupíte nové moduly s verzí OS 3.0, je tam všechno jinak. Doporučuji si počkat na nový článek, kde tobude popsáno.