2013. szeptember 20., péntek

RFM01 és RFM02 rádiómodulok

      Az RFM01 (vevő) és RFM02 (adó) rádiófrekvenciás modulpár (RFM - Radio Frequency Module) a HopeRF cég egyik terméke. A modulok az ISM sávban sugároznak (Industrial, Scientific and Medical), pontosabban a 433, 868 és 915MHz-es tartományban, FSK modulációt használva (Frequency-Shift Keying). Az adatok maximális átviteli sebessége 115.2kbps lehet. A működési paramétereket egy külső mikrokontrollerrel lehet beállítani, a következőkben erre lesz egy példa. Ilyen modulokat általában távvezérlőkben, otthoni biztonsági rendszerekben, vezeték nélküli számítógépes perifériákban, játékokban, kulcsokban, légnyomásmérőkben, orvosi adatgyüjtő készülékekben vagy egyéb vezeték nélküli mérőeszközben használnak. Hatótávolsága meghaladja a 300 métert is.


RFM02 - adó


Tulajdonságok:
  • Teljesen integrált (kevés alkatrész, egyszerű kivitel)
  • Nem igényel gyártási összehangolást
  • Gyorsan beállítható, programozható, magas-felbontású PLL
  • Képes a gyors frekvenciaugratásos módszerre
  • Stabil és gyors FSK moduláció programozható deviációval
  • Programozható a PLL-hurok sávszélessége
  • Közvetlen antennavezérlés
  • Automatikus antennahangoló áramkör
  • Programozható kimenő teljesítmény
  • SPI busz a mikrovezérlővel való kommunikációhoz
  • Órajel a mikrovezérlőnek
  • Programozható hangolókapacitás a kvarcnak
  • Sokféle ébresztést előidéző eseményt lehet beállítani
  • Időzítő
  • Alacsony tápfeszültségszint érzékelő
  • 2.2 - 5.4V üzemfeszültség
  • Alacsony áramfogyasztás
  • Alacsony készenléti áramfelvétel (0.3μA)
  • Átviteli szinkronizáció
      A DIP tokozású változat egy 18x14mm-es nyomtatott áramkör 2x4-es tüskesorból álló csatlakozóval, az SMD tokozású változat pedig 15.9x16.1mm-es lemez, 2x7-es szélső galvanizált forrasztási pontokhoz vezetett csatlakozással. A modulon található leragasztott chip (vagy "csepp-IC") tartalmazza az FM adót. Jó esetben feltüntetnek egy táblázatot az áramkörön ami a chip frekvencia képességeit tartalmazza és besatírozzák azt a sort, amelyik frekvenciára hangolva van az áramkör.
SDI - Serial Digital Interface: SPI bemenet, erre a lábra érkeznek a működési paraméterek
SCK - Serial ClocK: SPI órajel bemenet
nSEL - negált chip SELect: a modul csak akkor értelmezi az SPI adatokat, ha ezen a lábon 0V van.
nIRQ - negált chip Interrupt ReQuest: megszakítás kimenet, melyről ha 0V-ot olvasunk, az megszakítást jelent
FSK - a küldendő információ bemenete, mely FSK modulációval hagyja el az antennát
CLK -  CLocK: órajel kimenet, mely a mikrovezérlő órajeleként szolgálhat. Ha nincs szükség rá, akkor ki lehet kapcsolni.
Ant - antenna kimenet, mely lehet egy darab vezeték de akár komplexebb szerkezet is
VDD - Voltage Drain Drain: pozitív tápveszültség
VSS vagy GND - Voltage Source Source vagy GrouND: negatív tápfeszültség

      Az SMD tokozatú nyák esetében mindenik GND kivezetés egy-egy áramkört lát el tápfeszültséggel. Az alacsony fogyasztás érdekében nem tápláljuk azokat az áramköröket amelyekre nincs szükség. A mikrovezérlő oldalon teljesen mindegy milyen portra mennek a kivezetéseket, legalább is ha az SPI kommunikációt szoftveresen valósul meg. Hardveres vezérlés esetén viszont az SDI kivezetést a MOSI lábra, az SCK kivezetést az SCK lábra, az nSEL kivezetést pedig az SS lábra kell csatlakoztatni (AVR mikrovezérlők esetén).


      Ha a FSK lábra küldjük a továbbításra szánt információt akkor a következő diagram érvényes, amiből az derül ki, hogy csak az nSEL logikai 1-re állítása után veszi figyelembe a küldendő adatokat. Az is látszik, hogy időbe kerül míg a kristály (alvó üzemmódból elindul,) stabilizálódik és a PLL valamint a végfokozat készenlétbe kerül, ezért az nSEL felemelése után nem árt várni kicsit (max 5.25 msec) vagy pedig értelmetlen adatokat tenni a FSK lábra.

      Ha az SPI adatbuszra tesszük a kiküldendő információt, akkor az alábbi diagram igaz. Ebben az esetben is szükség van a küldő áramkörök előkészületére, azonban az nSEL logikai értéke 0 kell maradjon. Van egy parancs (11000110), mely után minden SDI lábra érkező adatot továbbítandó információnak fog tekinteni. Az ábrán az is látszik, hogy az SCK láb ennél a résznél nem szabad billegjen, különben az információ parancsnak lesz értelmezve, tehát innentől nem SPI kompatibilis a kommunikáció. Más szóval bitenként kell az SDI lábra rakni az információt akár ha a FSK lábra küldenénk. Amint az SCK órajel újra megjelenik, az SDI adat parancsként lesz értelmezve. Az előny a fenti módszerrel szemben az, hogy megspórolunk egy lábat a mikrovezérlőn.


Az adómodul blokkvázlata a következő:
- Crystal Oscillator: nem más mint a panelen lévő 10MHz-es kvarcoszcillátor, melynek két szerepe van: referencia frekvenciát biztosít a PLL-nek és órajelet szolgáltat a külső mikrokontrollernek (hogy ne kelljen annak is külön kvarcot szerelni). A kvarc hangolókapacitása programozható. Ha az RF modul alvó üzemmódba léptető parancsot kap a mikrovezérlőtől, az oszcillátor nem áll rögtön le, hanem további órajeleket küld, míg a mikrovezérlő is "elalszik".
- Synthetiser: a PLL frekvencia szintézer, mely beállítja a pontos működési frekvenciát. A FSK deviációja 30 és 210kHz között változtatható a különböző sávszélességek, adatsebességek és toleranciák elérése érdekében.
- RF Power Amplifier (háromszög): végfokozat vagy teljesítményerősítő mely erősítési tényezője programozható. Ez a blokk egy automatikus antennahangoló áramkört is tartalmaz.
- Low Battery Detect: alacsony-tápfeszültség érzékelő, amely a beállított küszöbérték alatt megszakításjelet küld a mikrovezérlőnek.
- Wake-up Timer: időzítő, mely a takarékos üzemmódban játszik szerepet. Az ébresztés 1ms-tól néhány napig terjedő időtartamra programozható be, 5%-os pontossággal. Minden bekapcsolásnál, majd minden 30 másodpercben újrakalibrálja magát. Ha a kvarcoszcillátor éppen nem megy (pl. alvó üzemmód), akkor bekapcsolja egy pár ms-re, hogy újrakalibrálhassa magát.
- Controller: mikrovezérlő, mellyel a működési paramétereket és a küldendő adatokat lehet az RF modulra adni. A paramétereket az RF modul SPI interfészére kell küldeni (SDI és SCK), a küldendő információt pedig lehet szintén az SPI bemenetre vagy pedig az erre a célre szolgáló FSK kivezetésre küldeni. A felprogramozott értékeket az RF modul mindaddig megőrzi míg tápfeszültséget kap (tehát alvó üzemmódban is). Újraindításkor minden visszaáll alapértelmezettre.

      Az adatlapban példaként áramkör és kód is található az AVR és PIC mikrovezérlőkre egyaránt. Én egy ATmega8 avr mikrovezérlőt használtam az alábbi bekötéssel. Ez az áramkör 915MHz-en sugároz, a küldés kezdetekor bekapcsolja D1 LED diódát, a küldés befejeztekor pedig kioltja. Ezt ismétli folytonosan ezért csak egy pislákoló LED jelzi a helyes működést.

Az adómodul SPI interfésze szoftveresen van vezérelve (ahogy az adatlapban) vagyis az SCK órajel minden taktusát külön kell a lábra rakni.

Az adó kódja C-ben:

#define F_CPU 1000000UL //rendszer orajel
#include <avr/io.h>
#include <util/delay.h>

#define SCK PB5 //SPI orajel
#define SDI PB4 //SPI adat
#define IRQ PC3 //megszakitas (SDO)
#define SEL PC2 //chip select
#define FSK PD1 //kimeno adat
#define LED PD5 //ha megy az adat

#define LED_OUTPUT() DDRD |= (1<<LED)
#define HI_LED() PORTD|= (1<<LED)
#define LOW_LED() PORTD&=~(1<<LED)

#define SEL_OUTPUT() DDRC |= (1<<SEL)
#define HI_SEL() PORTC|= (1<<SEL)
#define LOW_SEL() PORTC&=~(1<<SEL)

#define SDI_OUTPUT() DDRB |= (1<<SDI)
#define HI_SDI() PORTB|= (1<<SDI)
#define LOW_SDI() PORTB&=~(1<<SDI)

#define IRQ_INPUT() DDRC&= ~(1<<IRQ)
#define IRQ_HI() PINC&(1<<IRQ)

#define SCK_OUTPUT() DDRB |= (1<<SCK)
#define HI_SCK() PORTB|= (1<<SCK)
#define LOW_SCK() PORTB&=~(1<<SCK)

#define FSK_OUTPUT() DDRD |= (1<<FSK)
#define HI_FSK() PORTD|=(1<<FSK)
#define LOW_FSK() PORTD&=~(1<<FSK)

void INIT(void)
{
    SCK_OUTPUT();
    SDI_OUTPUT();
    SEL_OUTPUT();
    IRQ_INPUT();
    FSK_OUTPUT();
    LED_OUTPUT();
    HI_SEL();
    HI_SDI();
    LOW_SCK();
}

unsigned int COMMAND(unsigned int cmd)
{
    unsigned char i;
    unsigned int temp=0;

    LOW_SCK();
    LOW_SEL();
    for(i=0;i<16;i++)
    {
        temp<<=1;
        if(IRQ_HI()) temp|=0x0001; //SDO
        LOW_SCK();
        if(cmd&0x8000) HI_SDI(); else LOW_SDI();
        HI_SCK();
        cmd<<=1;
    };
    LOW_SCK();
    HI_SEL();
    return(temp);
}

void SEND(unsigned char aByte)
{
    unsigned char i;

    HI_SEL();
    for(i=0;i<8;i++)
    {
        while(IRQ_HI());//Polling nIRQ  (SDO)
        while(!(IRQ_HI()));
        if(aByte&0x80) HI_FSK(); else LOW_FSK();
        aByte<<=1;
    }
}

int main(void)
{
    unsigned char ChkSum;

    _delay_ms(500); //mig az RF modul boot-ol
    INIT();

    COMMAND(0xCC00);//allapotregiszter olvaso: kiuriti a megszakitasokat
    COMMAND(0x9865);//konfig: 915BAND, CLK=1MHz, 11.5pF, pozitiv modulacio, +/-180kHz deviacio
    COMMAND(0xA7D0);//vivo: 915MHz
    COMMAND(0xC823);//adatsebesseg: 9.6kbps
    COMMAND(0xD040);//PLL: adatsebesseg felezo => 4.8kbps
    COMMAND(0xC220);//Tx bit szinkronizáló áramkör be
    COMMAND(0xC001);//energiagazdalkodas: minden aramkor ki (vevo kikapcs)

    while(1)
    {
        HI_LED();
        COMMAND( 0xC039); //energiagazdalkodas: kristaly be, PLL be, erosito be (vevo bekapcs)
        ChkSum=0;
        SEND( 0xAA ); // elotag
        SEND( 0xAA ); // elotag
        SEND( 0xAA ); // elotag
        SEND( 0x2D ); // szinkronszo - head hi byte
        SEND( 0xD4 ); // szinkronszo - head low byte
        SEND( 0x10 ); //ADAT0
        ChkSum+=0x10;
        SEND( 0x11 ); //ADAT1
        ChkSum+=0x11;
        SEND( 0x12 ); //ADAT2
        ChkSum+=0x12;
        SEND( 0x13 ); //ADAT3
        ChkSum+=0x13;
        SEND( 0x14 ); //ADAT4
        ChkSum+=0x14;
        SEND( ChkSum ); //ADAT5=5A -> ellenorzo osszeg
        SEND( 0xAA );   //dummy byte
        COMMAND( 0xC001 ); //energiagazdalkodas: minden aramkor ki (vevo kikapcs)
        LOW_LED();
        _delay_ms(400);

    };
    return(0);
}


      A program a mikrovezérlő belső 1MHz-es órajelén működik és 6 darab adatcsomagot küld a vevőnek minden 400ms-ban. Az átláthatóság érdekében minden láb az RF modul lábainak megfelelő nevet kapta.

COMMAND
A parancsokat sorosan kell küldeni, mindenik 16 bit és csak akkor vannak értelmezve, ha az nSEL láb alacsony. Az SCK órajel felfutó élénél tolódnak bele a bitek az RF modul regiszterjébe (MSB-vel kezdve), ezért minden bit küldése előtt az SCK lábat alacsonyra, a küldés után pedig magasra kell állítani. A bitek elküldése során érkezhet egy megszakítás az nIRQ lábon, amit egy "temp" nevű változó tárol és a parancs küldésének befejeztével a függvény ezt visszatéríti. Ez az érték a megszakítás okát tartalmazza, ám ebben a példában nem foglalkozunk vele.
SEND
A küldendő információ is ugyanúgy sorosan távozik, ám ennek hossza csupán 8 bit lehet, különben csak az első 8 bit kerül elküldésre (a MSB-től számítva). A FSK információ akkor nyer értelmet, ha az nSEL láb magas és csak az nIRQ lefutó élén szabad kiküldeni. A programban polling módszerrel várjuk meg míg nIRQ láb nem magas (azaz csökkenni kezd). Az adatbit elküldése után ismét magasra ugrik amit megint csak pollinggal kell megvárni.
main
Mielőtt bármit is állítanánk szükséges egy 200-300ms-os várakozás (itt: 500ms), hogy készülék beinduljon. Ezután lehet inicializálni a lábakat, az nSEL magasra emelésével inicializálódik az SPI interfész is. A while(1) előtt vannak elküldve a konfigurációs parancsok, amelyek alapján az adó végig üzemelni fog. Ezeket nem részletezem, mert az adatlapban bőven el van magyarázva mindenik. A parancsok sorrendje nem mindegy, például a frekvenciasávot és a vivőfrekvenciát még azelőtt be kell állítani mielőtt a PLL szintézert bekapcsolnánk. Mindenik parancsnak van egy előtagja, mely a parancs típusát jelzi, például minden energiagazdálkodási parancs C0-val (11000000) kezdődik. A végtelenciklus a LED és az adó bekapcsolásával kezdődik, ami után 3 előtagot küldünk. Ennek bevezető szerepe van, míg minden áramkör stabilizálódik és a vevő is észleli hogy értelmezhető információ van a levegőben (például felébred az alvó üzemmódból). Ezután következik a szinkronszó. Erre azért van szükség, hogy a vevő rászinkronizálódjon az adóra és várja a hasznos információt. Ezt ki lehet kapcsolni a vevő oldalon, de azzal nő a hibás adatok vételének esélye. A ChkSum változóhoz mindig hozzáadjuk az elküldött bájtot, és utolsó hasznos információként, mint ellenőrzőösszeget küldjük a vevőnek. A vevő is majd ugyanígy összead minden fogadott bájtot és összehasonlítja az utolsónak fogadott adattal. Ezt követően kikapcsoljuk az adót a LED-del együtt és várakozunk 400msec-et. Az adatlapban lévő program hosszabb csomagokat küld ezért az ellenőrzőösszeg meghaladja a 8 bitet, így ennek csak az első 8 bitje kerül az adásra.

Az adó működése lemérhető a FSK és az nIRQ lábon. Ha FSK láb oszcillál akkor az adó megkapja az adatokat, ha az nIRQ láb is oszcillál akkor értelmezi és el is küldi ezeket. Egy kézi multiméter is kijelzi ezt a feszültségváltozást azonban az adatok helyességét nem garantálja.


RFM01 - vevő


Tulajdonságok:
  • Teljesen integrált (kevés alaktrész, egyszerű kivitel)
  • Nem igényel gyártási összehangolást
  • Gyorsan beállítható, programozható, magas-felbontású PLL
  • Képes a gyors frekvenciaugratásos módszerre
  • Nagy adatátviteli sebesség (115.2kbps digitális üzemmódban és 256kbps analóg üzemmódban)
  • Közvetlen differenciális antennabemenet
  • Programozható alapsávszélesség (67 - 400kHz)
  • Analóg és digitális RSSI kimenet
  • AFC (Automatic Frequency Control)
  • DQD (Data Quality Detection)
  • Beépített szűrés és CR (Clock Recovery)
  • RX mintafelismerő
  • SPI busz a mikrovezérlővel való kommunikációhoz
  • Reset és órajel a mikrovezérlőnek
  • 16 bites FIFO a vett adatoknak
  • Mikrovezérlőmentes önálló üzemmód
  • Alacsony kitöltésű tényezőjű üzemmód (< 0.5mA áramfelvétel)
  • Standard 10MHz-es referencia kvarckristály belső kalibrálással
  • Alternatív OOK támogatás
  • Időzítő
  • Alacsony tápfeszültségszint érzékelő
  • 2.2 - 5.4V üzemfeszültség
  • Alacsony áramfogyasztás
  • Alacsony készenléti áramfelvétel (0.3μA)
  A DIP tokozású változat egy 16.5x13.2mm-es nyomtatott áramkör 2x6-es tüskesorból álló csatlakozóval, az SMD tokozású változat pedig 15.9x16.1mm-es lemez, 2x7-es szélső galvanizált forrasztási pontokhoz vezetett csatlakozással. A modulon található leragasztott chip (vagy "csepp-IC") tartalmazza az FM vevőt.
SDI - Serial Digital Interface: SPI bemenet, erre a lábra érkeznek a működési paraméterek
SCK - Serial ClocK: SPI órajel bemenet
nSEL - negált chip SELect: a modul csak akkor értelmezi az SPI adatokat, ha ezen a lábon 0V van.
nIRQ - negált chip Interrupt ReQuest: megszakítás kimenet, melyről ha 0V-ot olvasunk, az megszakítást jelent
FFIT/SDO - az érkező információ kijövete, amit fel lehet dolgozni
CLK -  CLocK: órajel kimenet, mely a mikrovezérlő órajeleként szolgálhat. Ha nincs szükség rá, akkor ki lehet kapcsolni.
VDI - Valid Data Indicator: a feldolgozható adatok érkezését jelzi (pl az nIRQ helyett ezt is le lehet kérdezni)
DATA/nFFS -a beérkező adatokat (DATA) erről lehet leolvasni ha nem használunk FIFO-t (nFFS)
DCLK/CFIL/FFIT - Digital CLocK/Capacitor FILter/FIFO It: vett órajel/analóg szűrőkondi/FIFO telítettségjelző
nRES - negált RESet: a mikrovezérlő RESET lábára kell kötni (opcionális)
Ant - antenna kimenet, mely lehet egy darab vezeték de akár komplexebb szerkezet is
VDD - Voltage Drain Drain: pozitív tápveszültség
VSS vagy GND - Voltage Source Source vagy GrouND: negatív tápfeszültség

      Ezekre a lábakra is ugyanaz igaz mint az adónál, azaz az SMD tokozatú nyák esetében mindenik GND kivezetés egy-egy áramkört lát el tápfeszültésggel. Az alacsony fogyasztás érdekében nem tápláljuk azokat az áramköröket amelyekre nincs szükség. A mikrovezérlő oldalon az nRES kivételével teljesen mindegy milyen portra mennek a kivezetéseket, legalább is ha az SPI kommunikációt szoftveresen valósul meg. Hardveres vezérlés esetén viszont az SDI kivezetést a MOSI lábra, az SCK kivezetést az SCK lábra, az nSEL kivezetést pedig az SS lábra kell csatlakoztatni (AVR mikrovezérlők esetén).


      Ha FIFO üzemmódban vesszük az adatokat, akkor az alábbi diagram érvényes. Ebből az derül ki, hogy az nSEL végig nullán kell maradjon a kiolvasás során. Az ábrán csak a vétel eleje látható, az első 16 állapotjelző bit ami minden egyes érkező csomag előtt jelen van. Olvasáskor tehát ezeket át kell ugorni. Gyors üzemmódban csak az első 4 bit számít állapotbitnek, azonban vigyázni kell, hogy az SCK ne legyen nagyobb a kvarc negyedénél azaz 2.5MHz-nél (éppen ezért használnak annyi nop() utasítást az adatlapban lévő példában, ahol a mikrokvezérlő is 10MHz-ről üzemel).

 Az vevőmodul blokkvázlata a következő:
 LNA: Low-Noise Amplifier: alacsonyzajú erősítő 250Ω-os bemenő impedanciával. Ha az antenna impedanciája ettől eltér (pl. 50Ω), akkor egy külső illesztőáramkörre van szükség, hogy az impedancia megfelelő legyen és minél kisebb zajt vegyen. Az erősítő nyeresége változtatható 0, -6, -14 és -20dB között az jelerősséghez viszonyítva.
MIX: I/Q down converter MIXer: demodulálás előtt szét kell választani az I (In-phase - fázisban lévő azaz pozitív frekvencia) és Q (Quadrature - 90 fokkal eltolt fázisú azaz negatív frekvencia) jeleket mert ezek sosem interferálnak egymással. A szétválasztó modulokat a helyi feszültségvezérelt oszcillátor (VCO) hajtja.
BB Amp/Filt/Limiter: alapsávi szűrők, melyek sávja programozható. Ezzel lehet beállítani a vevő üzemi frekvencisávját. A szűrő egy hetedrendű Butterworth aluláteresztő 40dB-es folytással dupla sávszélességben. Az offset frekvencia kiiktatása egy 7kHz-es vágási frekvenciájú felüláteresztő szűrővel történik.
RSSI: Received Signal Strength Indicator: jelerősség mérő, melynek kimenete magasra vált ha a jelerősség meghalad egy beprogramozott értéket (COMP - Comparátor), azonban képes analóg jelt is szolgáltatni.
DQD: Data Quality Detector: adatminőség jelző, mely figyeli a megszűrt I és Q jeleket megszámolván az egymást követő 0->1 és 1->0 tranzíciókat. Ezzel előjelzi a BER (Bit Error Rate) romlását. Be lehet állítani neki egy küszöbértéket ami alatt gyenge vételt jelezzen. Ha a FSK deviációja közel áll az adatsebességhez, akkor 4 tranzíciónak kell történnie egy bit periódusideje alatt. Minél kisebb az adatsebesség annál több tranzícióra lehet számítani.
AFC: Automatic Frequency Control: automatikus frekvenciaszabályzás, minek segítségével a vevő rászinkronizálódhat a vett jelre.
I/Q Demod: a megszűrt I/Q jelek demodulátora mely kimenete egy 10kΩ-os ellenállással a DCLK lábra van  vezetve. Analóg üzemmódban a DCLK láb és a negatív tápfeszültség közé egy kondenzátort kell rakni, ami így egy RC analóg aluláteresztő szűrőt eredményez. A kondenzátor értéke az átviteli sebességtől függ.
Data filt. CLK Rec: digitális üzemmódban ez a blokk kerül felhasználásra. Az adatsző egy analóg RC szűrőből és egy hiszterézises komparátorból áll. Ebben a blokkban van egy órajel-visszaállító (CR - Clock Recovery) áramkör is amely szinkronizált órajelet biztosít az adatoknak amivel azok a FIFO-ba kerülnek. Ennek három sebessége van: lassú (magas immunitás a zajra), gyors (nem szükség a pontos timing)  és automatikus (váltogat a lassú és gyors között).
LBD: Low Battery Detector: alacsony feszültségszint érzékelő, mely minden 8ms-ban megméri a feszültséget és megszakítást generál, ha a beprogramozott érték alá csökken.
WTM: Wake-up TiMer: időzítő, mely a takarékos üzemmódban játszik szerepet. Az ébresztés 1ms-tól néhány napig terjedő időtartamra programozható be, 5%-os pontossággal. Minden bekapcsolásnál, majd minden 30 másodpercben újrakalibrálja magát. Ha a kvarcoszcillátor éppen nem megy (pl. alvó üzemmód), akkor bekapcsolja egy pár ms-re, hogy újrakalibrálhassa magát.
Xosc: kvarcoszcillátor: a panelen lévő 10MHz-es kvarcoszcillátor, melynek két szerepe van: referencia frekvenciát biztosít a PLL-nek és órajelet szolgáltat a CLKdiv frekvenciaosztó blokkon keresztül a külső mikrokontrollernek (hogy ne kelljen annak is külön kvarcot szerelni). A kvarc hangolókapacitása programozható. Ha az RF modul alvó üzemmódba léptető parancsot kap a mikrovezérlőtől, az oszcillátor nem áll rögtön le, hanem további órajeleket küld, míg a mikrovezérlő is "elalszik".

       Akár az adó esetén, ennek az az adatlapjában is található példaként áramkör kód az AVR és PIC mikrovezérlkőkre. Én itt is egy ATmega8 avr mikrovezérlőt használtam az alábbi bekötéssel. Az áramkör a fenti adó jelét veszi, azaz 915MHz-re van hangolva, a helyes vételkor bekapcsolja D1 LED diódát 100ms időtartamig, majd kikapcsolja. Ezt ismétli folytonosan ezért csak egy pislákoló LED jelzi a helyes működést. Az adó 400ms-os időközönként sugároz, ezért a vevőnek is ilyen időközönként kell jeleznie. A vevőmodult FIFO módban használtam, az adatlap szerint ekkor a FIFO  nélküli üzemmódban használandó lábat fel kell húzni a pozitív tápfeszültségre.

 Az vevőmodul SPI interfésze is szoftveresen van vezérelve (ahogy az adatlapban) vagyis az SCK órajel minden taktusát külön kell a lábra rakni. 

A vevő kódja C-ben

#define F_CPU 1000000UL //rendszer orajel
#include <avr/io.h>
#include <util/delay.h>

#define SCK PB5 //SPI orajel
#define SDI PB3 //SPI adat
#define IRQ PC3 //megszakitas
#define SEL PC2 //chip select
#define FSK PC4 //bejovo adat (SDO)
#define LED1 PD5//ha helyes a vett adat

#define LED1_OUTPUT() DDRD |= (1<<LED1)
#define HI_LED1() PORTD|= (1<<LED1)
#define LOW_LED1() PORTD&=~(1<<LED1)

#define SEL_OUTPUT() DDRC |= (1<<SEL)
#define HI_SEL() PORTC|= (1<<SEL)
#define LOW_SEL() PORTC&=~(1<<SEL)

#define SDI_OUTPUT() DDRB |= (1<<SDI)
#define HI_SDI() PORTB|= (1<<SDI)
#define LOW_SDI() PORTB&=~(1<<SDI)

#define IRQ_INPUT() DDRC&= ~(1<<IRQ)
#define IRQ_HI() PINC&(1<<IRQ)

#define SCK_OUTPUT() DDRB |= (1<<SCK)
#define HI_SCK() PORTB|= (1<<SCK)
#define LOW_SCK() PORTB&=~(1<<SCK)

#define FSK_INPUT() DDRC&= ~(1<<FSK)
#define FSK_HI() PINC&(1<<FSK)

unsigned char BUFFER[22]; //tomb amibe a FIFO adatok kerulnek

void INIT(void)
{
    SCK_OUTPUT();
    SDI_OUTPUT();
    SEL_OUTPUT();
    IRQ_INPUT();
    FSK_INPUT();
    LED1_OUTPUT();
    HI_SEL();
    HI_SDI();
    LOW_SCK();
}

unsigned int COMMAND(unsigned int cmd)
{
    unsigned char i;
    unsigned int temp=0;
   
    LOW_SCK();
    LOW_SEL();
    for(i=0;i<16;i++)
    {
        temp<<=1;
        if(FSK_HI())temp|=0x0001; //SDO
        LOW_SCK();
        if(cmd&0x8000) HI_SDI(); else LOW_SDI();
        HI_SCK();
        cmd<<=1;
    };
    LOW_SCK();
    HI_SEL();
    return(temp);
}

unsigned char RECEIVE(void)
{
    unsigned char i,Result;

    LOW_SCK();
    LOW_SDI();
    LOW_SEL();
    for(i=0;i<16;i++) //allapotbitek atugrasa
    {
        HI_SCK();
        HI_SCK();
        LOW_SCK();
        LOW_SCK();
    }
    Result=0;
    for(i=0;i<8;i++) //egy Byte kiolvasasa
    {
        Result<<=1;
        if(FSK_HI()) Result|=1;
        HI_SCK();
        HI_SCK();
        LOW_SCK();
        LOW_SCK();
    };
    HI_SEL();
    return(Result);
}

int main(void)
{
    unsigned char i,j,ChkSum;

    _delay_ms(500); //mig az RF modul boot-ol
    INIT();
    COMMAND(0x0000);//allapotolvaso: kiuriti a megszakitasokat
    COMMAND(0x9968);//konfig: 915BAND, kristaly be, 11.5pF, +/-200kHz savszelesseg
    COMMAND(0xA7D0);//vivo: 915MHz
    COMMAND(0xC847);//adatsebesseg: 4.8kbps
    COMMAND(0xC69B);//AFC...
    COMMAND(0xC42A);//adatszuro: a(CR) nem megy magatol, Digital filter, DQD=2
    COMMAND(0xC240);//energiagazdalkodas: CLK=1.66MHz
    COMMAND(0xC080);//vevo: nincs CR, nincs zajerosites, -103dB indikator, vevo kikapcs
    COMMAND(0xCE84);//FIFO: FIFO kiuritese
    COMMAND(0xCE87);//FIFO: FIFO megtoltese szinkronszo utan, 16 bites FIFO
    COMMAND(0xC081);//vevobeallito: ...vevo bekapcs
    i=0;

    while(1)

    {
        while(!(IRQ_HI())) //nIRQ polling
        {
            BUFFER[i++]=RECEIVE();//FIFO adat -> BUFFER
            if(i==6) //ha mar benne van a ChkSum is
            {
                i=0;
                COMMAND(0xCE84); //FIFO kiurites
                COMMAND(0xCE87); //FIFO elokeszites a kovetkezo folyamra
                ChkSum=0;
                for(j=0;j<5;j++) ChkSum+=BUFFER[j]; //ellenorzoosszeg
                if(ChkSum==BUFFER[5]) //ha helyesek az adatok
                {
                    if(ChkSum==0x5A)  //ado adatok: 20+..+24=AA
                    {
                        HI_LED1();    //LED1 be
                        _delay_ms(100);
                        LOW_LED1();
                    }
                }
            }
        }
    }
    return(0);
}


      A program a mikrovezérlő belső 1MHz-es órajelén működik és 6 darab adatcsomagot vár. Az átláthatóság érdekében itt is minden láb az RF modul lábainak megfelelő nevet kapta (kivéve az SDO, neki a FSK jobban talált). A COMMAND parancs ugyanaz mint az adónál, az nIRQ helyett viszont a FSK lábat vizsgáljuk, hiszen megszakítás ebben az programban csak akkor érkezhet, ha a vevő észlel valamit.

RECEIVE
Az nSEL láb lenullázzása (aktivvá tétele) után kiolvassuk az első 16 állapotjelző bitet és nem foglalkozunk vele. Ezután a 8 bites hasznos információt a FSK láb állapota szerint a "Result" változóba toljuk. Az nSEL láb újra magasba helyezése után a függvény visszatéríti a "Result" változó tartalmát.
main
A főprogram eleje hasonlít az adóéhoz, a végtelen ciklusban azonban egy megszakításra vár az nIRQ  láb felől. Ez akkor érkezik meg, ha a vevő jól rá van hangolva az adóra és értelmezhető információt vesz. A vevő beállító parancsai között ott szerepel a FIFO megtöltésének feltétele is, melyet a szinkronszóhoz kötöttem. Lehetett volna a VDI lábhoz is kötni a feltételt, ekkor a VDI-hez tartozó kondíció döntötte volna el, hogy helyes-e az adat vagy sem. A VDI kondíciója lehet a jelerősség mérő (RSSI) az adatminőség mérő (DQD), ezek kombinációja, vagy CRL (Clock Recovery Lock) áramkör. A FIFO megtöltését lehet feltétel nélkülire is állítani, ám ekkor minden egyéb wi-fi eszköz frekvenciája bezavar. A vevő tehát csak a szinkronszó után kezdi felhasználni a vett adatokat. Tudván, hogy a várt csomagok hosszúsága 6 bájt, meghaladván ezt ki kell üríteni a FIFO-t , hogy legyen hely a következő csomagnak. A FIFO minden értékét egy BUFFER nevű tömben tároltunk, így rögtön ki is lehet számolni az ellenörzőösszeget. Ha ez megeggyezik a hatodik bájttal, akkor a vett érték helyes. A példa kedvéért az ellenőrző összeget összehasonlítottam a tényleges értékkel is, hogy meggyőző legyen az eredmény, mert az első próbálkozásoknál mind 0-val pakolta meg a tömböt (mert az adatsebesség nem talált a két modul között) és ezért az ellenörzőösszeg is 0 lévén heylesnek bizonyult. Az adatok helyességét egy 100msec-ig világító LED jelzi.

A FSK modulációnál a vevő sávszélessége egyenlő az adó frekvencia deviációjával + az adatsebességgel + némi extra frekvencia komponenssel. Ebben az esetben 180 + 4.8  = 184.8kHz, és az ehhez legközelebb eső de nagyobb sávszélességet válasszuk ki a táblázatból, ami éppen 200kHz.


Próba áramkör

 

 Adó

Az adóáramkört és a mikrovezérlőt egy próbapanelre szereltem fel. Két adót használtam, a mikrovezérlő hol az egyiknek, hol a másiknak adott engedélyt a sugárzásra.
A beállított paraméterekkel a 6 csomag elküldése kb 10ms-os villanást eredményez a LED-eken. Az egyik adó sokat vacakolt míg ki nem derült, hogy egyáltalán nem veszi igénybe a ráforrasztott oszcillátort. Ezt először a LED-eken volt tapasztalható: míg az egyik adó LEDje 10ms-ig világított a másiké kb 50msec-ig, ugyanazzal a programmal. Ezek után kiforrasztottam a kvarcot és ugyanaz volt az eredmény. Az oszcillátort egy külső órajelre állított mikrovezérlővel próbáltam ki, ám nem volt vele baj. Talán csak forrasztási hiba lehetett, mert miután visszaforrasztottam a helyére, működni kezdett az adásvétel.


Vevő

A vevőáramkör is ugyanúgy próbanyákra került. A zöld LED az 1.adó (a fenti képen a távolabbi), a piros LED a 2.adó adatainak helyességét jelzi.




Mikrovezérlő

Az ATmega8 egy SMD tokozatú mikrovezérő, melynek a NYÁK-ját magam készítettem.

 

Antenna tervezés

      Az adatlapban szereplő táblázat szerint az RFM02 adó akkor tudja leadni a maximális teljesítményt (6dBm = 3.98mW), ha az antenna impedanciája 915MHz frekvencián 8.7+j77Ω (ez az adó belső impedanciája, Zb)



A táblázat szerint az antenna induktív, de ezt le ellenőrizhető a fáziskésés meghatározásával:



Láthatóan nem teljesen induktív, a feszültség fázisa 83.55 fokot siet az áram fázisához képest, nem pedig 90 fokot. Az impedancia reaktáns részéből kifejthető a frekvencia függő induktív és kapacitív reaktancia:



Még ha reaktáns részt kapacitással konjugáljuk is, az antenna hossza legalább λ/4 kell legyen aminek rezisztens része kizárt, hogy csupán 8.7Ω legyen. Az impedanciát tehát illeszteni kell. Az illesztés történhet az adó és az antenna felől is vagy akár mindkét oldalon, ám ez utóbbi dupla veszteséggel jár. Ahhoz, hogy az adó teljes gőzzel sugározzon, a saját belső impedanciáját kell lássa. Tegyük fel, hogy a λ/4 (8.191cm) hosszúságú antennát nem közvetlenül az adómodulra forrasszuk, hanem például egy Zo = 75 ohmos koaxiális kábellel kötjük az adóra. Amennyiben ez a vezeték λ/10-nél (3.27cm) hosszabb, akkor már transzmissziós vezetéknek számít és figyelembe kell venni a karakterisztikus impedanciáját. Mivel az antenna impedanciáját nem ismerjük, és ha vektoriális analizátorral egy reflexiómentes kamrában megmérjük, akkor sem biztos, hogy az a végleges pozíciójában is ugyanannyi lesz, ezért illesszük az adó és a kábel impedanciáját (mert azokat ismerjük és nem is változnak). Az illesztéshez a legegyszerűbb L-tagú LC illesztőt választom és az Impedancia illesztés bejegyzés példáihoz hasonlóan Smith diagrammal és a 4nec2 programmal számolom ki a megfelelő értékeket. Általában az antenna impedanciáját szokás a kábel vagy az adó/vevő impedanciájához illeszteni, hogy az adó/vevő jó impedanciát lásson. Ebben a példában a kábel impedanciáját illesszük az adó impedanciájához, ezért a kiszámolt párhuzamos és soros értékek helyet cserélnek majd. Hogy könnyebb legyen, fordítva számolok (az adót illesztem a kábelhez), ezért az áramkör két végét majd fel kell cserélni.
  1. A normalizált impedancia: zb = Zb/Zo =  0.116+j1.026. Ezt bejelöljük a diagramon: a vízszintes tengelyen lévő r = 0.116 kör és a függőleges tengely pozitív oldalán lévő jx = 1.026 körív metszéspontja. Ez a pont az 1+jx körön kívül esik, ezért a párhuzamos + soros sorrendű elrendezést alkalmazzuk az L-tagban. (Ez fog később felcserélődni).
  2. Rajzolunk egy közép centrikus (SWR) kört a diagramra, amely áthalad zb ponton, majd zb ponttól, a diagram origóján át húzunk egy egyenest, míg metszeni fogja a kör túlsó oldalát. Itt lesz a normalizált admittancia: yb = 0.116-j0.99.
  3. Rajzoljuk meg az admittancia (baloldali) 1+jx kört. Ha soros kapacitást szeretnénk (bár választásunk nem igazán van), akkor vigyük yb pontot ennek a körnek a negatív szélére ugyanazon az r kör mentén (=> 0.116-j0.29). A megtett út hossza X = -j0.7.
  4. Ezt a pontot visszaalakítjuk impedanciába (SWR kör + origót átszelő egyenes) => 1+j3. Ha párhuzamos kapacitást szeretnénk, vigyük ezt a pontot a diagram vízszintes tengelyéig (1+j0) az r = 1 kör mentén. A megtett út hossza B = j3.
Az alábbi képen az Smith diagram tekinthető meg (klikk rá a nagyobb felbontásért).


Ezek után ki lehet számolni az induktivitást és a kapacitást és meg lehet rajzolni a (tükrözött) áramkört:



Ha a soros kapacitás mellé párhuzamos induktivitást szeretnénk, akkor a 3. lépésben yb pontot vigyük fel az 1+jx admittancia kör pozitív szélére => 0.116+j0.29, így a megtett út X = -j1.28 lesz. Ezt a pontot visszaalakítva impedanciába (SWR kör + origót átszelő egyenes), az 1+j3 pontba jutunk, amit ha a vízszintes tengelyig viszünk, akkor a B = -j3 megtett utat kapjuk. Az így kapott kapacitás és induktivitás:


Az alábbi képen a 4nec2 programmal kiszámított illesztők láthatók (klikk a nagyobb felbontásért):


Az, hogy a kábelt illeszük az adóhoz, vagy az adót a kábelhez, ugyanazokat az eredményeket adja, csupán az áramkör tükröződik meg az előjelek miatt. A program képletes számításai pontosabb eredményt adnak, ám ha papíron számolunk, akkor gyorsabb a Smith diagram alkalmazása. A hátránya a Smith diagramon való rajzolgatásnak, hogy a vonalak vastagsága, a körök tökéletlensége és a tizedesnyi hibák miatt nem lehet hajszál pontosan megközelíteni a képletesen kiszámolt értékeket.

     Minél hoszabb kábelt, minél több csatlakozót és illesztőt használunk, annál jobban esik a teljesítmény. Az RF modulok elég kicsik ahhoz, hogy közvetlenül az antenna talppontjára lehessen őket forrasztani, egy egyszerű elosztó (splitter) dobozkában is kényelmesen elférnek. Az antenna és az RF modul közti távolság helyett inkább a mikrovezérlő és az RF modul között hagyjunk hosszabb vezetéket, de 1-2 méternél ne nagyobbat, különben időzítési zavarok (timing) léphetnek fel a kommunikációban. A következő képen a fenti módszerrel illesztett vevő-modul látható egy kis árnyékolt dobozba szerelve.



Nincsenek megjegyzések:

Megjegyzés küldése