Už dávnejšie sme uverejnili článok:
„Transkodér (na čo (nám) to je?) a Diferenciálny výškomer“,
v ktorom je (v druhej polovici článku) spomínaný aj - podľa nás výnimočný senzor MPL3115A2 od firmy NXP (predtým Freescale, ešte predtým ako divízia Motoroly).
Dostali sme niekoľko mailov od čitateľov našej web-stránky, v ktorých nás žiadajú o podrobnejšie informácie, ako s týmto senzorom pracovať – ako z neho (čo najjednoduchšie) „vydolovať“ informácie o (tlaku, teplote, ale najmä) o (nadmorskej) výške.
Tieto hodnoty by chceli – podobne ako my, využiť na meranie výšky letu svojich modelov, prípadne ako vario.
A keďže sme sa aj my ťažko „prepracovávali“ ku zrozumiteľným a jednoducho použiteľným informáciám, rozhodli sme sa, že sa o naše skúsenosti podelíme.
autor: Janko O.
V spomínanom článku sme uviedli, že Tip na tento senzor sme dostali od Andreja B., za čo sme mu nesmierne vďační. Pretože sme prepátrali Internet a nenašli sme iný podobný senzor, ktorý by bol pre modelárske využitie vhodnejší.
Nie že by bolo málo všakovakých tlakomerných senzorov (napr. tiež už, ale nie v dobrom spomínaný BMP085), ale ... Ide o to, že (softvérová) práca s nimi je nepohodlná:
pri analógových senzoroch (napr. MPX4115A) treba čo najpresnejšie zmerať ich výstupné napätie (čo môže byť značný (hardvérový) problém), to komplikovane prepočítať na atmosférický tlak a ten ešte komplikovanejšie prepočítať na zodpovedajúcu nadmorskú výšku.
pri digitálnych senzoroch (napr. tom nami neobľúbenom BMP085) síce odpadá meranie napätia, ale získanie hodnoty atmosférického tlaku je podľa nášho názoru nezmyselne komplikovaná a nepohodlná cesta, požierajúca zbytočne veľa systémových zdrojov nadradeného systému (pripojeného mikrokontroléra, či počítača). No a zo získaného atmosférického tlaku treba opäť komplikovane a nepohodlne vypočítať zodpovedajúcu nadmorskú výšku. Brrr. Skrátka des.
Všetky tieto procedúry vyžadujú pomerne veľa neprehľadných riadkov kódu a spotrebujú aj isté (nezanedbateľné) množstvo programovej pamäte mikrokontroléra.
Takto komplikovane musí užívateľ senzora BMP085 vypočítať atmosférický tlak.
A zhruba rovnako komplikovane z neho ešte musí vypočítať aj nadmorskú výšku.
No a ako to robí (nami milovaný) MPL3115A2?
Jednoducho! Všetky vyššie spomínané komplikované a nepohodlné výpočty a procedúry urobí vo vnútri za nás. Stačí len:
senzor iniciovať: „povedať“ mu, čo má merať (či teplotu, alebo atmosférický tlak, alebo rovno nadmorskú výšku) a prípadne ako dáta predspracovať: napr. spriemerovať až 128 meraní za účelom odstránenia šumu a kolísania tlaku … Toto „vybavia“ napr. len dva jednoduché riadky kódu.
namerané a vypočítané hodnoty (napr. nadmorskú výšku priamo v metroch) si jednoducho „vyzdvihnúť“ z registrov senzora, za účelom ich zobrazenia na displeji, či prenesenia do prijímača telemetrie a pod. Na to opäť stačia dva, alebo tri jednoduché riadky kódu, podľa toho, na koľko desatinných miest chceme údaj o nadmorskej výške (alebo atmosférickom tlaku) merať.
Tento senzor je určený pre napájanie napätím 3,3 Voltu a so svojim okolím komunikuje prostredníctvom dvojvodičovej zbernice IIC (alebo I2C, I2C ...).
Takže aj zbernica aj nadradený systém (mikrokontrolér alebo počítač) musia byť na toto napätie uspôsobené. Ak používate mikrokontrolér napájaný napätím +5 Voltov (tak ako my), tak na zbernici I2C medzi senzorom a mikrokontrolérom musí byť zaradený obojsmerný prevodník napäťových úrovní (nebojte sa, je to jednoduchučké zapojenie s dvomi tranzistormi a štyrmi rezistormi – bude popísané v ďalšom článku) .
No a teraz si to poďme ukázať konkrétne tých pár riadkov kódu, aby sme jasne videli, že aké je to jednoduché a že je to vlastne „brnkačka“ .
Podotýkam, že my na prácu s mikrokontrolérmi PIC od firmy Microchip používame program PIC Baic Compiler Pro, ktorý sa nám javí oveľa jednoduchší a prehľadnejší, ako všeobecne používané „Céčko“. Navyše my PIC Basic Compiler považujeme za vyšší programovací jazyk, ktorý je okrem bežných príkazov ako If , For, While a pod. na rozdiel od iných ešte vybavený príkazmi, ktoré sú akoby na mieru šité pre elektronikov – bastličov . Napr.:
na zmeranie frekvencie (alebo spočítanie počtu impulzov) stačí jediný príkaz: Count
na zmeranie šírky impulzu stačí jediný príkaz: PulsIn
na vygenerovanie impulzu/impulzov presne definovanej šírky stačí jediný príkaz: PulsOut
na zobrazenie na LCD displeji stačí jediný príkaz: LcdOut
na zápis do I2C zariadenia (v našom prípade senzora MPL3115A2) stačí jediný príkaz: I2CWrite
na čítanie z I2C zariadenia stačí jediný príkaz: I2CRead
..…
Inicializácia senzora MPL3115A2: to sú naozaj dva riadky kódu, hoci my použijeme ešte ďalšie dva, aby sme si kód sprehľadnili.
Keďže na zbernici I2C môže byť súčasne pripojených viacej (až 128) zariadení, tak aby bolo zrejmé, s ktorým z nich mikrokontrolér práve komunikuje, každé I2C zariadenie má svoje označenie (číslo, meno) – teda Adresu. Senzor MPL3115A2 má (pevnú, nemennú, výrobcom danú) adresu C0 („Cé Nula“, v Hexa - teda v šestnástkovom vyjadrení). PIC Basic Compiler na Hexa-vyjadrenie používa prefix $, takže adresa Integrovaného Obvodu (senzora MPL3115A2) bude:
AdrIO = $C0
Ako sme si už v úvode povedali, najskôr musíme senzor inicializovať, teda oznámiť mu, čo a ako má merať. To sa (jednoducho) robí tak, že mu po zbernici I2C do určitého („nastavovacieho“) registra pošleme „povel“ (príkaz, číslo).
Adresa tohto pre nás momentálne dôležitého „nastavovacieho“ registra (Control Register 1) bude:
AdrReg = $26
My do tohto registra pošleme „povel“ $B8 (Hexa-číslo B8). Adresu obvodu a ani adresy registrov sme si „nevycucali“ z prsta, ale vyčítali sme ich z datašítu nášho senzora. Rovnako sme si „nevycucali“ z prsta ani „príkaz“ $B8, ale sme na základe dokumentácie „poskladali“ taký povel, ktorý senzor nastaví do toho - pre nás najvhodnejšieho a súčasne najjednoduchšieho režimu. $B8 teda znamená:
senzor je nastavený do režimu Altimeter (výškomer (teda nie tlakomer))
je nastavený tak, že sám rýchlo meria a vypočítava výšku, túto (nestabilnú a „poskakujúcu“) hodnotu spriemeruje zo 128 vzoriek (OverSample Ratio = 128) a výsledok každých 512 milisekúnd uloží do svojich výstupných registrov, aby si užívateľ takto predpripravenú (vyhladenú - „umravnenú“) hodnotu mohol „vyzdvihnúť“
senzor je v režime Stand By (pripravený a čaká na spustenie - na Aktiváciu)
Z dôvodu maximálnej hardvérovej ale aj softvérovej jednoduchosti sme zvolili režim činnosti senzora typu Polling Data. Vtedy senzor pracuje sám - nezávisle a nie je potrebné ho prostredníctvom (ďalšej) Interrupt-linky kontrolovať, či už výsledky má alebo nie. Vzhľadom na to, že naša telemetria pracuje s intervalom 1 sekunda, je pre nás režim Polling Data plne vyhovujúci, ale hlavne je obvodovo aj programovo jednoduchší.
Po nastavení spôsobu činnosti a uvedení do Stand By režimu je možné senzor Aktivovať. To sa robí „povelom“: $B9.
Ony v úvode spomínané dva riadky inicializácie senzora MPL3115A2 potom vyzerajú nasledovne:
Nastavenie režimu činnosti a uvedenie do stavu pripravenosti (Stand By):
I2cWrite SDa, SCl, AdrIO, AdrReg, [$B8]
Aktivácia senzora:
I2cWrite SDa, SCl, AdrIO, AdrReg, [$B9]
SCl je „Clock“ (hodinový – taktovací – synchronizačný) vývod mikrokontroléra zbernice I2C, v našom (konkrétnom, neskôr uvedenom) prípade napr.: PortA.2.
SDa je Dátový vývod mikrokontroléra zbernice I2C, v našom (konkrétnom) prípade napr.: PortA.3.
Potom celá subrutina (podprogram) inicializácie senzora MPL3115A2 vyzerá nasledovne:
MPL3115_Init:
AdrIO = $C0
AdrReg = $26
I2cWrite SDa, SCl, AdrIO, AdrReg, [$B8]
I2cWrite SDa, SCl, AdrIO, AdrReg, [$B9]
Return
Je samozrejme možné samostatné definovanie Adresy IO a Adresy Registra vynechať a ich hodnoty vložiť priamo do príkazov. Potom si naozaj vystačíme len s dvomi príkazmi kompletnej inicializácie senzora:
MPL3115_Init:
I2cWrite SDa, SCl, $C0, $26, [$B8]
I2cWrite SDa, SCl, $C0, $26, [$B9]
Return
Je zrejmé, že takto sú príkazy akosi menej „čitateľné“ (ako v predchádzajúcom prípade), cez to všetko sa dajú ľudskou rečou preložiť ako:
Prvý príkaz (nastavenie spôsobu činnosti a pripravenosti k meraniu):
Pomocou I2C pošli (zapíš - Write) po linkách SDa a SCl, do obvodu s Adresou $C0, konkrétne do registra s Adresou $26, povel – hodnotu $B8.
Druhý príkaz (Aktivácia – zahájenie merania):
Pomocou I2C pošli (zapíš) po linkách SDa a SCl, do obvodu s Adresou $C0, konkrétne do registra s Adresou $26, povel – hodnotu $B9.
Po takejto úspešnej inicializácii začne senzor do svojich troch 8-bitových výstupných registrov „sypať“ dáta, teda hodnoty nadmorskej výšky a je len na nás, či a ako často si ich odtadiaľ „vyzdvihneme“.
Zmeraná a spriemerovaná (nadmorská) výška v metroch je k dispozícii v 20-bitovom formáte (16 bitov pre celé metre a 4 bity pre centimetre) v troch výstupných registroch senzora:
register 8 najvyšších bitov (OUT_P_MSB) má adresu $01
register 8 stredných bitov (OUT_P_CSB) má adresu $02
register 8 najnižších bitov (OUT_P_LSB) má adresu $03
V skutočnosti register najnižších bitov (OUT_P_LSB) obsahuje len 4 platné bity, tie najvyššie. Zvyšné 4 bity (tie nižšie) nie sú využité.
V budúcej časti si ukážeme, ako si tieto tri registre (Byty (bajty)) zo senzora jednoducho „vyzdvihnúť“ a poskladať tak, aby z nich „vypadla“ nadmorská výška v metroch (registre OUT_P_MSB a OUT_P_CSB) a v centimetroch (register OUT_P_LSB), s presnosťou na jednu šestnástinu metra (cca šesť centimetrov) .