22
Fotogalerie

Pojďme programovat elektroniku: Bigclown a rádiový alarm s akcelerometrem

  • Stavebnici BigClown jsme si ukázali už několikrát
  • Ale vůbec jsme jej neprogramovali
  • Dnes si ukážeme, jak na to v několika příkladech

Po kratší zdravotní přestávce (v letních tropech nemá smysl bastlit – mozek se přehřívá a nefunguje) nastal čas na pokračování našeho seriálu o programování elektroniky.

Tentokrát opustíme svět arduin a podíváme se znovu na českou stavebnici BigClown, kterou jsme si už v našem seriálu ukázali mnohokrát (1, 2, 3), ale nic jsme si vlastně doposud nenaprogramovali. Jelikož se BigClown od Arudina v mnoha aspektech liší, dnes si pro představu ukážeme několik naprosto elementárních ukázek, ze kterých bude na první pohled patrné, v čem je BigClown vlastně jiný (a lepší).

Začneme rozblikáním LED, poté změříme vzdálenost pomocí ultrazvukového dálkoměru HC-SR04 a nakonec si postavíme jednoduchý otřesový alarm. Když jej vezmeme do ruky, začne blikat, rozezní se bzučák, základní destička BigClownu ale především odešle kratičkou rádiovou zprávu, kterou zachytí druhá destička a předá informaci skrze sériovou linku do PC, který by už konečně mohl odeslat třeba e-mail, anebo skrze IFTTT odeslat třeba notifikaci na mobil.

Co je to vlastně ten BigClown

Co je to vlastně BigClown, jsme si už podrobně popsali v několika předchozích článcích, takže jen zrekapituluji, že se jedná o českou prototypovací destičku s hromadou rozšiřujících modulů, jejímž srdcem je 32bitový armový mikrokontroler STM32L083CZ (ARM Cortex M0+).

87507769-10b2-4597-8d27-1d9d1878d25c
Základní deska stavebnice BigClown se jmenuje Core Module a jejím mozkem je armový 32bitový mikrokontroler STM32L083CZ

K dispozici má 192kB úložiště pro náš firmware, 20 kB RAM a na destičce je pro snadné ovládání připájená programovatelná LED, tlačítko, teploměr, akcelerometr a především 868MHz rádiový vysílač SPIRIT1, pomocí kterého může náš program šifrovaně komunikovat s ostatními základními deskami stavebnice BigClown.

Specialitou BigClownu a všech jeho rozšiřujících modulů je optimalizace pro běh na dvě tužkové baterie AAA, které mu dle zátěže vystačí přinejmenším na několik měsíců. Tím se naprosto odlišuje od všech běžných prototypovacích stavebnic na trhu.

cfce22a0-a728-4def-a82c-6e6a7a93ee8c
Pinout základní desky BigClown, aneb popis funkce každého pinu. Nechybí hromada 3,3V univerzálních pinů GPIO, sběrnice I2C a SPI, analogový vstup i výstup a také tři sériové linky.

Příklad z praxe: Na BigClownu jsem si postavil většinu své chytré domácnosti. Zatímco bezdrátová krabička s infračerveným detektorem pohybu PIR, která získaná data o lidské aktivitě v bytě odesílá do centrály každé dvě minuty, vydrží na baterii asi tři měsíce, velká meteostanice, která měří teplotu vzduchu, vlhkost, osvětlení, atmosférický tlak, oxid uhličitý a ke všemu má displej a dvě tlačítka pro spínání lamp v bytě, vydrží na čtyři tužkové baterie AAA zhruba půl roku.

Tak, základní resumé, v čem je BigClown unikátní, bychom měli, a teď už dost teoretické omáčky a jdeme konečně programovat.


V další kapitole založíme nový projekt a zkusíme jej přeložit a nahrát do čipu. Kapitola bude trošku delší, musíme totiž pochopit základní rozdíly oproti Arduinu.

Pokračování 2 / 5

Vytváříme nový projekt pro BigClown

BigClown nemá na rozdíl od Arduina vlastní editor kódu. Namísto toho si stáhnete balík aplikací BigClown Toolchain s vlastním textovým rozhraním. Když Toolchain spustíte, zobrazí se vám (v případě Windows) vcelku běžná textová řádka, podporuje ale všechny nástroje, které budeme potřebovat.

Nejprve vytvoříme nový projekt. Chceme rozblikat LED, a tak do terminálu napíšeme:

bcf create sexy_dioda

Toolchain nyní z Githubu stáhne základní kostru programu s celým SDK (všemi potřebnými zdrojovými soubory) a vše uloží do stejnojmenného adresáře sexy_dioda s hromadou podsložek. Určitě koukněte do sdk/_examples, ve které najdete hromadu hotových příkladů.

5a0776e9-59a9-4479-b6b4-4761bdd834ce
Příkazem k vytvoření nového projektu se z GitHubu stáhlo vše potřebné včetně šablony nového projektu. To vše nyní najdete v novém adresáři sexy_dioda.

Pro náš uživatelský kód je vyhrazena podsložka app, ve které se nacházejí soubory application.c a application.h, což je základ. K jejich editaci můžete použít libovolný textový editor, přičemž já preferuji bezplatný a multiplatformní Visual Studio Code od Microsoftu. Abyste v něm otevřeli celou složku, stačí přímo z příkazové řádky toolchainu napsat code sexy_dioda.

7c161e4d-346d-4662-b5f1-69f0aadb90af
K editaci kódu můžete použít jakýkoliv textový editor, samotný BigClown ale doporučuje multiplatformní a bezplatný Visual Studio Code od Microsoftu.

Zdrojové kódy nového projektu nejsou prázdné, ale BigClown namísto toho použil šablonu s jednoduchým programem, který po stisknutí tlačítka na destičce buď rozsvítí, nebo zhasne vestavěnou LED. Díky šabloně se může každý začátečník seznámit ze základní strukturou programu.

Arduino má hlavní funkci setup, BigClown zase application_init

Zatímco Arduino používá dvě povinné funkce setup (spustí se po startu) a loop (následuje za setupem a její obsah se ve smyčce opakuje stále dokola), BigClown má jen jednu povinnou funkci application_init. Dělá úplně to stejné, co setup ze světa Arduina – čip ji spustí ihned po svém startu.

Kompletní kód výchozí šablony:

#include <application.h>

// LED instance
bc_led_t led;

// Button instance
bc_button_t button;

void button_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param)
{
    if (event == BC_BUTTON_EVENT_PRESS)
    {
        bc_led_set_mode(&led, BC_LED_MODE_TOGGLE);
    }

    // Logging in action
    bc_log_info("Button event handler - event: %i", event);
}

void application_init(void)
{
    // Initialize logging
    bc_log_init(BC_LOG_LEVEL_DUMP, BC_LOG_TIMESTAMP_ABS);

    // Initialize LED
    bc_led_init(&led, BC_GPIO_LED, false, false);
    bc_led_set_mode(&led, BC_LED_MODE_ON);

    // Initialize button
    bc_button_init(&button, BC_GPIO_BUTTON, BC_GPIO_PULL_DOWN, false);
    bc_button_set_event_handler(&button, button_event_handler, NULL);
}

void application_task(void)
{
    // Logging in action
    bc_log_debug("application_task run");

    // Plan next run this function after 1000 ms
    bc_scheduler_plan_current_from_now(1000);
}

Arduino má delay, BigClown plánovač

V šabloně nicméně vidíte zcela dole ještě jednu systémovou (ale nepovinnou) funkci application_task, kterou autoři BigClownu přidali do šablony až později, aby usnadnili přechod ze světa Arduina. Application_task totiž tak trochu napodobuje smyčku loop a to díky tomu, že se na jejím konci nachází příkaz bc_scheduler_plan_current_from_now(1000), který čipu přikazuje, aby za 1 000 milisekund tuto funkci znovu zpracoval. Prodlevu samozřejmě můžete libovolně upravit.

Do jisté míry bychom tedy tuto funkci mohli připodobnit ke smyčce loop, ve které by byl na konci příkaz delay(1000). Jenže opravdu jen do určité míry, ve skutečnosti totiž BigClown funguje úplně jinak. Neblokuje!

0b3d6cdd-25df-467c-b87a-5a5e7cc31cf405b70726-e65f-4141-b349-6fabe06695d23da5bbbf-4f4c-44bc-b11c-c7bdb2d4fe12
První ukázka je jednoduchá. Po stisku tlačítka se rozsvítí, nebo naopak zhasne vestavěná LED na základní desce Core Module. Právě tento příklad se použije z šablony při vytvoření nového projektu.

Ona dlouhá funkce tedy nesděluje čipu: Teď 1 000 ms čekej, blokuj vše ostatní a nic nedělej, ale namísto toho mu řekne, ať si zapíše do speciálního interního plánovače úloh (scheduleru) informaci, že má za tisíc milisekund zavolat funkci application_task. A takhle stále dokola a dokola. Oba přístupy z našeho úhlu pohledu vypadají stejně, odlišnost BigClownu ale spočívá v tom, že v mezidobí může vykonávat celý zástup další naplánované práce, anebo prostě odpočívat a spalovat méně energie.

Pokud tedy budeme potřebovat nějakou funkci spustit třeba až za 500 ms, jednoduše ji zaregistrujeme v scheduleru, stanovíme čas startu a nemusíme blokovat procesor.

BigClown reaguje na událost, aby mohl po zbytek času spát

Zpět ale k našemu kódu, který pro nás vytvořila šablona. Zatímco v hlavní funkci application_init nastartujeme vše potřebné (projděte si okomentovaný kód výše) a funkce smyčky application_task jen každou sekundu vypisuje do sériové linky ukázkovou zprávičku, je tu ještě jedna funkce jménem button_event_handler.

V hlavní funkci přikazujeme čipu, ať ji zavolá tehdy, pokud nastane nějaká událost na systémovém tlačítku. V samotné funkci se pak ptáme, co to bylo za událost. Pokud to byl stisk (BC_BUTTON_EVENT_PRESS), pak pomocí další vestavěné funkce BigClownu přepneme systémovou LED. A to je celé.

Na rozdíl od Arudina, ke kterému bychom připojili tlačítko, tedy nemusíme ve smyčce loop stále dokola číst jeho logickou hodnotu a v případě změny (stisku) rozsvítit LED. Používáme událostní přístup (event-driven), kdy reagujeme až na nějakou akci. Vše ostatní za nás dělá samotný framework BigClownu, takže kód funkčního programu může být docela stručný.

Jak hotový kód přeložit a nahrát do čipu

Jak náš program přeložit a nahrát do čipu destičky BigClown? Vraťme se zpět do příkazové řádky Toolchain a v adresáři našeho projektu zadejme příkaz:

make

který vše přeloží do strojového kód procesoru ARM.

První překlad každého nového projektu bude relativně dlouhý, musí se totiž přeložit i zdrojové kódy celého frameworku. Ale nebojte, každý další překlad už bude velmi svižný, překládá se totiž jen váš uživatelský kód v podadresáři app, který se propojí s již přeloženým podhoubím.

abb3b658-00ed-448f-9528-783e33e8896f
První překlad nového projektu může trvat docela dlouho

Jakmile bude vše hotovo, stačí destičku skrze USB připojit k PC z příkazové řádky konečně inicializovat flashování příkazem:

bcf flash device=COM3

Číslo sériového zařízení COM3 samozřejmě změňte podle toho, jaké vaše destička získala od Windows. Tento případ se týká novější generace základních destiček BigClown s integrovaným USB/UART převodníkem FTDI. Starší generace destičky se dvěma tlačítky, která už ale není v prodeji, má trošku odlišný postup.

371640bd-c00b-46ce-8818-f28f63dc11c0
Flashování našeho programu do armového čipu skrze USB a sériovou linku

Tak, kompilovat a nahrávat program do čipu desky BigClown už umíme, v příští kapitole se tedy podíváme, jak se pracuje s piny GPIO. Rozblikáme LED na nepájivém poli. A nebojte se, už to bude stručnější.

Pokračování 3 / 5

Práce s plánovačem a piny GPIO

Fajn, pojďme si základní šablonu v dalším příkladu rozšířit a to pomocí externí LED, kterou připojíme na nepájivé pole. Tentokrát tedy namísto vestavěné LED budeme měnit logický stav na jednom z pinů GPIO, ke kterému bude skrze tlumící rezistor připojená LED.

Arduino má pro práci s GPIO základní funkce pinMode pro nastavení režimu daného pinu a digitalWrite/digitalRead pro zápis a čtení logické hodnoty na pinu. BigClown je na tom podobně a jako Arduino pracuje i s populárními sběrnicemi I2C, SPI nebo sériovou linkou.

LED připojíme na pin číslo P0. Program rozbliká LED, pokud aktivujeme blikání stisknutím vestavěného tlačítka. Když jej stiskneme znovu, blikání se zastaví.

Kompletní kód druhého příkladu, který si níže popíšeme krok za krokem:

#include <application.h>

// Vestavene tlacitko
bc_button_t tlacitko;

// Pomocne stavove promenne
bool stav_led = false;
bool povoleno = false;

// Blikaci uloha planovace
bc_scheduler_task_id_t blikani;

// Bliknuti LED - tuto funkci zavola planovac
static void blik(){
    // Prohod stav LED
    stav_led = !stav_led;
     // Podle stavu rozsvit/zhasni LED
    bc_gpio_set_output(BC_GPIO_P0, stav_led);
    // Za 500 ms zpracuj ukol blikani, ktery spousti tuto funkci
    bc_scheduler_plan_from_now(blikani, 500);
}

// Udalostni funkce tlacitka
void stisk_tlacitka(bc_button_t *self, bc_button_event_t udalost, void *parametry){
    // Pokud se jedna o stisk tlacitka
    if(udalost == BC_BUTTON_EVENT_PRESS){
        // Pokud uz blikam
        if(povoleno){
            // Vypis do seriove linky zpravu, ze vypinam blikani
            bc_log_info("Vypinam blikani");
            // Z planovaci odregistruj nasi ulohu
            bc_scheduler_unregister(blikani);
            // Anluluj stav LED a nastav logickou 0 na pinu P0
            stav_led = 0;
            bc_gpio_set_output(BC_GPIO_P0, stav_led);
            povoleno = false;
        }
        // Pokud neblikam, zaregistruj novou ulohu planovace,
        // ktera ma spustit funkci blik, a hned tuto ulohu zpracuj
        else{
            bc_log_info("Zapinam blikani");
            povoleno = true;
            blikani = bc_scheduler_register(blik, NULL, bc_tick_get());
        }
    }
}

void application_init(void){
    // Nastartovani jednoducheho logovani pres seriovou linku
    bc_log_init(BC_LOG_LEVEL_INFO, BC_LOG_TIMESTAMP_ABS);

    // Nastartuj pin P0
    bc_gpio_init(BC_GPIO_P0);
    // Nastav pin P0 na vystup
    bc_gpio_set_mode(BC_GPIO_P0, BC_GPIO_MODE_OUTPUT);
    // Nastav na pinu P0 logickou 0
    bc_gpio_set_output(BC_GPIO_P0, 0);

    //Nastartuj tlacitko a zaregistruj k nemu udalostni funkci
    bc_button_init(&tlacitko, BC_GPIO_BUTTON, BC_GPIO_PULL_DOWN, 0);
    bc_button_set_event_handler(&tlacitko, stisk_tlacitka, NULL);

}

V hlavní funkci application_init tentokrát musíme nastavit chování pinu P0, který bude nastaven na zápis/výstup a jeho počáteční logická hodnota bude rovna nule (LED nesvítí, napětí na lince je 0V). Zároveň podobně jako v úvodním příkladu nastartujeme tlačítko a zaregistrujeme jeho událostní funkci stisk_tlacitka.

Program běží, ale nic nedělá. Čip tedy spí a celková spotřeba elektrické energie je o mnoho řádů nižší než v případě jakékoliv jiné stavebnice. V tomto stavu by BigClown vydržel klidně i rok a déle.

1f1e6d7c-9f0e-41e0-bd69-c76ee3def874
Program vypisuje údaje do sériové linky. Můžete použít jakýkoliv terminál včetně toho z prostředí Arduino. Stačí jej nastartovat rychlostí 115200 bps. Jednoduchý terminál nabízí i Bigclown Toolchain.

Dobrá, pojďme stisknout tlačítko! Řídící čip zaregistroval stisk a vyvolal událostní funkci stisk_tlacitka. My si v ní nejprve ověříme, jestli se jedná o událost typu BC_BUTTON_EVENT_PRESS (může jich být více) a poté zjistíme, v jakém stavu je blikání pomocí proměnné povoleno typu bool, která může nabývat hodnoty pravda a nepravda.

Ve výchozím stavu je povoleno nastaveno na false, takže LED nebliká. V tom případě vypíšeme do sériové linky zprávu „Zapinam blikani“ a v scheduleru zaregistrujeme úkol blikani, který bez otálení spustí funkci blik.

7240ebfd-a190-43d8-9ea9-2076845baa1b62b9c38f-9de7-4749-b373-ed9fe5d32df1bc3c9efe-2751-43fd-a839-49890ba8dad8
Připojení externí LED na pin P0. Lišta pro piny je z boku popsaná, takže se neztratíte.

Uvnitř funkce blik se nejprve prohodí hodnota další pomocné proměnné typu bool, ve které držíme aktuální stav LED (zapnuto/vypnuto, tedy pravda/nepravda), podle této proměnné nastavíme logický stav na GPIO pinu P0 a LED se konečně rozsvítí, neboť ve výchozím stavu byla zhasnutá. Nakonec řekneme plánovači scheduler, aby znovu vyvolal úkol blikani za dalších 500 milisekund. Už víme, že tento úkol zavolá funkci blik, která tentokrát LED zhasne. A tak stále dokola a dokola.

Podívejte se na video, jak to celé vypadá v akci:

Člověk odkojený Arudinem a jeho funkcí delay bude zpočátku z podobného plánovače možná trošku rozmrzelý, protože bude muset napsat mnohem více kódu i pro podobné primitivní úkony (i BigClown ve skutečnosti nabízí delay, ale opravdu jen tam kde to má smysl – pro velmi krátké a přesné časové úseky v řádu mikrosekund), výhoda tohoto přístupu ale opět spočívá v tom, že neblokujeme čip a ten tedy může po většinu času odpočívat. A tedy spalovat méně elektřiny.

V každém případě, blikání skrze plánovač běží, dokud znovu nestiskneme tlačítko. V takovém případě vypíšeme do sériové linky informaci o ukončení blikání, z plánovače pomocí funkce bc_scheduler_unregister odstraníme naši úlohu a nastavíme na pinu P0 opět logickou nulu, aby LED zhasla, pokud plánovač ukončil úlohu zrovna v okamžiku, kdy svítila.

Na závěr si všimněte, že v tomto programu vůbec nepoužíváme smyčku application_task. Vše je řízeno událostmi tlačítka a plánovače, takže nekonečná smyčka není vůbec potřeba.


Základy GPIO máme za sebou, co kdybychom ale chtěli skrze BigClown ovládnout třeba oblíbený ultrazvukový dálkoměr HC-SR04? Je to snadné, autoři jej totiž přímo podporují ve svém frameworku. Ukážeme si to v další kapitole.

Pokračování 4 / 5

BigClown a ultrazvukový dálkoměr HC-SR04

Základní práci s piny GPIO bychom tedy měli. Jednou z dalších výhod BigClownu je nicméně to, že jeho framework podporuje hromadu populárních zařízení. Nejen ty, které si pro něj koupíte na jeho e-shopu. Patří mezi ně i ultrazvukový dálkoměr HC-SR04, se kterým jsme si v našem seriálu pohráli už mnohokrát.

Pro přímé připojení k BigClownu je třeba použít buď bezpečnou 3,3V verzi HC-SR04 (armový čip BigClownu běží na 3,3V logice, zatímco klasické Arduino na 5V), anebo použít obvod logického převodníku.

Kompletní kód třetího příkladu, který si níže popíšeme krok za krokem:

#include <application.h>

// Udalostni funkce dalkomeru
void dalkomer_udalost(bc_hc_sr04_event_t udalost, void *data){
    // Pokud dalkomer vypocital novou vzdalenost
    if (udalost == BC_HC_SR04_EVENT_UPDATE){
        // Precti vzdalenost, preved na cm a vypis do seriove linky
        float vzdalenost;
        if (bc_hc_sr04_get_distance_millimeter(&vzdalenost)){
            bc_log_info("Vzdalenost: %.2f cm", vzdalenost / 10.0);
        }
    }
}

// HAlvni funkce programu
void application_init(void){
    // Nastartuj logovani skrze seriovou linku (115200 bps)
    bc_log_init(BC_LOG_LEVEL_DUMP, BC_LOG_TIMESTAMP_ABS);
    
    // Nastartuj dalkomer
    bc_hc_sr04_init();
    // Zaregistruj udalsotni funkci po vypocitani vzdalenosti
    bc_hc_sr04_set_event_handler(dalkomer_udalost, NULL);
    // Nastav frekvenci mereni vzdalenosti kazdou sekundu
    bc_hc_sr04_set_update_interval(1000);
}

Já zvolil první případ, ať je obvod co nejjednodušší, a připojil signální piny dálkoměru TRIG a ECHO na piny P9 a P8, se kterými vestavěná podpora počítá. Jen připomenu, že řídící čip nejprve na pinu TRIG (spoušť) vyvolá kratičký elektrický pulz, který dá dálkoměru vědět, že má začít měřit.

5ca695e7-eb20-40b0-a26c-9f25364348fd97066d9e-0e83-456e-b9cd-cacef346dae9cdf17a99-279b-494c-8799-86a2736c52d5
K BigClownu snadno připojíte i populární ultrazvukový dálkoměr HC-SR04, framework jej totiž přímo podporuje a vyhradil pro jeho piny TRIG a ECHO vlastní P9 a P8.

To znamená, že vyšle několik ultrazvukových pulzů, které se odrazí od překážky a doputují zpět do detektoru dálkoměru. Dálkoměr celou dobu měří, jak dlouho to trvalo, a podle toho pak na pinu ECHO vytvoří stejně dlouhý pulz.

Řídící čip tedy po vygenerování pulzu na pinu TRIG čeká na pulz na pinu ECHO, změří jeho délku, dle podle známé rychlosti šíření zvuku ve vzduchu spočítá, jak daleko je překážka. Za nás toto všechno udělá framework BigClownu, takže uživatelský kód je opět velmi krátký.

Podívejte se na dálkoměr v akci:

Stejně jako v předchozích příkladech s tlačítkem v hlavní funkci application_init tentokrát pomocí vestavěné funkce bc_hc_sr04_init nastartujeme dálkoměr a zaregistrujeme událostní funkci, kterou má BigClown vyvolat, až dálkoměr dokončí práci. Zároveň nastavíme, jak často má BigClown měřit vzdálenost – v našem případě každých 1 000 milisekund (jednou za sekundu).

V událostní funkci si tentokrát ověříme, že se jedná o událost typu BC_HC_SR04_EVENT_UPDATE a pomocí další vestavěné funkce bc_hc_sr04_get_distance_millimeter uložíme do proměnné vzdalenost vzdálenost v milimetrech. Nakonec ji podělíme deseti a jako centimetry vypíšeme do sériové linky.

f998d202-f49f-4f67-9554-b1181151c01d
Vypisování vzdálenosti každou sekundu do sériové linky

Jelikož si pracovní takt dálkoměru tentokrát řídí BiGClown, opět nemusíme použít smyčku application_task. Stačí tedy otevřít sériové spojení výchozí rychlostí 115200 bps a v libovolném sériovém terminálu se začnou vypisovat textové řádky se změřenou vzdáleností.


To bylo rychlé, že? Už nám tedy zbývá jediné- Rádiový vysílač! V poslední kapitole si ukážeme, jak snadné je přenést tři bajty z jedné základní desky BigClownu do druhé pomocí vestavěného 868MHz vysílače SPIRIT1.

Pokračování 5 / 5

Rádiový alarm, který při otřesu odešle zprávu do základny BigClown

Nakonec si pojďme ukázat ještě to, co dělá BigClown BigClownem – práci s jeho rádiovým 868MHz vysílačem SPIRIT1. Ačkoliv autoři BigClownu nabízejí kompletní ekosystém a firmwary pro rádiovou komunikaci a příjem dat skrze protokol MQTT, my si ukážeme, jak to funguje v samotném nitru a připravíme si vlastní jednoduchý přijímač rádiových zpráv. Bude to jen pár řádků kódu!

V posledním příkladu si vyrobíme jednoduchý otřesový alarm, základní deska Core Module totiž obsahuje i drobný čip trojosého akcelerometru LIS2DH12 od STMicroelectronics. Pro nás je podstatné, že může být opět velmi úsporný, co se spotřeby elektřiny týče.

c69b46d5-28bd-47e3-80ef-85709de3c14995ffe6be-f24e-441a-9ae4-898a945070941deb44ac-04a7-4fc8-9910-13ea20eef0a4
Vlevo samotný alarm, tedy základní deska s rozšiřujícím bateriovým modulem, vpravo pak druhá základní deska v režimu brány/přijímače připojená do PC

Když naším otřesovým alarmem pohneme (mohl by být třeba přilepený na dveřích), jeho vestavěná LED se rozbliká a také se sepne piezoelektrický modul bzučáku připojený opět na GPIO pin P0, na kterém nastavíme logickou jedničku. Zároveň zaregistrujeme v plánovači úlohu, která o dvě sekundy později bzučení a blikání ukončí.

Na pozadí se ale odehraje ještě jedna a zcela klíčová operace. Rádiový vysílač odešle krátkou zprávičku ve formě tří surových bajtů AA, BB a CC. Jakmile je zachytí přijímač, vypíše do sériové linky varovné hlášení „PREPADENI.“

Náš alarm tentokrát nebude napájený skrze USB kabel, ale použijeme klíčový rozšiřující modul stavebnice BigClown – Battery Module. Jedná se o pouzdro pro dvě tužkové baterie AAA a obvodem step-up měniče. BigClown zároveň umí číst napětí v těchto bateriích, takže skrze rádiovou síť můžeme přenášet i údaje o jejich nabití, sledovat, jak dlouho vydrží a zavčas je vyměnit.

Jak vypadá poslední příklad v praxi? Podívejte se na video:

A vydrží sakra dlouho, hlavní čip totiž může po většinu času spát hlubokým spánkem. Jak je to možné? Vše budou opět řídit jen události. Takže namísto toho, abychom stále dokola měřily surová data z akcelerometru, tedy zrychlení (otřesy) v osách X, Y a Z, nastavíme alarm třeba na ose X a jeho hraniční hodnotu.

Když bude otřes v dané ose dostatečně silný (překoná naši hraniční hodnotu – threshold), akcelerometr vyšle řídícímu čipu impulz a ten poté opět zavolá událostní funkci jako v předchozích příkladech. Náš uživatelský kód tedy jen čeká, dokud dorazí informace o otřesu a nemusí tyto otřesy průběžně sledovat a zatěžovat hlavní řídící čip.

568a7b46-ac53-46d2-b5a8-25a1f0786cb1
Druhá destička v režimu brány přijala zprávu od první destičky a skrze sériovou linku a USB odeslal do počítače zprávu ALARM!

Suma sumárum, alarm může díky modulu se dvěma tužkovými bateriemi běžet celé měsíce, což by bylo v případě klasického Arduina či destiček s Wi-Fi čipy ESP8266 bez pokročilých optimalizací prakticky nemožné. V případě BigClownu je to ale jeho vlastnost už v základu. BigClown je ve srovnání s ostatními prototypovacími stavebnicemi úsporný by design, jak se říká.

Zdrojové kódy rádiového alarmu

Na úplný závěr se tedy opět podívejte na zdrojový kód posledního příkladu, který se tentokrát skládá ze dvou částí. První část je určena pro základní destičku BigClown, která se bude chovat jako detektor otřesu na baterii.

Druhá část pak patří přijímači, což bude druhá základní deska BigClown v režimu brány, která bude automaticky párovat a přijímat data ze všech ostatních destiček v dosahu rádiové sítě. Jakmile zachytí surovou zprávičku o třech bajtech AA, BB a CC, odešle do počítače skrze USB a sériovou linku varování, které může počítač dále zpracovat a třeba nám odeslat varování na e-mail, uložit údaj do databáze aj.

Zdrojový kód vysílače s akcelerometrem:

#include <application.h>

// Vestavena LED
bc_led_t led;

// Vestaveny akcelerometr
bc_lis2dh12_t akcelerometr;

// Vestavene tlacitko
bc_button_t tlacitko;

// Alarm pro vestaveny akcelerometr
bc_lis2dh12_alarm_t alarm;

// Pomocne promenna ukol pro planovac, ktery vypne pipani a bzucak
bool pipam = false;
bool povoleno = false;
bc_scheduler_task_id_t uloha_zastavit;

// Udalostni funkce po stisku tlacitka
void stisk_tlacitka(bc_button_t *self, bc_button_event_t udalost, void *event_param)
{
    // Stisk tlacitka aktivuje, nebo deaktivuje alarm
    if (udalost == BC_BUTTON_EVENT_PRESS){
        povoleno = !povoleno;
    }
}

// Funkce zastavit, kterou vyvola nase uloha zaregistrovana v planovaci
void zastavit(){
    // Vypni blikajici LED
    bc_led_set_mode(&led, BC_LED_MODE_OFF);
    // Vypni bzucak pripojeny na PIO pin P0
    bc_gpio_set_output(BC_GPIO_P0, 0);
    pipam = false;
}

// Udalostni funkce akcelerometru
void udalost_akcelerometru(bc_lis2dh12_t *self, bc_lis2dh12_event_t udalost, void *event_param){
    // Jedna se o udalost alarmu v akcelerometru
    if (udalost == BC_LIS2DH12_EVENT_ALARM) {
        // Pokud je alarm povoleny a jeste belikam
        if(povoleno && !pipam){
            pipam = true;
            // Zapni bzucak pripojeny na GPIO pin P0
            bc_gpio_set_output(BC_GPIO_P0, 1);
            // Rozblikej systemovou LED
            bc_led_set_mode(&led, BC_LED_MODE_BLINK_FAST);
            // Naplanuj vypnuti bzucaku a LED za 2 sekundy
            bc_scheduler_plan_from_now(uloha_zastavit, 2000);
            // Odesli radiovou zpravu se tremi bajty AA, BB a CC
            uint8_t zprava[3] = {0xAA, 0xBB, 0xCC};
            bc_radio_pub_buffer(zprava, sizeof(zprava));
        }
    }
}

// Hlavni funkce, ktera se zpracuje po startu (analogie funkce setup ze sveta Arduino)
void application_init(void){
    // Nastartovani baterioveho modulu, ze ktereho bychom mohli cist treba udaj o napeti v baterii
    bc_module_battery_init();

    // Nastartovani radioveho modulu v rezimu spici sondy
    // Komunikace je jesnosmerna. Radiovy cip se vzdy probudi jen k odeslani dat
    // Pokud se bude radio probouzet jen jednou za par minut, vydrz muze byt mnoho mesicu
    bc_radio_init(BC_RADIO_MODE_NODE_SLEEPING);
    // Kazda sonda muze byt rozlisena svym nazvem a verzi
    // Tyto udaje muzeme precist na prijiamci a identifikovat zarizeni
    bc_radio_pairing_request("KRABICKA", "1");

    // Nastaveni pinu bzucaku pripojeneho k pinu P0
    bc_gpio_init(BC_GPIO_P0);
    bc_gpio_set_mode(BC_GPIO_P0, BC_GPIO_MODE_OUTPUT);
    // Aktivujeme pull-down rezistor (v tomto pripade neni nutne, ale pro ukazku)
    // Pokud nebude bzucak bzucet, je na tomto pinu cista logicka nula
    bc_gpio_set_pull(BC_GPIO_P0, BC_GPIO_PULL_DOWN);
    // Nastavime vychozi logicky stav na 0
    bc_gpio_set_output(BC_GPIO_P0, 0);

    // Zaregistrujeme ulohu pro zastaveni buceni a blikani, ale nestanovime cas, kdy se ma zpracovat
    uloha_zastavit = bc_scheduler_register(zastavit, NULL, BC_TICK_INFINITY);
    
    // Nastartujeme tlacitko a nastavime jeho udalostni funkci, ktera se vyvola po stisku
    bc_button_init(&tlacitko, BC_GPIO_BUTTON, BC_GPIO_PULL_DOWN, 0);
    bc_button_set_event_handler(&tlacitko, stisk_tlacitka, NULL);

    // Nastartujeme vestavenou LED a vypneme ji
    bc_led_init(&led, BC_GPIO_LED, false, false);
    bc_led_set_mode(&led, BC_LED_MODE_OFF);

    // Nastaveni alarmu akcelerometru
    // Alarm bude reagovat na otres v ose X
    alarm.x_high = true;
    // Hranicni sila otresu, aby se vvyvolal alarm (tedy nastaveni citlivosti)
    alarm.threshold = 1;

    // Nastartujeme vestaveny akcelerometr, ktery komunikuje na sbernici I2C a I2C adrese 0x19
    bc_lis2dh12_init(&akcelerometr, BC_I2C_I2C0, 0x19);
    // Zaregistrujeme na akcelerometru nas alarm
    bc_lis2dh12_set_alarm(&akcelerometr, &alarm);
    // Zaregistrujeme udalostni funkci akcelerometru, ktera nam da vedet, ze akcelerometr vyvolal alarm
    bc_lis2dh12_set_event_handler(&akcelerometr, udalost_akcelerometru, NULL);
}

Zdrojový kód přijímače připojeného do PC:

#include <application.h>

// Udalostni funkce, ktera se vyvola, pokud dorazi surova data
// BigClown podpourje i prenos konkretnich promennyc a dat z cidel
// tato funkce je urcena pro prijem surovych dat o velikosti az nekolika desítek bajtu
// V parametrech je ulozene unikatni ID odesilatele, ukazatel na data a velikost techto dat
void bc_radio_pub_on_buffer(uint64_t *id, uint8_t *data, size_t delka){
    // Pokud ma zprava alespon 3 bajty a pokud jsou prvni tri bajty AA, BB a CC,
    // je to zprava z radioveho alarmu, a tak napisu do seriové linky varovani
    if(delka >= 3){
        if(data[0] == 0xAA && data[1] == 0xBB && data[2] == 0xCC){
            bc_log_info("ALARM!");
        }
    }
}

// Hlavni funkce programu
void application_init(void)
{
    // Nastartovani logovani
    bc_log_init(BC_LOG_LEVEL_DUMP, BC_LOG_TIMESTAMP_ABS);

    // Nastartovani radia v rezimu brany
    bc_radio_init(BC_RADIO_MODE_GATEWAY);
    // Nastaveni automatickeho parovani klientu
    // Parovani tedy nemusim pro jednoduchost rucne autorizovat
    bc_radio_automatic_pairing_start();

    // Smaz vsechny doposud sparovane klienty
    // Pocet klientu na jednu branu je omezeny!
    // Tyto udaje se trvale ukladaji v casti pameti EEPROM
    // Pro nase testovaci ucely to nema smysl, takze se seznam
    // po kazdem startu smaze
    bc_radio_peer_device_purge_all();
}

Jak vidno, BigClown funguje trošku jinak než základní Arduino, i v tomto případě se však jedná o velmi rychlé a snadné prototypování. Zvláště tehdy, pokud použijeme podporovaná a úsporná čidla přímo pro tuto stavebnici, která jsou vývojovým prostředím BigClownu přímo podporovaná.

Hlavním benefitem stavebnice je ale jeho velmi nízká spotřeba elektrické energie, která nemá mezi ostatními stavebnicemi obdoby. A to je nakonec i jeden z důvodů, proč je BigClown přece jen dražší než laciné čínské klony Arduina z Aliexpressu za nějaký ten dolar.

Určitě si přečtěte

Články odjinud